Skip to content

Commit

Permalink
Make the camera zoom-in when tilting, instead of blocking the tilt. C…
Browse files Browse the repository at this point in the history
…loses: #279
  • Loading branch information
TBlueF committed Nov 27, 2024
1 parent 05a1cac commit b32f808
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 8 deletions.
7 changes: 2 additions & 5 deletions common/webapp/src/js/controls/map/MapControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export class MapControls {
*/
start(manager) {
this.manager = manager;
this.snapDistance = manager.distance;

this.rootElement.addEventListener("contextmenu", this.onContextMenu);
this.hammer.on("tap", this.onTap);
Expand Down Expand Up @@ -172,9 +173,6 @@ export class MapControls {

this.manager.distance = softClamp(this.manager.distance, this.minDistance, this.maxDistance, 0.8);

// max angle for current distance
let maxAngleForZoom = MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance);

// rotation
this.mouseRotate.update(delta, map);
this.keyRotate.update(delta, map);
Expand All @@ -193,12 +191,11 @@ export class MapControls {
this.mouseAngle.update(delta, map);
this.keyAngle.update(delta, map);
this.touchAngle.update(delta, map);
this.manager.angle = softClamp(this.manager.angle, 0, maxAngleForZoom, 0.8);
this.manager.angle = softClamp(this.manager.angle, 0, HALF_PI, 0.8);
}

// target height
if (this.manager.ortho === 0 || this.manager.angle === 0) {
this.mapHeight.maxAngle = maxAngleForZoom;
this.mapHeight.update(delta, map);
}
}
Expand Down
7 changes: 4 additions & 3 deletions common/webapp/src/js/controls/map/MapHeightControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/

import {MathUtils, Vector2} from "three";
import {MapControls} from "./MapControls";

export class MapHeightControls {

Expand All @@ -36,7 +37,6 @@ export class MapHeightControls {

this.cameraHeightStiffness = cameraHeightStiffness;
this.targetHeightStiffness = targetHeightStiffness;
this.maxAngle = Math.PI / 2;

this.targetHeight = 0;
this.cameraHeight = 0;
Expand Down Expand Up @@ -78,7 +78,8 @@ export class MapHeightControls {

// camera height
this.minCameraHeight = 0;
if (this.maxAngle >= 0.1) {
let maxAngle = MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance);
if (maxAngle >= 0.1) {
let cameraSmoothing = this.cameraHeightStiffness / (16.666 / delta);
cameraSmoothing = MathUtils.clamp(cameraSmoothing, 0, 1);

Expand All @@ -88,7 +89,7 @@ export class MapHeightControls {
this.cameraHeight += cameraDelta * cameraSmoothing;
if (Math.abs(cameraDelta) < 0.001) this.cameraHeight = cameraTerrainHeight;

let maxAngleHeight = Math.cos(this.maxAngle) * this.manager.distance;
let maxAngleHeight = Math.cos(maxAngle) * this.manager.distance;
this.minCameraHeight = this.cameraHeight - maxAngleHeight + 1;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

import {MathUtils} from "three";
import {KeyCombination} from "../../KeyCombination";
import {softMax} from "../../../util/Utils";
import {MapControls} from "../MapControls";

export class KeyAngleControls {

Expand Down Expand Up @@ -90,6 +92,7 @@ export class KeyAngleControls {
smoothing = MathUtils.clamp(smoothing, 0, 1);

this.manager.angle += this.deltaAngle * smoothing * this.speed * delta * 0.06;
this.manager.angle = softMax(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance), 0.8);

this.deltaAngle *= 1 - smoothing;
if (Math.abs(this.deltaAngle) < 0.0001) {
Expand Down
2 changes: 2 additions & 0 deletions common/webapp/src/js/controls/map/keyboard/KeyZoomControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import {MathUtils} from "three";
import {KeyCombination} from "../../KeyCombination";
import {MapControls} from "../MapControls";

export class KeyZoomControls {

Expand Down Expand Up @@ -88,6 +89,7 @@ export class KeyZoomControls {
smoothing = MathUtils.clamp(smoothing, 0, 1);

this.manager.distance *= Math.pow(1.5, this.deltaZoom * smoothing * this.speed * delta * 0.06);
this.manager.angle = Math.min(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance));

this.deltaZoom *= 1 - smoothing;
if (Math.abs(this.deltaZoom) < 0.0001) {
Expand Down
20 changes: 20 additions & 0 deletions common/webapp/src/js/controls/map/mouse/MouseAngleControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/

import {MathUtils} from "three";
import {MapControls} from "../MapControls";
import {softMax, softSet} from "../../../util/Utils";

export class MouseAngleControls {

Expand All @@ -40,6 +42,9 @@ export class MouseAngleControls {
this.lastY = 0;
this.deltaAngle = 0;

this.dynamicDistance = false;
this.startDistance = 0;

this.speed = speed;
this.stiffness = stiffness;

Expand All @@ -56,6 +61,7 @@ export class MouseAngleControls {
this.target.addEventListener("mousedown", this.onMouseDown);
window.addEventListener("mousemove", this.onMouseMove);
window.addEventListener("mouseup", this.onMouseUp);
window.addEventListener("wheel", this.onWheel);

window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
}
Expand All @@ -64,6 +70,7 @@ export class MouseAngleControls {
this.target.removeEventListener("mousedown", this.onMouseDown);
window.removeEventListener("mousemove", this.onMouseMove);
window.removeEventListener("mouseup", this.onMouseUp);
window.removeEventListener("wheel", this.onWheel);

window.removeEventListener("resize", this.updatePixelToSpeedMultiplier);
}
Expand All @@ -80,6 +87,12 @@ export class MouseAngleControls {

this.manager.angle += this.deltaAngle * smoothing * this.speed * this.pixelToSpeedMultiplierY;

if (this.dynamicDistance) {
this.manager.distance = softSet(this.manager.distance, Math.min(MapControls.getMaxDistanceForPerspectiveAngle(this.manager.angle), this.startDistance), 0.4);
} else {
this.manager.angle = softMax(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance), 0.8);
}

this.deltaAngle *= 1 - smoothing;
if (Math.abs(this.deltaAngle) < 0.0001) {
this.deltaAngle = 0;
Expand All @@ -100,6 +113,9 @@ export class MouseAngleControls {
this.moving = true;
this.deltaAngle = 0;
this.lastY = evt.y;

this.startDistance = this.manager.distance;
this.dynamicDistance = this.manager.distance < 1000;
}
}

Expand All @@ -123,6 +139,10 @@ export class MouseAngleControls {
this.moving = false;
}

onWheel = evt => {
this.dynamicDistance = false;
}

updatePixelToSpeedMultiplier = () => {
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
}
Expand Down
2 changes: 2 additions & 0 deletions common/webapp/src/js/controls/map/mouse/MouseZoomControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/

import {MathUtils} from "three";
import {MapControls} from "../MapControls";

export class MouseZoomControls {

Expand Down Expand Up @@ -66,6 +67,7 @@ export class MouseZoomControls {
smoothing = MathUtils.clamp(smoothing, 0, 1);

this.manager.distance *= Math.pow(1.5, this.deltaZoom * smoothing * this.speed);
this.manager.angle = Math.min(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance));

this.deltaZoom *= 1 - smoothing;
if (Math.abs(this.deltaZoom) < 0.0001) {
Expand Down
3 changes: 3 additions & 0 deletions common/webapp/src/js/controls/map/touch/TouchAngleControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/

import {MathUtils} from "three";
import {softMax} from "../../../util/Utils";
import {MapControls} from "../MapControls";

export class TouchAngleControls {

Expand Down Expand Up @@ -83,6 +85,7 @@ export class TouchAngleControls {
smoothing = MathUtils.clamp(smoothing, 0, 1);

this.manager.angle += this.deltaAngle * smoothing * this.speed * this.pixelToSpeedMultiplierY;
this.manager.angle = softMax(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance), 0.8);

this.deltaAngle *= 1 - smoothing;
if (Math.abs(this.deltaAngle) < 0.0001) {
Expand Down
3 changes: 3 additions & 0 deletions common/webapp/src/js/controls/map/touch/TouchZoomControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* THE SOFTWARE.
*/

import {MapControls} from "../MapControls";

export class TouchZoomControls {

/**
Expand Down Expand Up @@ -87,6 +89,7 @@ export class TouchZoomControls {
onTouchMove = evt => {
if(this.moving){
this.deltaZoom *= evt.scale / this.lastZoom;
this.manager.angle = Math.min(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance));
}

this.lastZoom = evt.scale;
Expand Down
11 changes: 11 additions & 0 deletions common/webapp/src/js/util/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,17 @@ export const softClamp = (value, min, max, stiffness) => {
return softMax(softMin(value, min, stiffness), max, stiffness);
}

/**
* Softly sets a value
* @param value {number}
* @param target {number}
* @param stiffness {number}
* @returns {number}
*/
export const softSet = (value, target, stiffness) => {
return softClamp(value, target, target, stiffness);
}

export const vecArrToObj = (val, useZ = false) => {
if (val && val.length >= 2) {
if (useZ) return {x: val[0], z: val[1]};
Expand Down

0 comments on commit b32f808

Please sign in to comment.