Skip to content

Commit dca41fd

Browse files
authored
Merge pull request #22 from smartify-org-uk/fix-stylable-permissiongesture-dialog
Feature: Adds classnames to obtainPermissionGesture dialog on DeviceOrientationControls
2 parents c0866b6 + 5ec575c commit dca41fd

File tree

2 files changed

+125
-52
lines changed

2 files changed

+125
-52
lines changed

lib/constants/classes.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const LOCAR_DEVICE_ORIENTATION_PERMISSION_MODAL =
2+
"locar-device-orientation-permission-modal";
3+
export const LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON =
4+
"locar-device-orientation-permission-button";
5+
export const LOCAR_DEVICE_ORIENTATION_PERMISSION_MESSAGE =
6+
"locar-device-orientation-permission-message";
7+
export const LOCAR_DEVICE_ORIENTATION_PERMISSION_INNER =
8+
"locar-device-orientation-permission-inner";
9+
export const LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON_INNER =
10+
"locar-device-orientation-permission-button-inner";

lib/three/device-orientation-controls.js

Lines changed: 115 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222

2323
import { Euler, EventDispatcher, MathUtils, Quaternion, Vector3 } from "three";
2424
import EventEmitter from './event-emitter.js';
25+
import {
26+
LOCAR_DEVICE_ORIENTATION_PERMISSION_MODAL,
27+
LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON,
28+
LOCAR_DEVICE_ORIENTATION_PERMISSION_MESSAGE,
29+
LOCAR_DEVICE_ORIENTATION_PERMISSION_INNER,
30+
LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON_INNER,
31+
} from "../constants/classes.js";
32+
33+
const LOCAR_DEVICE_ORIENTATION_MESSAGE =
34+
"This immersive website requires access to your device motion sensors.";
2535

2636
const isIOS = navigator.userAgent.match(/iPhone|iPad|iPod/i) ||
2737
(/Macintosh/i.test(navigator.userAgent) &&
@@ -67,10 +77,11 @@ class DeviceOrientationControls extends EventDispatcher {
6777
"ondeviceorientationabsolute" in window
6878
? "deviceorientationabsolute"
6979
: "deviceorientation";
70-
console.log("Device Orientation Event Name:", this.orientationChangeEventName);
7180

7281
this.smoothingFactor = options.smoothingFactor || 1;
7382
this.enablePermissionDialog = options.enablePermissionDialog ?? true;
83+
this.enableInlineStyling = options.enableStyling ?? true;
84+
this.preferConfirmDialog = options.preferConfirmDialog ?? false;
7485

7586
const onDeviceOrientationChangeEvent = function ({
7687
alpha,
@@ -391,80 +402,132 @@ class DeviceOrientationControls extends EventDispatcher {
391402
return device && device.gamma ? MathUtils.degToRad(device.gamma) : 0
392403
};
393404

394-
395-
396405
// Provide gesture before initialising device orientation controls
397406
// From PR #659 on the main AR.js repo
398407
// Thanks to @ma2yama
399-
this.obtainPermissionGesture = function() {
408+
this.createObtainPermissionGestureDialog = function () {
409+
// Add all the elements and a common class names to all elements
410+
// to allow external styling
400411
const startModal = document.createElement("div");
412+
startModal.classList.add(LOCAR_DEVICE_ORIENTATION_PERMISSION_MODAL);
413+
401414
const innerDiv = document.createElement("div");
415+
innerDiv.classList.add(LOCAR_DEVICE_ORIENTATION_PERMISSION_INNER);
416+
402417
const msgDiv = document.createElement("div");
418+
msgDiv.classList.add(LOCAR_DEVICE_ORIENTATION_PERMISSION_MESSAGE);
419+
403420
const btnDiv = document.createElement("div");
421+
btnDiv.classList.add(LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON_INNER);
422+
423+
const btn = document.createElement("button");
424+
btn.classList.add(LOCAR_DEVICE_ORIENTATION_PERMISSION_BUTTON);
425+
404426
document.body.appendChild(startModal);
405-
const startModalStyles = {
406-
display: 'flex',
407-
position: 'fixed',
408-
top: 0,
409-
left: 0,
410-
width: '100%',
411-
height: '100%',
412-
zIndex: 1,
413-
backgroundColor: 'rgba(0,0,0,0.6)',
414-
justifyContent: 'center',
415-
alignItems: 'center'
416-
};
417-
const innerDivStyles = {
418-
backgroundColor: 'white',
419-
padding: '6px',
420-
borderRadius: '3px',
421-
width: '36rem',
422-
height: '24rem'
423-
};
424-
const msgDivStyles = {
425-
width: '100%',
426-
height: '70%',
427-
display: 'flex',
428-
justifyContent: 'center',
429-
alignItems: 'center'
430-
};
431-
const btnDivStyles = {
432-
display: 'inline-flex',
433-
width: '100%',
434-
height: '30%',
435-
justifyContent: 'center',
436-
alignItems: 'center'
437-
};
438-
for(let key in startModalStyles) {
427+
428+
// Apply inline styling if required, the styling tries to resemble
429+
// a native ios dialog as closely as possible
430+
if (this.enableInlineStyling === true) {
431+
const startModalStyles = {
432+
fontFamily:
433+
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'",
434+
display: "flex",
435+
position: "fixed",
436+
zIndex: 100000,
437+
justifyContent: "center",
438+
alignItems: "center",
439+
backgroundColor: "rgba(0,0,0,0.2)",
440+
inset: 0,
441+
padding: "20px",
442+
};
443+
444+
const innerDivStyles = {
445+
backgroundColor: "rgba(220, 220, 220, 0.85)",
446+
padding: "6px 0",
447+
borderRadius: "10px",
448+
width: "100%",
449+
maxWidth: "400px",
450+
};
451+
452+
const msgDivStyles = {
453+
padding: "10px 12px",
454+
textAlign: "center",
455+
fontWeight: 400,
456+
fontSize: "13px",
457+
display: "flex",
458+
justifyContent: "center",
459+
alignItems: "center",
460+
};
461+
462+
const btnDivStyles = {
463+
display: "block",
464+
textAlign: "center",
465+
textDecoration: "none",
466+
borderTop: "rgb(180,180,180) solid 1px",
467+
};
468+
469+
const btnStyles = {
470+
display: "block",
471+
width: "100%",
472+
textAlign: "center",
473+
appearance: "none",
474+
background: "none",
475+
border: "none",
476+
outline: "none",
477+
padding: "10px",
478+
fontWeight: 400,
479+
fontSize: "16px",
480+
color: "#2e7cf1",
481+
cursor: "pointer",
482+
};
483+
484+
for (let key in startModalStyles) {
439485
startModal.style[key] = startModalStyles[key];
440-
}
441-
for(let key in innerDivStyles) {
486+
}
487+
for (let key in innerDivStyles) {
442488
innerDiv.style[key] = innerDivStyles[key];
443-
}
444-
for(let key in msgDivStyles) {
489+
}
490+
for (let key in msgDivStyles) {
445491
msgDiv.style[key] = msgDivStyles[key];
446-
}
447-
for(let key in btnDivStyles) {
492+
}
493+
for (let key in btnDivStyles) {
448494
btnDiv.style[key] = btnDivStyles[key];
495+
}
496+
for (let key in btnStyles) {
497+
btn.style[key] = btnStyles[key];
498+
}
449499
}
500+
450501
startModal.appendChild(innerDiv);
451502
innerDiv.appendChild(msgDiv);
452503
innerDiv.appendChild(btnDiv);
453-
msgDiv.innerHTML = '<div style="font-size: 24pt; margin: 1rem;">This immersive website requires access to your device motion sensors.</div>';
504+
msgDiv.appendChild(
505+
document.createTextNode(LOCAR_DEVICE_ORIENTATION_MESSAGE)
506+
);
454507

455508
const onStartClick = () => {
456509
this.requestOrientationPermissions();
457-
startModal.style.display = 'none';
458-
}
459-
const btn = document.createElement("button");
510+
startModal.style.display = "none";
511+
};
512+
460513
btn.addEventListener("click", onStartClick);
461-
btn.style.width = '50%';
462-
btn.style.height = '80%';
463-
btn.style.fontSize = '20pt';
464514
btn.appendChild(document.createTextNode("OK"));
515+
465516
btnDiv.appendChild(btn);
466517
document.body.appendChild(startModal);
467-
}
518+
};
519+
520+
this.obtainPermissionGesture = function () {
521+
// Create a simple ok/cancel confirm() dialog instead of creating an html one
522+
// if defined in the options, otherwise create the html dialog as above
523+
if (this.preferConfirmDialog === true) {
524+
if (window.confirm(LOCAR_DEVICE_ORIENTATION_MESSAGE)) {
525+
this.requestOrientationPermissions();
526+
}
527+
} else {
528+
this.createObtainPermissionGestureDialog();
529+
}
530+
};
468531
}
469532

470533
on(eventName, eventHandler) {

0 commit comments

Comments
 (0)