Skip to content

Commit b32f808

Browse files
committed
Make the camera zoom-in when tilting, instead of blocking the tilt. Closes: #279
1 parent 05a1cac commit b32f808

File tree

9 files changed

+50
-8
lines changed

9 files changed

+50
-8
lines changed

common/webapp/src/js/controls/map/MapControls.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export class MapControls {
9696
*/
9797
start(manager) {
9898
this.manager = manager;
99+
this.snapDistance = manager.distance;
99100

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

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

175-
// max angle for current distance
176-
let maxAngleForZoom = MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance);
177-
178176
// rotation
179177
this.mouseRotate.update(delta, map);
180178
this.keyRotate.update(delta, map);
@@ -193,12 +191,11 @@ export class MapControls {
193191
this.mouseAngle.update(delta, map);
194192
this.keyAngle.update(delta, map);
195193
this.touchAngle.update(delta, map);
196-
this.manager.angle = softClamp(this.manager.angle, 0, maxAngleForZoom, 0.8);
194+
this.manager.angle = softClamp(this.manager.angle, 0, HALF_PI, 0.8);
197195
}
198196

199197
// target height
200198
if (this.manager.ortho === 0 || this.manager.angle === 0) {
201-
this.mapHeight.maxAngle = maxAngleForZoom;
202199
this.mapHeight.update(delta, map);
203200
}
204201
}

common/webapp/src/js/controls/map/MapHeightControls.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525

2626
import {MathUtils, Vector2} from "three";
27+
import {MapControls} from "./MapControls";
2728

2829
export class MapHeightControls {
2930

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

3738
this.cameraHeightStiffness = cameraHeightStiffness;
3839
this.targetHeightStiffness = targetHeightStiffness;
39-
this.maxAngle = Math.PI / 2;
4040

4141
this.targetHeight = 0;
4242
this.cameraHeight = 0;
@@ -78,7 +78,8 @@ export class MapHeightControls {
7878

7979
// camera height
8080
this.minCameraHeight = 0;
81-
if (this.maxAngle >= 0.1) {
81+
let maxAngle = MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance);
82+
if (maxAngle >= 0.1) {
8283
let cameraSmoothing = this.cameraHeightStiffness / (16.666 / delta);
8384
cameraSmoothing = MathUtils.clamp(cameraSmoothing, 0, 1);
8485

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

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

common/webapp/src/js/controls/map/keyboard/KeyAngleControls.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
import {MathUtils} from "three";
2727
import {KeyCombination} from "../../KeyCombination";
28+
import {softMax} from "../../../util/Utils";
29+
import {MapControls} from "../MapControls";
2830

2931
export class KeyAngleControls {
3032

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

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

9497
this.deltaAngle *= 1 - smoothing;
9598
if (Math.abs(this.deltaAngle) < 0.0001) {

common/webapp/src/js/controls/map/keyboard/KeyZoomControls.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import {MathUtils} from "three";
2727
import {KeyCombination} from "../../KeyCombination";
28+
import {MapControls} from "../MapControls";
2829

2930
export class KeyZoomControls {
3031

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

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

9294
this.deltaZoom *= 1 - smoothing;
9395
if (Math.abs(this.deltaZoom) < 0.0001) {

common/webapp/src/js/controls/map/mouse/MouseAngleControls.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525

2626
import {MathUtils} from "three";
27+
import {MapControls} from "../MapControls";
28+
import {softMax, softSet} from "../../../util/Utils";
2729

2830
export class MouseAngleControls {
2931

@@ -40,6 +42,9 @@ export class MouseAngleControls {
4042
this.lastY = 0;
4143
this.deltaAngle = 0;
4244

45+
this.dynamicDistance = false;
46+
this.startDistance = 0;
47+
4348
this.speed = speed;
4449
this.stiffness = stiffness;
4550

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

6066
window.addEventListener("resize", this.updatePixelToSpeedMultiplier);
6167
}
@@ -64,6 +70,7 @@ export class MouseAngleControls {
6470
this.target.removeEventListener("mousedown", this.onMouseDown);
6571
window.removeEventListener("mousemove", this.onMouseMove);
6672
window.removeEventListener("mouseup", this.onMouseUp);
73+
window.removeEventListener("wheel", this.onWheel);
6774

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

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

90+
if (this.dynamicDistance) {
91+
this.manager.distance = softSet(this.manager.distance, Math.min(MapControls.getMaxDistanceForPerspectiveAngle(this.manager.angle), this.startDistance), 0.4);
92+
} else {
93+
this.manager.angle = softMax(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance), 0.8);
94+
}
95+
8396
this.deltaAngle *= 1 - smoothing;
8497
if (Math.abs(this.deltaAngle) < 0.0001) {
8598
this.deltaAngle = 0;
@@ -100,6 +113,9 @@ export class MouseAngleControls {
100113
this.moving = true;
101114
this.deltaAngle = 0;
102115
this.lastY = evt.y;
116+
117+
this.startDistance = this.manager.distance;
118+
this.dynamicDistance = this.manager.distance < 1000;
103119
}
104120
}
105121

@@ -123,6 +139,10 @@ export class MouseAngleControls {
123139
this.moving = false;
124140
}
125141

142+
onWheel = evt => {
143+
this.dynamicDistance = false;
144+
}
145+
126146
updatePixelToSpeedMultiplier = () => {
127147
this.pixelToSpeedMultiplierY = 1 / this.target.clientHeight;
128148
}

common/webapp/src/js/controls/map/mouse/MouseZoomControls.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525

2626
import {MathUtils} from "three";
27+
import {MapControls} from "../MapControls";
2728

2829
export class MouseZoomControls {
2930

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

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

7072
this.deltaZoom *= 1 - smoothing;
7173
if (Math.abs(this.deltaZoom) < 0.0001) {

common/webapp/src/js/controls/map/touch/TouchAngleControls.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525

2626
import {MathUtils} from "three";
27+
import {softMax} from "../../../util/Utils";
28+
import {MapControls} from "../MapControls";
2729

2830
export class TouchAngleControls {
2931

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

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

8790
this.deltaAngle *= 1 - smoothing;
8891
if (Math.abs(this.deltaAngle) < 0.0001) {

common/webapp/src/js/controls/map/touch/TouchZoomControls.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* THE SOFTWARE.
2424
*/
2525

26+
import {MapControls} from "../MapControls";
27+
2628
export class TouchZoomControls {
2729

2830
/**
@@ -87,6 +89,7 @@ export class TouchZoomControls {
8789
onTouchMove = evt => {
8890
if(this.moving){
8991
this.deltaZoom *= evt.scale / this.lastZoom;
92+
this.manager.angle = Math.min(this.manager.angle, MapControls.getMaxPerspectiveAngleForDistance(this.manager.distance));
9093
}
9194

9295
this.lastZoom = evt.scale;

common/webapp/src/js/util/Utils.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ export const softClamp = (value, min, max, stiffness) => {
377377
return softMax(softMin(value, min, stiffness), max, stiffness);
378378
}
379379

380+
/**
381+
* Softly sets a value
382+
* @param value {number}
383+
* @param target {number}
384+
* @param stiffness {number}
385+
* @returns {number}
386+
*/
387+
export const softSet = (value, target, stiffness) => {
388+
return softClamp(value, target, target, stiffness);
389+
}
390+
380391
export const vecArrToObj = (val, useZ = false) => {
381392
if (val && val.length >= 2) {
382393
if (useZ) return {x: val[0], z: val[1]};

0 commit comments

Comments
 (0)