From 7bed789a8a93c56a144f775b2375b14d331f7f0f Mon Sep 17 00:00:00 2001 From: Andre Vasconcelos Date: Mon, 9 May 2022 12:41:57 +0900 Subject: [PATCH] Added support for mobile deviceorientation --- src/components/room_scene.js | 38 +++++++++++++++++++++++++++--------- src/index.js | 25 ++++++++++++++++++++++-- src/sass/style.scss | 9 +++++++++ webpack.config.js | 1 + 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/components/room_scene.js b/src/components/room_scene.js index 7a2465f..abadbca 100644 --- a/src/components/room_scene.js +++ b/src/components/room_scene.js @@ -1,5 +1,5 @@ import * as THREE from 'three'; -import DeviceOrientationControls from 'three-device-orientation'; +// import DeviceOrientationControls from 'three-device-orientation'; // import GLTFLoader from 'three-gltf-loader' import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; @@ -20,6 +20,7 @@ export default class RoomScene { this.landingPage = new LandingPage({ isMobile }); mount(document.body, this.loadingScreen); mount(document.body, this.landingPage); + // Scene components this.scene = new THREE.Scene(); this.renderer = new THREE.WebGLRenderer(); @@ -37,13 +38,14 @@ export default class RoomScene { this.rig = new THREE.Object3D(); this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 400); - if (this.isMobile) { - this.controls = new DeviceOrientationControls(this.camera); - } this.rig.position.set(0, 0, -1.5); this.rig.add(this.camera); this.scene.add(this.rig); + // Mobile gyroscope calculations + this.prevX = this.camera.rotation.x; + this.prevY = this.camera.rotation.y; + // Set up scene this.createScene(); this.fontLoader.load('/fonts/Poppins_SemiBold.json', (font) => { @@ -222,10 +224,9 @@ export default class RoomScene { this.scannerLockMesh.rotation.z -= 0.01; } - if (this.controls) { + if (this.isMobile) { // hover effect on objects this.detectObjects(window.innerWidth / 2, window.innerHeight / 2); - this.controls.update(); } this.renderScene(); @@ -245,11 +246,11 @@ export default class RoomScene { // mouse rotation const deltaY = -window.innerHeight / 2 + y; - const deltax = -window.innerWidth / 2 + x; - const rotAnimation = gsap.to(this.camera.rotation, { + const deltaX = -window.innerWidth / 2 + x; + gsap.to(this.camera.rotation, { duration: 0.5, x: -deltaY * sensitivity, - y: -deltax * sensitivity, + y: -deltaX * sensitivity, z: 0, ease: Power1.easeOut, }); @@ -257,6 +258,25 @@ export default class RoomScene { this.detectObjects(x, y); }; + handleGyroscope = (x, y) => { + if (this.isMovingCamera) return; + const sensitivity = 0.09; + const rad = Math.PI / 180; + + // Get differenece in radians + const deltaX = this.prevX - x; + const rotationX = (this.prevX + deltaX + 90) * rad; + + const deltaY = this.prevY - y; + const rotationY = (this.prevY + deltaY) * rad; + + this.camera.rotation.set(-rotationX * sensitivity, -rotationY * sensitivity, 0); + + this.prevX = rotationX; + this.prevY = rotationY; + this.renderer.render(this.scene, this.camera); + }; + detectObjects = (x, y) => { const vector = new THREE.Vector2(); vector.x = (x / window.innerWidth) * 2 - 1; diff --git a/src/index.js b/src/index.js index f51e628..ead8889 100644 --- a/src/index.js +++ b/src/index.js @@ -7,19 +7,40 @@ class Root { constructor() { const testExp = /Android|webOS|iPhone|iPad|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i; this.isMobile = testExp.test(navigator.userAgent); - this.roomSceneObj = new RoomScene({ isMobile: this.isMobile }); + this.roomSceneObj = new RoomScene({ + isMobile: this.isMobile, + }); this.el = el('#main-div'); + this.mobileEl = el('p#mobile-debug'); } onmount() { mount(this.el, this.roomSceneObj); + mount(this.el, this.mobileEl); + this.registerEventListeners(); } + renderOrientationData = (x, y) => { + this.mobileEl.innerHTML = `x: ${x};
y: ${y};`; + }; + registerEventListeners = () => { if (this.isMobile) { - document.addEventListener('touchend', (event) => { + window.addEventListener('touchend', (event) => { this.handleClickAndTap(event); + DeviceOrientationEvent.requestPermission().then((response) => { + if (response === 'granted') { + window.addEventListener('deviceorientation', (e) => { + const x = Math.round(e.beta); + const y = Math.round(e.gamma); + if (x < 85) { + // this.renderOrientationData(x, y); + this.roomSceneObj.handleGyroscope(x, y); + } + }); + } + }); }); } else { window.addEventListener( diff --git a/src/sass/style.scss b/src/sass/style.scss index 86df55c..94e0ab0 100644 --- a/src/sass/style.scss +++ b/src/sass/style.scss @@ -7,6 +7,15 @@ html { font-family: 'Poppins', sans-serif; } +#mobile-debug { + position: absolute; + bottom: 20px; + color: #fff; + font-size: 18px; + text-align: left; + width: 100%; + z-index: 1000; +} // @font-face { // font-family: 'Montserrat-Black'; // font-display: auto; diff --git a/webpack.config.js b/webpack.config.js index afedd13..8aa1a71 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,6 +30,7 @@ const options = { static: { directory: path.join(__dirname, 'dist'), }, + https: true, compress: true, }, output: {