forked from mirror/BlueMap
Add touch controls
This commit is contained in:
parent
7cca8e428f
commit
c5485e6657
@ -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",
|
||||
|
@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>BlueMap</title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -69,6 +69,7 @@ export default class BlueMap {
|
||||
this.dataRoot = dataRoot;
|
||||
|
||||
this.loadingNoticeElement = $('<div id="bluemap-loading" class="box">loading...</div>').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, `
|
||||
<div style="max-width: 500px">
|
||||
<h1>Error</h1>
|
||||
<p style="color: red; font-family: monospace">${message}</p>
|
||||
</div>
|
||||
`);
|
||||
};
|
||||
|
||||
// ###### UI ######
|
||||
|
||||
toggleAlert(id, content) {
|
||||
@ -474,6 +484,7 @@ export default class BlueMap {
|
||||
alert.fadeIn(200);
|
||||
};
|
||||
|
||||
if (id !== undefined) {
|
||||
let sameAlert = alertBox.find(`.alert[data-alert-id=${id}]`);
|
||||
if (sameAlert.length > 0) {
|
||||
alertBox.fadeOut(200, () => {
|
||||
@ -482,6 +493,7 @@ export default class BlueMap {
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let oldAlerts = alertBox.find('.alert');
|
||||
if (oldAlerts.length > 0){
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ module.exports = {
|
||||
compress: true,
|
||||
port: 8080,
|
||||
hot: true,
|
||||
host: "192.168.178.22"
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
|
Loading…
Reference in New Issue
Block a user