From c5485e665767af3250ee3965725b2a15cba100a4 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Sat, 18 Jan 2020 23:33:38 +0100 Subject: [PATCH] Add touch controls --- BlueMapCore/package.json | 3 +- BlueMapCore/src/main/webroot/index.html | 1 + .../src/main/webroot/js/libs/BlueMap.js | 32 +++-- .../src/main/webroot/js/libs/Controls.js | 116 +++++++++++++++++- BlueMapCore/webpack.config.js | 1 + 5 files changed, 138 insertions(+), 15 deletions(-) diff --git a/BlueMapCore/package.json b/BlueMapCore/package.json index 512f0515..9788f551 100644 --- a/BlueMapCore/package.json +++ b/BlueMapCore/package.json @@ -17,7 +17,8 @@ "homepage": "https://github.com/BlueMap-Minecraft/BlueMap#readme", "dependencies": { "jquery": "^3.4.1", - "three": "^0.94.0" + "three": "^0.94.0", + "hammerjs": "^2.0.8" }, "devDependencies": { "css-loader": "^3.4.2", diff --git a/BlueMapCore/src/main/webroot/index.html b/BlueMapCore/src/main/webroot/index.html index d818108c..07fb8406 100644 --- a/BlueMapCore/src/main/webroot/index.html +++ b/BlueMapCore/src/main/webroot/index.html @@ -2,6 +2,7 @@ + BlueMap diff --git a/BlueMapCore/src/main/webroot/js/libs/BlueMap.js b/BlueMapCore/src/main/webroot/js/libs/BlueMap.js index c890fb90..9cbb6532 100644 --- a/BlueMapCore/src/main/webroot/js/libs/BlueMap.js +++ b/BlueMapCore/src/main/webroot/js/libs/BlueMap.js @@ -69,6 +69,7 @@ export default class BlueMap { this.dataRoot = dataRoot; this.loadingNoticeElement = $('
loading...
').appendTo($(this.element)); + window.onerror = this.onLoadError; this.fileLoader = new FileLoader(); this.blobLoader = new FileLoader(); @@ -105,7 +106,7 @@ export default class BlueMap { this.initModules(); this.start(); - }); + }).catch(error => this.onLoadError(error.toString())); } initModules() { @@ -363,7 +364,6 @@ export default class BlueMap { return new Promise(resolve => { this.fileLoader.load(this.dataRoot + 'textures.json', textures => { textures = JSON.parse(textures); - let materials = []; for (let i = 0; i < textures['textures'].length; i++) { let t = textures['textures'][i]; @@ -399,7 +399,6 @@ export default class BlueMap { } this.hiresMaterial = materials; - resolve(); }); }); @@ -458,6 +457,17 @@ export default class BlueMap { }) } + onLoadError = (message, url, line, col) => { + this.loadingNoticeElement.remove(); + + this.toggleAlert(undefined, ` +
+

Error

+

${message}

+
+ `); + }; + // ###### UI ###### toggleAlert(id, content) { @@ -474,13 +484,15 @@ export default class BlueMap { alert.fadeIn(200); }; - let sameAlert = alertBox.find(`.alert[data-alert-id=${id}]`); - if (sameAlert.length > 0){ - alertBox.fadeOut(200, () => { - alertBox.html(''); - alertBox.show(); - }); - return; + if (id !== undefined) { + let sameAlert = alertBox.find(`.alert[data-alert-id=${id}]`); + if (sameAlert.length > 0) { + alertBox.fadeOut(200, () => { + alertBox.html(''); + alertBox.show(); + }); + return; + } } let oldAlerts = alertBox.find('.alert'); diff --git a/BlueMapCore/src/main/webroot/js/libs/Controls.js b/BlueMapCore/src/main/webroot/js/libs/Controls.js index e0bb3efe..2eef441d 100644 --- a/BlueMapCore/src/main/webroot/js/libs/Controls.js +++ b/BlueMapCore/src/main/webroot/js/libs/Controls.js @@ -30,6 +30,7 @@ import { Vector3, MOUSE } from 'three'; +import Hammer from 'hammerjs'; import { Vector2_ZERO } from './utils.js'; @@ -94,10 +95,15 @@ export default class Controls { this.cameraPosDelta = new Vector3(0, 0, 0); this.moveDelta = new Vector2(0, 0); - this.keyStates = {} + this.touchStart = new Vector2(0, 0); + this.touchDelta = new Vector2(0, 0); + + this.keyStates = {}; this.state = Controls.STATES.NONE; let canvas = $(this.element).find('canvas').get(0); + + // mouse events window.addEventListener('contextmenu', event => { event.preventDefault(); }, false); @@ -108,6 +114,37 @@ export default class Controls { window.addEventListener('keydown', this.onKeyDown, false); window.addEventListener('keyup', this.onKeyUp, false); + // touch events + this.hammer = new Hammer.Manager(canvas); + let touchMove = new Hammer.Pan({ event: 'move', direction: Hammer.DIRECTION_ALL, threshold: 0 }); + let touchTilt = new Hammer.Pan({ event: 'tilt', direction: Hammer.DIRECTION_VERTICAL, pointers: 2, threshold: 0 }); + let touchRotate = new Hammer.Rotate({ event: 'rotate', pointers: 2, threshold: 10 }); + let touchZoom = new Hammer.Pinch({ event: 'zoom', pointers: 2, threshold: 0 }); + + touchTilt.recognizeWith(touchRotate); + touchTilt.recognizeWith(touchZoom); + touchRotate.recognizeWith(touchZoom); + + this.hammer.add( touchMove ); + this.hammer.add( touchTilt ); + this.hammer.add( touchRotate ); + this.hammer.add( touchZoom ); + + this.hammer.on('movestart', this.onTouchDown); + this.hammer.on('movemove', this.onTouchMove); + this.hammer.on('moveend', this.onTouchUp); + this.hammer.on('movecancel', this.onTouchUp); + this.hammer.on('tiltstart', this.onTouchTiltDown); + this.hammer.on('tiltmove', this.onTouchTiltMove); + this.hammer.on('tiltend', this.onTouchTiltUp); + this.hammer.on('tiltcancel', this.onTouchTiltUp); + this.hammer.on('rotatestart', this.onTouchRotateDown); + this.hammer.on('rotatemove', this.onTouchRotateMove); + this.hammer.on('rotateend', this.onTouchRotateUp); + this.hammer.on('rotatecancel', this.onTouchRotateUp); + this.hammer.on('zoomstart', this.onTouchZoomDown); + this.hammer.on('zoommove', this.onTouchZoomMove); + this.camera.position.set(0, 1000, 0); this.camera.lookAt(this.position); this.camera.updateProjectionMatrix(); @@ -218,9 +255,6 @@ export default class Controls { updateMouseMoves = () => { this.deltaMouse.set(this.lastMouse.x - this.mouse.x, this.lastMouse.y - this.mouse.y); - this.moveDelta.x = 0; - this.moveDelta.y = 0; - if (this.keyStates[Controls.KEYS.UP]){ this.moveDelta.y -= 20; } @@ -254,6 +288,9 @@ export default class Controls { } this.lastMouse.copy(this.mouse); + + this.moveDelta.x = 0; + this.moveDelta.y = 0; }; onMouseWheel = event => { @@ -305,6 +342,77 @@ export default class Controls { } }; + onTouchDown = event => { + this.touchStart.x = this.targetPosition.x; + this.touchStart.y = this.targetPosition.z; + this.state = Controls.STATES.MOVE; + }; + + onTouchMove = event => { + if (this.state !== Controls.STATES.MOVE) return; + + this.touchDelta.x = event.deltaX; + this.touchDelta.y = event.deltaY; + + if (this.touchDelta.x !== 0 || this.touchDelta.y !== 0) { + this.touchDelta.rotateAround(Vector2_ZERO, -this.direction); + + this.targetPosition.x = this.touchStart.x - (this.touchDelta.x * this.distance / this.element.clientHeight * this.settings.move.speed); + this.targetPosition.z = this.touchStart.y - (this.touchDelta.y * this.distance / this.element.clientHeight * this.settings.move.speed); + } + }; + + onTouchUp = event => { + this.state = Controls.STATES.NONE; + }; + + onTouchTiltDown = event => { + this.touchTiltStart = this.targetAngle; + this.state = Controls.STATES.ORBIT; + }; + + onTouchTiltMove = event => { + if (this.state !== Controls.STATES.ORBIT) return; + + this.targetAngle = this.touchTiltStart - (event.deltaY / this.element.clientHeight * Math.PI); + }; + + onTouchTiltUp = event => { + this.state = Controls.STATES.NONE; + }; + + onTouchRotateDown = event => { + this.lastTouchRotation = event.rotation; + this.state = Controls.STATES.ORBIT; + }; + + onTouchRotateMove = event => { + if (this.state !== Controls.STATES.ORBIT) return; + + let delta = event.rotation - this.lastTouchRotation; + this.lastTouchRotation = event.rotation; + if (delta > 180) delta -= 360; + if (delta < -180) delta += 360; + + this.targetDirection += (delta * (Math.PI / 180)) * 1.4; + }; + + onTouchRotateUp = event => { + this.state = Controls.STATES.NONE; + }; + + + onTouchZoomDown = event => { + this.touchZoomStart = this.targetDistance; + }; + + onTouchZoomMove = event => { + this.targetDistance = this.touchZoomStart / event.scale; + + if (this.targetDistance < this.settings.zoom.min) this.targetDistance = this.settings.zoom.min; + if (this.targetDistance > this.settings.zoom.max) this.targetDistance = this.settings.zoom.max; + }; + onKeyDown = event => { this.keyStates[event.keyCode] = true; }; diff --git a/BlueMapCore/webpack.config.js b/BlueMapCore/webpack.config.js index e2b68645..0e271fa9 100644 --- a/BlueMapCore/webpack.config.js +++ b/BlueMapCore/webpack.config.js @@ -23,6 +23,7 @@ module.exports = { compress: true, port: 8080, hot: true, + host: "192.168.178.22" }, plugins: [ new MiniCssExtractPlugin({