mirror of
https://github.com/BlueMap-Minecraft/BlueMapWeb.git
synced 2024-11-16 15:15:10 +01:00
Add cache-hashes and more tweaks
This commit is contained in:
parent
fd74e320cc
commit
3a7b8aef59
@ -27,7 +27,7 @@ import {Map} from "./map/Map";
|
||||
import {SkyboxScene} from "./skybox/SkyboxScene";
|
||||
import {ControlsManager} from "./controls/ControlsManager";
|
||||
import Stats from "./util/Stats";
|
||||
import {alert, dispatchEvent, elementOffset, htmlToElement} from "./util/Utils";
|
||||
import {alert, dispatchEvent, elementOffset, generateCacheHash, htmlToElement} from "./util/Utils";
|
||||
import {TileManager} from "./map/TileManager";
|
||||
import {HIRES_VERTEX_SHADER} from "./map/hires/HiresVertexShader";
|
||||
import {HIRES_FRAGMENT_SHADER} from "./map/hires/HiresFragmentShader";
|
||||
@ -73,6 +73,8 @@ export class MapViewer {
|
||||
loadedLowresViewDistance: 2000,
|
||||
}
|
||||
|
||||
this.tileCacheHash = generateCacheHash();
|
||||
|
||||
this.stats = new Stats();
|
||||
this.stats.hide();
|
||||
|
||||
@ -87,7 +89,7 @@ export class MapViewer {
|
||||
this.renderer.uniforms = this.data.uniforms;
|
||||
|
||||
// CSS2D renderer
|
||||
this.css2dRenderer = new CSS2DRenderer();
|
||||
this.css2dRenderer = new CSS2DRenderer(this.events);
|
||||
|
||||
this.skyboxScene = new SkyboxScene(this.data.uniforms);
|
||||
|
||||
@ -310,7 +312,7 @@ export class MapViewer {
|
||||
this.map = map;
|
||||
|
||||
if (this.map && this.map.isMap) {
|
||||
return map.load(HIRES_VERTEX_SHADER, HIRES_FRAGMENT_SHADER, LOWRES_VERTEX_SHADER, LOWRES_FRAGMENT_SHADER, this.data.uniforms)
|
||||
return map.load(HIRES_VERTEX_SHADER, HIRES_FRAGMENT_SHADER, LOWRES_VERTEX_SHADER, LOWRES_FRAGMENT_SHADER, this.data.uniforms, this.tileCacheHash)
|
||||
.then(() => {
|
||||
for (let texture of this.map.loadedTextures){
|
||||
this.renderer.initTexture(texture);
|
||||
@ -356,6 +358,16 @@ export class MapViewer {
|
||||
this.map.loadMapArea(this.data.loadedCenter.x, this.data.loadedCenter.y, this.data.loadedHiresViewDistance, this.data.loadedLowresViewDistance);
|
||||
}
|
||||
|
||||
clearTileCache(newTileCacheHash) {
|
||||
if (!newTileCacheHash) newTileCacheHash = generateCacheHash();
|
||||
|
||||
this.tileCacheHash = newTileCacheHash;
|
||||
if (this.map) {
|
||||
this.map.lowresTileManager.tileLoader.tileCacheHash = this.tileCacheHash;
|
||||
this.map.hiresTileManager.tileLoader.tileCacheHash = this.tileCacheHash;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
|
@ -41,14 +41,18 @@ export class FreeFlightControls {
|
||||
this.target = target;
|
||||
this.manager = null;
|
||||
|
||||
this.data = {
|
||||
|
||||
};
|
||||
|
||||
this.hammer = new Manager(this.target);
|
||||
this.initializeHammer();
|
||||
|
||||
this.keyMove = new KeyMoveControls(this.target, 0.5, 0.1);
|
||||
this.keyHeight = new KeyHeightControls(this.target, 0.5, 0.2);
|
||||
this.mouseRotate = new MouseRotateControls(this.target, 0.002, -0.003, -0.002, 0.5);
|
||||
this.mouseAngle = new MouseAngleControls(this.target, 0.002, -0.003, -0.002, 0.5);
|
||||
this.touchPan = new TouchPanControls(this.hammer, 0.005, 0.15);
|
||||
this.mouseRotate = new MouseRotateControls(this.target, 1.5, -2, -1.5, 0.5);
|
||||
this.mouseAngle = new MouseAngleControls(this.target, 1.5, -2, -1.5, 0.5);
|
||||
this.touchPan = new TouchPanControls(this.target, this.hammer, 5, 0.15);
|
||||
|
||||
this.started = false;
|
||||
|
||||
@ -74,24 +78,6 @@ export class FreeFlightControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
this.target.addEventListener("mouseup", this.onMouseUp);
|
||||
window.addEventListener("wheel", this.onWheel, {passive: true});
|
||||
|
||||
let startOrtho = this.manager.ortho;
|
||||
let startDistance = this.manager.distance;
|
||||
let startAngle = this.manager.angle;
|
||||
let startY = this.manager.position.y;
|
||||
|
||||
let targetAngle = Math.PI / 2;
|
||||
|
||||
animate(progress => {
|
||||
let smoothProgress = EasingFunctions.easeInOutQuad(progress);
|
||||
|
||||
this.manager.ortho = MathUtils.lerp(startOrtho, 0, progress);
|
||||
this.manager.distance = MathUtils.lerp(startDistance, 0, smoothProgress);
|
||||
this.manager.angle = MathUtils.lerp(startAngle, targetAngle, smoothProgress);
|
||||
this.manager.position.y = MathUtils.lerp(startY, this.animationTargetHeight, smoothProgress);
|
||||
}, 500, () => {
|
||||
this.started = true;
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -105,8 +91,6 @@ export class FreeFlightControls {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
this.target.removeEventListener("mouseup", this.onMouseUp);
|
||||
window.removeEventListener("wheel", this.onWheel);
|
||||
|
||||
this.started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,11 +98,6 @@ export class FreeFlightControls {
|
||||
* @param map {Map}
|
||||
*/
|
||||
update(delta, map) {
|
||||
if (!this.started) {
|
||||
this.animationTargetHeight = map.terrainHeightAt(this.manager.position.x, this.manager.position.z) + 10;
|
||||
return;
|
||||
}
|
||||
|
||||
this.keyMove.update(delta, map);
|
||||
this.keyHeight.update(delta, map);
|
||||
this.mouseRotate.update(delta, map);
|
||||
@ -126,6 +105,8 @@ export class FreeFlightControls {
|
||||
this.touchPan.update(delta, map);
|
||||
|
||||
this.manager.angle = MathUtils.clamp(this.manager.angle, 0, Math.PI);
|
||||
this.manager.distance = 0;
|
||||
this.manager.ortho = 0;
|
||||
}
|
||||
|
||||
initializeHammer() {
|
||||
@ -145,7 +126,10 @@ export class FreeFlightControls {
|
||||
if (Math.abs(this.clickStart.x - evt.x) > 5) return;
|
||||
if (Math.abs(this.clickStart.y - evt.y) > 5) return;
|
||||
|
||||
this.target.requestPointerLock();
|
||||
document.body.requestFullscreen()
|
||||
.finally(() => {
|
||||
this.target.requestPointerLock();
|
||||
});
|
||||
}
|
||||
|
||||
onWheel = evt => {
|
||||
|
@ -46,6 +46,9 @@ export class MouseAngleControls {
|
||||
this.speedRight = speedRight;
|
||||
this.speedCapture = speedCapture;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplier = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,12 +60,16 @@ export class MouseAngleControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,14 +110,14 @@ export class MouseAngleControls {
|
||||
*/
|
||||
onMouseMove = evt => {
|
||||
if (document.pointerLockElement) {
|
||||
this.deltaAngle += evt.movementY * this.speedCapture;
|
||||
this.deltaAngle += evt.movementY * this.speedCapture * this.pixelToSpeedMultiplier;
|
||||
}
|
||||
|
||||
else if(this.moving){
|
||||
if (evt.buttons === 1) {
|
||||
this.deltaAngle += (evt.y - this.lastY) * this.speedLeft;
|
||||
this.deltaAngle += (evt.y - this.lastY) * this.speedLeft * this.pixelToSpeedMultiplier;
|
||||
} else {
|
||||
this.deltaAngle += (evt.y - this.lastY) * this.speedRight;
|
||||
this.deltaAngle += (evt.y - this.lastY) * this.speedRight * this.pixelToSpeedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,4 +132,8 @@ export class MouseAngleControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplier = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ import {MathUtils} from "three";
|
||||
export class MouseRotateControls {
|
||||
|
||||
/**
|
||||
* @param target {EventTarget}
|
||||
* @param target {Element}
|
||||
* @param speedLeft {number}
|
||||
* @param speedRight {number}
|
||||
* @param speedCapture {number}
|
||||
@ -46,6 +46,9 @@ export class MouseRotateControls {
|
||||
this.speedRight = speedRight;
|
||||
this.speedCapture = speedCapture;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplier = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,12 +60,16 @@ export class MouseRotateControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,14 +110,14 @@ export class MouseRotateControls {
|
||||
*/
|
||||
onMouseMove = evt => {
|
||||
if (document.pointerLockElement) {
|
||||
this.deltaRotation -= evt.movementX * this.speedCapture;
|
||||
this.deltaRotation -= evt.movementX * this.speedCapture * this.pixelToSpeedMultiplier;
|
||||
}
|
||||
|
||||
else if(this.moving){
|
||||
if (evt.buttons === 1) {
|
||||
this.deltaRotation -= (evt.x - this.lastX) * this.speedLeft;
|
||||
this.deltaRotation -= (evt.x - this.lastX) * this.speedLeft * this.pixelToSpeedMultiplier;
|
||||
} else {
|
||||
this.deltaRotation -= (evt.x - this.lastX) * this.speedRight;
|
||||
this.deltaRotation -= (evt.x - this.lastX) * this.speedRight * this.pixelToSpeedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,4 +132,8 @@ export class MouseRotateControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplier = (1 / this.target.clientWidth) * (this.target.clientWidth / this.target.clientHeight);
|
||||
}
|
||||
|
||||
}
|
@ -30,11 +30,13 @@ export class TouchPanControls {
|
||||
static tempVec2_1 = new Vector2();
|
||||
|
||||
/**
|
||||
* @param target {Element}
|
||||
* @param hammer {Manager}
|
||||
* @param speed {number}
|
||||
* @param stiffness {number}
|
||||
*/
|
||||
constructor(hammer, speed, stiffness) {
|
||||
constructor(target, hammer, speed, stiffness) {
|
||||
this.target = target;
|
||||
this.hammer = hammer;
|
||||
this.manager = null;
|
||||
|
||||
@ -44,6 +46,10 @@ export class TouchPanControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierX = 0;
|
||||
this.pixelToSpeedMultiplierY = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,6 +62,8 @@ export class TouchPanControls {
|
||||
this.hammer.on("movemove", this.onTouchMove);
|
||||
this.hammer.on("moveend", this.onTouchUp);
|
||||
this.hammer.on("movecancel", this.onTouchUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -63,6 +71,8 @@ export class TouchPanControls {
|
||||
this.hammer.off("movemove", this.onTouchMove);
|
||||
this.hammer.off("moveend", this.onTouchUp);
|
||||
this.hammer.off("movecancel", this.onTouchUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,8 +85,8 @@ export class TouchPanControls {
|
||||
let smoothing = this.stiffness / (16.666 / delta);
|
||||
smoothing = MathUtils.clamp(smoothing, 0, 1);
|
||||
|
||||
this.manager.rotation += this.deltaPosition.x * this.speed * this.stiffness;
|
||||
this.manager.angle -= this.deltaPosition.y * this.speed * this.stiffness;
|
||||
this.manager.rotation += this.deltaPosition.x * this.speed * this.pixelToSpeedMultiplierX * this.stiffness;
|
||||
this.manager.angle -= this.deltaPosition.y * this.speed * this.pixelToSpeedMultiplierY * this.stiffness;
|
||||
|
||||
this.deltaPosition.multiplyScalar(1 - smoothing);
|
||||
if (this.deltaPosition.lengthSq() < 0.0001) {
|
||||
@ -126,4 +136,9 @@ export class TouchPanControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierX = (1 / this.target.clientWidth) * (this.target.clientWidth / this.target.clientHeight);
|
||||
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -27,9 +27,9 @@ import {MouseMoveControls} from "./mouse/MouseMoveControls";
|
||||
import {MouseZoomControls} from "./mouse/MouseZoomControls";
|
||||
import {MouseRotateControls} from "./mouse/MouseRotateControls";
|
||||
import {MouseAngleControls} from "./mouse/MouseAngleControls";
|
||||
import {MathUtils, Vector2} from "three";
|
||||
import {MathUtils, Vector2, Vector3} from "three";
|
||||
import {Manager, Pan, Pinch, Rotate, Tap, DIRECTION_ALL, DIRECTION_VERTICAL} from "hammerjs";
|
||||
import {animate, EasingFunctions, softClamp} from "../../util/Utils";
|
||||
import {softClamp} from "../../util/Utils";
|
||||
import {MapHeightControls} from "./MapHeightControls";
|
||||
import {KeyMoveControls} from "./keyboard/KeyMoveControls";
|
||||
import {KeyAngleControls} from "./keyboard/KeyAngleControls";
|
||||
@ -39,29 +39,34 @@ import {TouchMoveControls} from "./touch/TouchMoveControls";
|
||||
import {TouchRotateControls} from "./touch/TouchRotateControls";
|
||||
import {TouchAngleControls} from "./touch/TouchAngleControls";
|
||||
import {TouchZoomControls} from "./touch/TouchZoomControls";
|
||||
import {PlayerMarker} from "../../markers/PlayerMarker";
|
||||
|
||||
const HALF_PI = Math.PI * 0.5;
|
||||
|
||||
export class MapControls {
|
||||
|
||||
static _beforeMoveTemp = new Vector3();
|
||||
|
||||
/**
|
||||
* @param rootElement {EventTarget}
|
||||
* @param rootElement {Element}
|
||||
*/
|
||||
constructor(rootElement) {
|
||||
this.rootElement = rootElement;
|
||||
|
||||
this.data = {
|
||||
followingPlayer: null
|
||||
};
|
||||
|
||||
/** @type {ControlsManager} */
|
||||
this.manager = null;
|
||||
|
||||
this.started = false;
|
||||
|
||||
this.hammer = new Manager(this.rootElement);
|
||||
this.initializeHammer();
|
||||
|
||||
//controls
|
||||
this.mouseMove = new MouseMoveControls(this.rootElement, 0.002,0.3);
|
||||
this.mouseRotate = new MouseRotateControls(this.rootElement, 0.004, 0.3);
|
||||
this.mouseAngle = new MouseAngleControls(this.rootElement, 0.004, 0.3);
|
||||
this.mouseMove = new MouseMoveControls(this.rootElement, 1.5,0.3);
|
||||
this.mouseRotate = new MouseRotateControls(this.rootElement, 6, 0.3);
|
||||
this.mouseAngle = new MouseAngleControls(this.rootElement, 3, 0.3);
|
||||
this.mouseZoom = new MouseZoomControls(this.rootElement, 1, 0.2);
|
||||
|
||||
this.keyMove = new KeyMoveControls(this.rootElement, 0.025, 0.2);
|
||||
@ -69,14 +74,15 @@ export class MapControls {
|
||||
this.keyAngle = new KeyAngleControls(this.rootElement, 0.04, 0.15);
|
||||
this.keyZoom = new KeyZoomControls(this.rootElement, 0.2, 0.15);
|
||||
|
||||
this.touchMove = new TouchMoveControls(this.hammer, 0.002,0.3);
|
||||
this.touchMove = new TouchMoveControls(this.rootElement, this.hammer, 1.5,0.3);
|
||||
this.touchRotate = new TouchRotateControls(this.hammer, 0.0174533, 0.3);
|
||||
this.touchAngle = new TouchAngleControls(this.hammer, 0.01, 0.3);
|
||||
this.touchAngle = new TouchAngleControls(this.rootElement, this.hammer, 3, 0.3);
|
||||
this.touchZoom = new TouchZoomControls(this.hammer);
|
||||
|
||||
this.mapHeight = new MapHeightControls(0.2, 0.1);
|
||||
|
||||
this.animationTargetHeight = 0;
|
||||
this.lastTap = -1;
|
||||
this.lastTapCenter = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,27 +110,11 @@ export class MapControls {
|
||||
this.touchZoom.start(manager);
|
||||
|
||||
this.mapHeight.start(manager);
|
||||
|
||||
|
||||
let startOrtho = this.manager.ortho;
|
||||
let startDistance = this.manager.distance;
|
||||
let startAngle = this.manager.angle;
|
||||
let startY = this.manager.position.y;
|
||||
|
||||
let targetDistance = MathUtils.clamp(this.manager.distance, 100, 10000);
|
||||
let targetAngle = Math.min(startAngle, this.getMaxPerspectiveAngleForDistance(targetDistance));
|
||||
|
||||
animate(progress => {
|
||||
let smoothProgress = EasingFunctions.easeInOutQuad(progress);
|
||||
|
||||
this.manager.ortho = MathUtils.lerp(startOrtho, 0, progress);
|
||||
this.manager.distance = MathUtils.lerp(startDistance, targetDistance, smoothProgress);
|
||||
this.manager.angle = MathUtils.lerp(startAngle, targetAngle, smoothProgress);
|
||||
this.manager.position.y = MathUtils.lerp(startY, this.animationTargetHeight, smoothProgress);
|
||||
}, 500, () => this.started = true);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.stopFollowingPlayerMarker();
|
||||
|
||||
this.rootElement.removeEventListener("contextmenu", this.onContextMenu);
|
||||
this.hammer.off("tap", this.onTap);
|
||||
|
||||
@ -144,8 +134,6 @@ export class MapControls {
|
||||
this.touchZoom.stop();
|
||||
|
||||
this.mapHeight.stop();
|
||||
|
||||
this.started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,18 +141,27 @@ export class MapControls {
|
||||
* @param map {Map}
|
||||
*/
|
||||
update(delta, map) {
|
||||
if (!this.started){
|
||||
this.mapHeight.updateHeights(delta, map);
|
||||
this.animationTargetHeight = this.mapHeight.getSuggestedHeight();
|
||||
return;
|
||||
this.manager.position.y = 0; // reset target y position
|
||||
|
||||
// move
|
||||
MapControls._beforeMoveTemp.copy(this.manager.position);
|
||||
this.mouseMove.update(delta, map);
|
||||
this.keyMove.update(delta, map);
|
||||
this.touchMove.update(delta, map);
|
||||
|
||||
// if moved, stop following the marker and give back control
|
||||
if (this.data.followingPlayer && !MapControls._beforeMoveTemp.equals(this.manager.position)) {
|
||||
this.stopFollowingPlayerMarker();
|
||||
}
|
||||
|
||||
// move and zoom
|
||||
this.mouseMove.update(delta, map);
|
||||
// follow player marker
|
||||
if (this.data.followingPlayer) {
|
||||
this.manager.position.copy(this.data.followingPlayer.position);
|
||||
}
|
||||
|
||||
// zoom
|
||||
this.mouseZoom.update(delta, map);
|
||||
this.keyMove.update(delta, map);
|
||||
this.keyZoom.update(delta, map);
|
||||
this.touchMove.update(delta, map);
|
||||
this.touchZoom.update(delta, map);
|
||||
|
||||
this.manager.distance = softClamp(this.manager.distance, 5, 10000, 0.8);
|
||||
@ -189,7 +186,6 @@ export class MapControls {
|
||||
|
||||
// target height
|
||||
if (this.manager.ortho === 0 || this.manager.angle === 0) {
|
||||
this.manager.position.y = 0;
|
||||
this.mapHeight.maxAngle = maxAngleForZoom;
|
||||
this.mapHeight.update(delta, map);
|
||||
}
|
||||
@ -211,38 +207,6 @@ export class MapControls {
|
||||
return MathUtils.clamp((1 - Math.pow(Math.max(distance - 5, 0.001) / 500, 0.5)) * HALF_PI,0, HALF_PI)
|
||||
}
|
||||
|
||||
setPerspectiveView() {
|
||||
this.reset();
|
||||
|
||||
let startOrtho = this.manager.ortho;
|
||||
let startAngle = this.manager.angle;
|
||||
|
||||
let targetAngle = Math.min(startAngle, this.getMaxPerspectiveAngleForDistance(this.manager.distance));
|
||||
|
||||
animate(progress => {
|
||||
let smoothProgress = EasingFunctions.easeInOutQuad(progress);
|
||||
|
||||
this.manager.ortho = MathUtils.lerp(startOrtho, 0, progress);
|
||||
this.manager.angle = MathUtils.lerp(startAngle, targetAngle, smoothProgress);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
setOrthographicView(targetRotation = 0, targetAngle = 0) {
|
||||
this.reset();
|
||||
|
||||
let startOrtho = this.manager.ortho;
|
||||
let startAngle = this.manager.angle;
|
||||
let startRotation = this.manager.rotation;
|
||||
|
||||
animate(progress => {
|
||||
let smoothProgress = EasingFunctions.easeInOutQuad(progress);
|
||||
|
||||
this.manager.ortho = MathUtils.lerp(startOrtho, 1, progress);
|
||||
this.manager.angle = MathUtils.lerp(startAngle, targetAngle, smoothProgress);
|
||||
this.manager.rotation = MathUtils.lerp(startRotation, targetRotation, smoothProgress);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
initializeHammer() {
|
||||
let touchTap = new Tap({ event: 'tap', pointers: 1, taps: 1, threshold: 5 });
|
||||
let touchMove = new Pan({ event: 'move', pointers: 1, direction: DIRECTION_ALL, threshold: 0 });
|
||||
@ -264,12 +228,36 @@ export class MapControls {
|
||||
this.hammer.add(touchZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param marker {object}
|
||||
*/
|
||||
followPlayerMarker(marker) {
|
||||
if (marker.isPlayerMarker) marker = marker.data;
|
||||
this.data.followingPlayer = marker;
|
||||
}
|
||||
|
||||
stopFollowingPlayerMarker() {
|
||||
this.data.followingPlayer = null;
|
||||
}
|
||||
|
||||
onContextMenu = evt => {
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
onTap = evt => {
|
||||
this.manager.handleMapInteraction(new Vector2(evt.center.x, evt.center.y));
|
||||
let doubleTap = false;
|
||||
let center = new Vector2(evt.center.x, evt.center.y);
|
||||
|
||||
let now = Date.now();
|
||||
if (this.lastTap > 0 && this.lastTapCenter && now - this.lastTap < 500 && this.lastTapCenter.distanceTo(center) < 5){
|
||||
doubleTap = true;
|
||||
this.lastTap = -1;
|
||||
} else {
|
||||
this.lastTap = now;
|
||||
this.lastTapCenter = center;
|
||||
}
|
||||
|
||||
this.manager.handleMapInteraction(new Vector2(evt.center.x, evt.center.y), {doubleTap: doubleTap});
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,9 @@ export class MouseAngleControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierY = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,12 +56,16 @@ export class MouseAngleControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +78,7 @@ export class MouseAngleControls {
|
||||
let smoothing = this.stiffness / (16.666 / delta);
|
||||
smoothing = MathUtils.clamp(smoothing, 0, 1);
|
||||
|
||||
this.manager.angle += this.deltaAngle * smoothing * this.speed;
|
||||
this.manager.angle += this.deltaAngle * smoothing * this.speed * this.pixelToSpeedMultiplierY;
|
||||
|
||||
this.deltaAngle *= 1 - smoothing;
|
||||
if (Math.abs(this.deltaAngle) < 0.0001) {
|
||||
@ -116,4 +123,8 @@ export class MouseAngleControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -31,7 +31,7 @@ export class MouseMoveControls {
|
||||
static tempVec2_1 = new Vector2();
|
||||
|
||||
/**
|
||||
* @param target {EventTarget}
|
||||
* @param target {Element}
|
||||
* @param speed {number}
|
||||
* @param stiffness {number}
|
||||
*/
|
||||
@ -45,6 +45,10 @@ export class MouseMoveControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierX = 0;
|
||||
this.pixelToSpeedMultiplierY = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,12 +60,16 @@ export class MouseMoveControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,8 +85,8 @@ export class MouseMoveControls {
|
||||
let directionDelta = MouseMoveControls.tempVec2_1.copy(this.deltaPosition);
|
||||
directionDelta.rotateAround(VEC2_ZERO, this.manager.rotation);
|
||||
|
||||
this.manager.position.x += directionDelta.x * smoothing * this.manager.distance * this.speed;
|
||||
this.manager.position.z += directionDelta.y * smoothing * this.manager.distance * this.speed;
|
||||
this.manager.position.x += directionDelta.x * smoothing * this.manager.distance * this.speed * this.pixelToSpeedMultiplierX;
|
||||
this.manager.position.z += directionDelta.y * smoothing * this.manager.distance * this.speed * this.pixelToSpeedMultiplierY;
|
||||
|
||||
this.deltaPosition.multiplyScalar(1 - smoothing);
|
||||
if (this.deltaPosition.lengthSq() < 0.0001) {
|
||||
@ -124,4 +132,9 @@ export class MouseMoveControls {
|
||||
if (evt.button === 0) this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierX = (1 / this.target.clientWidth) * (this.target.clientWidth / this.target.clientHeight);
|
||||
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,9 @@ export class MouseRotateControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierX = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,12 +56,16 @@ export class MouseRotateControls {
|
||||
this.target.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.target.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +78,7 @@ export class MouseRotateControls {
|
||||
let smoothing = this.stiffness / (16.666 / delta);
|
||||
smoothing = MathUtils.clamp(smoothing, 0, 1);
|
||||
|
||||
this.manager.rotation += this.deltaRotation * smoothing * this.speed;
|
||||
this.manager.rotation += this.deltaRotation * smoothing * this.speed * this.pixelToSpeedMultiplierX;
|
||||
|
||||
this.deltaRotation *= 1 - smoothing;
|
||||
if (Math.abs(this.deltaRotation) < 0.0001) {
|
||||
@ -116,4 +123,8 @@ export class MouseRotateControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierX = (1 / this.target.clientWidth); //* (this.target.clientWidth / this.target.clientHeight);
|
||||
}
|
||||
|
||||
}
|
@ -28,11 +28,13 @@ import {MathUtils} from "three";
|
||||
export class TouchAngleControls {
|
||||
|
||||
/**
|
||||
* @param target {Element}
|
||||
* @param hammer {Manager}
|
||||
* @param speed {number}
|
||||
* @param stiffness {number}
|
||||
*/
|
||||
constructor(hammer, speed, stiffness) {
|
||||
constructor(target, hammer, speed, stiffness) {
|
||||
this.target = target;
|
||||
this.hammer = hammer;
|
||||
this.manager = null;
|
||||
|
||||
@ -42,6 +44,9 @@ export class TouchAngleControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierY = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,6 +59,8 @@ export class TouchAngleControls {
|
||||
this.hammer.on("tiltmove", this.onTouchMove);
|
||||
this.hammer.on("tiltend", this.onTouchUp);
|
||||
this.hammer.on("tiltcancel", this.onTouchUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -61,6 +68,8 @@ export class TouchAngleControls {
|
||||
this.hammer.off("tiltmove", this.onTouchMove);
|
||||
this.hammer.off("tiltend", this.onTouchUp);
|
||||
this.hammer.off("tiltcancel", this.onTouchUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +82,7 @@ export class TouchAngleControls {
|
||||
let smoothing = this.stiffness / (16.666 / delta);
|
||||
smoothing = MathUtils.clamp(smoothing, 0, 1);
|
||||
|
||||
this.manager.angle += this.deltaAngle * smoothing * this.speed;
|
||||
this.manager.angle += this.deltaAngle * smoothing * this.speed * this.pixelToSpeedMultiplierY;
|
||||
|
||||
this.deltaAngle *= 1 - smoothing;
|
||||
if (Math.abs(this.deltaAngle) < 0.0001) {
|
||||
@ -115,4 +124,8 @@ export class TouchAngleControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -31,11 +31,13 @@ export class TouchMoveControls {
|
||||
static tempVec2_1 = new Vector2();
|
||||
|
||||
/**
|
||||
* @param target {Element}
|
||||
* @param hammer {Manager}
|
||||
* @param speed {number}
|
||||
* @param stiffness {number}
|
||||
*/
|
||||
constructor(hammer, speed, stiffness) {
|
||||
constructor(target, hammer, speed, stiffness) {
|
||||
this.target = target;
|
||||
this.hammer = hammer;
|
||||
this.manager = null;
|
||||
|
||||
@ -45,6 +47,10 @@ export class TouchMoveControls {
|
||||
|
||||
this.speed = speed;
|
||||
this.stiffness = stiffness;
|
||||
|
||||
this.pixelToSpeedMultiplierX = 0;
|
||||
this.pixelToSpeedMultiplierY = 0;
|
||||
this.updatePixelToSpeedMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +63,8 @@ export class TouchMoveControls {
|
||||
this.hammer.on("movemove", this.onTouchMove);
|
||||
this.hammer.on("moveend", this.onTouchUp);
|
||||
this.hammer.on("movecancel", this.onTouchUp);
|
||||
|
||||
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -64,6 +72,8 @@ export class TouchMoveControls {
|
||||
this.hammer.off("movemove", this.onTouchMove);
|
||||
this.hammer.off("moveend", this.onTouchUp);
|
||||
this.hammer.off("movecancel", this.onTouchUp);
|
||||
|
||||
window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,8 +89,8 @@ export class TouchMoveControls {
|
||||
let directionDelta = TouchMoveControls.tempVec2_1.copy(this.deltaPosition);
|
||||
directionDelta.rotateAround(VEC2_ZERO, this.manager.rotation);
|
||||
|
||||
this.manager.position.x += directionDelta.x * smoothing * this.manager.distance * this.speed;
|
||||
this.manager.position.z += directionDelta.y * smoothing * this.manager.distance * this.speed;
|
||||
this.manager.position.x += directionDelta.x * smoothing * this.manager.distance * this.speed * this.pixelToSpeedMultiplierX;
|
||||
this.manager.position.z += directionDelta.y * smoothing * this.manager.distance * this.speed * this.pixelToSpeedMultiplierY;
|
||||
|
||||
this.deltaPosition.multiplyScalar(1 - smoothing);
|
||||
if (this.deltaPosition.lengthSq() < 0.0001) {
|
||||
@ -130,4 +140,9 @@ export class TouchMoveControls {
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
updatePixelToSpeedMultiplier = () => {
|
||||
this.pixelToSpeedMultiplierX = (1 / this.target.clientWidth) * (this.target.clientWidth / this.target.clientHeight);
|
||||
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
|
||||
}
|
||||
|
||||
}
|
@ -27,7 +27,7 @@ import {
|
||||
FileLoader, FrontSide, NearestFilter, NearestMipMapLinearFilter, Raycaster,
|
||||
Scene, ShaderMaterial, Texture, Vector2, Vector3, VertexColors
|
||||
} from "three";
|
||||
import {alert, dispatchEvent, hashTile, stringToImage} from "../util/Utils";
|
||||
import {alert, dispatchEvent, generateCacheHash, hashTile, stringToImage} from "../util/Utils";
|
||||
import {TileManager} from "./TileManager";
|
||||
import {TileLoader} from "./TileLoader";
|
||||
import {MarkerFileManager} from "../markers/MarkerFileManager";
|
||||
@ -42,7 +42,7 @@ export class Map {
|
||||
* @param texturesUrl {string}
|
||||
* @param events {EventTarget}
|
||||
*/
|
||||
constructor(id, dataUrl, settingsUrl, texturesUrl, events = null) {
|
||||
constructor(id, dataUrl, settingsUrl, texturesUrl, events = null) {
|
||||
Object.defineProperty( this, 'isMap', { value: true } );
|
||||
|
||||
this.events = events;
|
||||
@ -91,9 +91,10 @@ export class Map {
|
||||
* @param lowresVertexShader {string}
|
||||
* @param lowresFragmentShader {string}
|
||||
* @param uniforms {object}
|
||||
* @param tileCacheHash {number}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
load(hiresVertexShader, hiresFragmentShader, lowresVertexShader, lowresFragmentShader, uniforms) {
|
||||
load(hiresVertexShader, hiresFragmentShader, lowresVertexShader, lowresFragmentShader, uniforms, tileCacheHash = 0) {
|
||||
this.unload()
|
||||
|
||||
let settingsPromise = this.loadSettings();
|
||||
@ -108,8 +109,8 @@ export class Map {
|
||||
|
||||
this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures);
|
||||
|
||||
this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}hires/`, this.hiresMaterial, this.data.hires), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events);
|
||||
this.lowresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}lowres/`, this.lowresMaterial, this.data.lowres), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
|
||||
this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}hires/`, this.hiresMaterial, this.data.hires, tileCacheHash), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events);
|
||||
this.lowresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}lowres/`, this.lowresMaterial, this.data.lowres, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
|
||||
|
||||
this.hiresTileManager.scene.autoUpdate = false;
|
||||
this.lowresTileManager.scene.autoUpdate = false;
|
||||
@ -201,7 +202,7 @@ export class Map {
|
||||
|
||||
let loader = new FileLoader();
|
||||
loader.setResponseType("json");
|
||||
loader.load(this.data.settingsUrl,
|
||||
loader.load(this.data.settingsUrl + "?" + generateCacheHash(),
|
||||
settings => {
|
||||
if (settings.maps && settings.maps[this.data.id]) {
|
||||
resolve(settings.maps[this.data.id]);
|
||||
@ -225,7 +226,7 @@ export class Map {
|
||||
|
||||
let loader = new FileLoader();
|
||||
loader.setResponseType("json");
|
||||
loader.load(this.data.texturesUrl,
|
||||
loader.load(this.data.texturesUrl + "?" + generateCacheHash(),
|
||||
resolve,
|
||||
() => {},
|
||||
() => reject(`Failed to load the textures.json for map: ${this.data.id}`)
|
||||
|
@ -31,13 +31,14 @@ export class TileLoader {
|
||||
* @param tilePath {string}
|
||||
* @param material {THREE.Material | THREE.Material[]}
|
||||
* @param tileSettings {{
|
||||
* tileSize: {x: number, z: number},
|
||||
* scale: {x: number, z: number},
|
||||
* tileSize: {x: number, z: number},
|
||||
* scale: {x: number, z: number},
|
||||
* translate: {x: number, z: number}
|
||||
* }}
|
||||
* @param tileCacheHash {number}
|
||||
* @param layer {number}
|
||||
*/
|
||||
constructor(tilePath, material, tileSettings, layer = 0) {
|
||||
constructor(tilePath, material, tileSettings, tileCacheHash = 0, layer = 0) {
|
||||
Object.defineProperty( this, 'isTileLoader', { value: true } );
|
||||
|
||||
this.tilePath = tilePath;
|
||||
@ -46,6 +47,8 @@ export class TileLoader {
|
||||
|
||||
this.layer = layer;
|
||||
|
||||
this.tileCacheHash = tileCacheHash;
|
||||
|
||||
this.fileLoader = new FileLoader();
|
||||
this.fileLoader.setResponseType('json');
|
||||
|
||||
@ -53,8 +56,10 @@ export class TileLoader {
|
||||
}
|
||||
|
||||
load = (tileX, tileZ) => {
|
||||
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.fileLoader.load(this.tilePath + pathFromCoords(tileX, tileZ) + '.json',
|
||||
this.fileLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||
geometryJson => {
|
||||
if (!geometryJson.type || geometryJson.type !== 'BufferGeometry') reject({status: "empty"});
|
||||
|
||||
@ -69,7 +74,7 @@ export class TileLoader {
|
||||
object.position.set(tileX * tileSize.x + translate.x, 0, tileZ * tileSize.z + translate.z);
|
||||
object.scale.set(scale.x, 1, scale.z);
|
||||
|
||||
object.userData.tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.json';
|
||||
object.userData.tileUrl = tileUrl;
|
||||
|
||||
object.updateMatrixWorld(true);
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
import {FileLoader, Scene} from "three";
|
||||
import {MarkerSet} from "./MarkerSet";
|
||||
import {alert} from "../util/Utils";
|
||||
import {alert, generateCacheHash} from "../util/Utils";
|
||||
|
||||
/**
|
||||
* A manager for loading and updating markers from a file
|
||||
@ -170,7 +170,7 @@ export class MarkerManager {
|
||||
return new Promise((resolve, reject) => {
|
||||
let loader = new FileLoader();
|
||||
loader.setResponseType("json");
|
||||
loader.load(this.fileUrl,
|
||||
loader.load(this.fileUrl + "?" + generateCacheHash(),
|
||||
markerFileData => {
|
||||
if (!markerFileData) reject(`Failed to parse '${this.fileUrl}'!`);
|
||||
else resolve(markerFileData);
|
||||
|
@ -41,6 +41,8 @@ export class ObjectMarker extends Marker {
|
||||
this.data.detail = null;
|
||||
this.data.link = null;
|
||||
this.data.newTab = true;
|
||||
|
||||
this.lastClick = -1;
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
@ -50,6 +52,8 @@ export class ObjectMarker extends Marker {
|
||||
pos.sub(this.position);
|
||||
}
|
||||
|
||||
if (event.data.doubleTap) return false;
|
||||
|
||||
if (this.data.detail || this.data.label) {
|
||||
let popup = new LabelPopup(this.data.detail || this.data.label);
|
||||
popup.position.copy(pos);
|
||||
|
@ -40,6 +40,8 @@ export class PlayerMarker extends Marker {
|
||||
this.data.playerUuid = playerUuid;
|
||||
this.data.name = playerUuid;
|
||||
|
||||
this.data.world = "?";
|
||||
|
||||
this.elementObject = new CSS2DObject(htmlToElement(`
|
||||
<div id="bm-marker-${this.data.id}" class="bm-marker-${this.data.type}">
|
||||
<img src="assets/playerheads/${this.data.playerUuid}.png" alt="playerhead" draggable="false">
|
||||
@ -135,6 +137,9 @@ export class PlayerMarker extends Marker {
|
||||
if (this.playerNameElement.innerHTML !== name)
|
||||
this.playerNameElement.innerHTML = name;
|
||||
|
||||
// update world
|
||||
this.data.world = markerData.world || "?";
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
@ -43,11 +43,13 @@ export class PoiMarker extends HtmlMarker {
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
if (event.data.doubleTap) return false;
|
||||
|
||||
if (this.highlight || !this.data.label) return true;
|
||||
this.highlight = true;
|
||||
|
||||
let eventHandler = evt => {
|
||||
if (evt.path.includes(this.element)) return;
|
||||
if (evt.composedPath().includes(this.element)) return;
|
||||
|
||||
this.highlight = false;
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
Object3D, Vector2,
|
||||
Vector3
|
||||
} from "three";
|
||||
import {htmlToElement} from "./Utils";
|
||||
import {dispatchEvent, htmlToElement} from "./Utils";
|
||||
|
||||
var CSS2DObject = function ( element ) {
|
||||
|
||||
@ -24,6 +24,8 @@ var CSS2DObject = function ( element ) {
|
||||
|
||||
this.anchor = new Vector2();
|
||||
|
||||
this.events = null;
|
||||
|
||||
this.addEventListener( 'removed', function () {
|
||||
|
||||
this.traverse( function ( object ) {
|
||||
@ -38,18 +40,33 @@ var CSS2DObject = function ( element ) {
|
||||
|
||||
} );
|
||||
|
||||
this.element.addEventListener("click", event => {
|
||||
if (this.onClick(event)) {
|
||||
let lastClick = -1;
|
||||
let handleClick = event => {
|
||||
let doubleTap = false;
|
||||
|
||||
let now = Date.now();
|
||||
if (now - lastClick < 500){
|
||||
doubleTap = true;
|
||||
}
|
||||
|
||||
lastClick = now;
|
||||
|
||||
let data = {doubleTap: doubleTap};
|
||||
|
||||
if (this.onClick( {event: event, data: data} )) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
// fire event
|
||||
dispatchEvent(this.events, "bluemapMapInteraction", {
|
||||
data: data,
|
||||
object: this,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.element.addEventListener("touch", event => {
|
||||
if (this.onClick(event)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.element.addEventListener("click", handleClick);
|
||||
this.element.addEventListener("touch", handleClick);
|
||||
|
||||
};
|
||||
|
||||
@ -58,7 +75,7 @@ CSS2DObject.prototype.constructor = CSS2DObject;
|
||||
|
||||
//
|
||||
|
||||
var CSS2DRenderer = function () {
|
||||
var CSS2DRenderer = function (events = null) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
@ -78,6 +95,8 @@ var CSS2DRenderer = function () {
|
||||
|
||||
this.domElement = domElement;
|
||||
|
||||
this.events = events;
|
||||
|
||||
this.getSize = function () {
|
||||
|
||||
return {
|
||||
@ -104,6 +123,8 @@ var CSS2DRenderer = function () {
|
||||
|
||||
if ( object instanceof CSS2DObject ) {
|
||||
|
||||
object.events = _this.events;
|
||||
|
||||
object.onBeforeRender( _this, scene, camera );
|
||||
|
||||
vector.setFromMatrixPosition( object.matrixWorld );
|
||||
|
@ -89,6 +89,9 @@ const splitNumberToPath = num => {
|
||||
*/
|
||||
export const hashTile = (x, z) => `x${x}z${z}`;
|
||||
|
||||
export const generateCacheHash = () => {
|
||||
return Math.round(Math.random() * 1000000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an event to the element of this map-viewer
|
||||
@ -184,7 +187,7 @@ export const animate = function (animationFrame, durationMs = 1000, postAnimatio
|
||||
this.lastFrame = time;
|
||||
}
|
||||
|
||||
let progress = MathUtils.clamp((time - this.animationStart) / durationMs, 0, 1);
|
||||
let progress = durationMs === 0 ? 1 : MathUtils.clamp((time - this.animationStart) / durationMs, 0, 1);
|
||||
let deltaTime = time - this.lastFrame;
|
||||
|
||||
animationFrame(progress, deltaTime);
|
||||
|
Loading…
Reference in New Issue
Block a user