From 5ea34d410987d199130e6c9edfa11e83be258a4b Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 13 Nov 2023 10:59:54 -0500 Subject: [PATCH 1/7] Use midpoint of two touches, rather than viewport center, for zoom/rotate calculations. --- engine/esm/wwt_control.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 0b59e46c..3cb270a5 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -118,6 +118,7 @@ export function WWTControl() { this._zooming = false; this._rotating = false; this._dragThreshold = 4; + this._twoTouchCenter = null; this._foregroundCanvas = null; this._fgDevice = null; @@ -1142,6 +1143,9 @@ var WWTControl$ = { this._lastY = ev.targetTouches[0].pageY; if (ev.targetTouches.length === 2) { this._hasTwoTouches = true; + var t0 = ev.touches[0]; + var t1 = ev.touches[1]; + this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); return; } if (this.uiController != null) { @@ -1165,12 +1169,11 @@ var WWTControl$ = { newRect[0] = Vector2d.create(t0.pageX, t0.pageY); newRect[1] = Vector2d.create(t1.pageX, t1.pageY); - if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null) { - var centerPoint = Vector2d.create(this.renderContext.width / 2, this.renderContext.height / 2); + if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null && this._twoTouchCenter != null) { var delta1 = Vector2d.subtract(newRect[0], this._pinchingZoomRect[0]); var delta2 = Vector2d.subtract(newRect[1], this._pinchingZoomRect[1]); - var radialDirection1 = Vector2d.subtract(this._pinchingZoomRect[0], centerPoint); - var radialDirection2 = Vector2d.subtract(this._pinchingZoomRect[1], centerPoint); + var radialDirection1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); + var radialDirection2 = Vector2d.subtract(this._pinchingZoomRect[1], this._twoTouchCenter); radialDirection1.normalize(); radialDirection2.normalize(); var radialDot1 = delta1.x * radialDirection1.x + delta1.y * radialDirection1.y; @@ -1189,10 +1192,10 @@ var WWTControl$ = { this.zoom(ratio); this._zooming = true; } else if (!this._zooming) { - var oldCenterDelta1 = Vector2d.subtract(this._pinchingZoomRect[0], centerPoint); - var oldCenterDelta2 = Vector2d.subtract(this._pinchingZoomRect[1], centerPoint); - var newCenterDelta1 = Vector2d.subtract(newRect[0], centerPoint); - var newCenterDelta2 = Vector2d.subtract(newRect[1], centerPoint); + var oldCenterDelta1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); + var oldCenterDelta2 = Vector2d.subtract(this._pinchingZoomRect[1], this._twoTouchCenter); + var newCenterDelta1 = Vector2d.subtract(newRect[0], this._twoTouchCenter); + var newCenterDelta2 = Vector2d.subtract(newRect[1], this._twoTouchCenter); var cross1 = this.crossProductZ(oldCenterDelta1, newCenterDelta1); var cross2 = this.crossProductZ(oldCenterDelta2, newCenterDelta2); var angle1 = Math.asin(cross1 / (oldCenterDelta1.get_length() * newCenterDelta1.get_length())); @@ -1246,6 +1249,7 @@ var WWTControl$ = { if (this._hasTwoTouches) { if (ev.touches.length < 2) { this._hasTwoTouches = false; + this._twoTouchCenter = null; } return; } From fc8af29cde54f2a28feee47cac362900c37d5e8b Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 13 Nov 2023 15:31:14 -0500 Subject: [PATCH 2/7] Increase drag threshold. --- engine/esm/wwt_control.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 3cb270a5..3e59d458 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -117,7 +117,7 @@ export function WWTControl() { this._moved = false; this._zooming = false; this._rotating = false; - this._dragThreshold = 4; + this._dragThreshold = 8; this._twoTouchCenter = null; this._foregroundCanvas = null; From f0f2b31af68e66a438eb2daedb856fabd4129a28 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 27 Nov 2023 11:59:37 -0500 Subject: [PATCH 3/7] Recalculate touch center on each touch move event. Adjust zoom/rotate threshold. --- engine/esm/wwt_control.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 3e59d458..b6bead17 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -1170,6 +1170,7 @@ var WWTControl$ = { newRect[1] = Vector2d.create(t1.pageX, t1.pageY); if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null && this._twoTouchCenter != null) { + this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); var delta1 = Vector2d.subtract(newRect[0], this._pinchingZoomRect[0]); var delta2 = Vector2d.subtract(newRect[1], this._pinchingZoomRect[1]); var radialDirection1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); @@ -1185,7 +1186,7 @@ var WWTControl$ = { var radialMagnitude = radialComponent1.get_length() + radialComponent2.get_length(); var angularMagnitude = angularComponent1.get_length() + angularComponent2.get_length(); - if (radialMagnitude >= 0.5 * angularMagnitude && !this._rotating) { + if (radialMagnitude >= 0.75 * angularMagnitude && !this._rotating) { var oldDist = this.getDistance(this._pinchingZoomRect[0], this._pinchingZoomRect[1]); var newDist = this.getDistance(newRect[0], newRect[1]); var ratio = oldDist / newDist; From 973ebe08a66740687bcb4a4aeb9a8d0e8bb8b009 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Wed, 7 Feb 2024 16:24:02 -0500 Subject: [PATCH 4/7] Adjust rotation-eagerness and require positive magnitude. --- engine/esm/wwt_control.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index b6bead17..210ce509 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -1186,13 +1186,13 @@ var WWTControl$ = { var radialMagnitude = radialComponent1.get_length() + radialComponent2.get_length(); var angularMagnitude = angularComponent1.get_length() + angularComponent2.get_length(); - if (radialMagnitude >= 0.75 * angularMagnitude && !this._rotating) { + if (radialMagnitude > 1.25 * angularMagnitude && !this._rotating) { var oldDist = this.getDistance(this._pinchingZoomRect[0], this._pinchingZoomRect[1]); var newDist = this.getDistance(newRect[0], newRect[1]); var ratio = oldDist / newDist; this.zoom(ratio); this._zooming = true; - } else if (!this._zooming) { + } else if (!this._zooming && radialMagnitude > 0) { var oldCenterDelta1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); var oldCenterDelta2 = Vector2d.subtract(this._pinchingZoomRect[1], this._twoTouchCenter); var newCenterDelta1 = Vector2d.subtract(newRect[0], this._twoTouchCenter); From 588a16e5ca53e5a8b0dc9969ec67f967e2cfd4f2 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Wed, 7 Feb 2024 16:31:54 -0500 Subject: [PATCH 5/7] Wait a certain number of two-touch movement events before deciding what type of motion we're using. --- engine/esm/wwt_control.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 210ce509..0e8cb6e7 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -119,6 +119,8 @@ export function WWTControl() { this._rotating = false; this._dragThreshold = 8; this._twoTouchCenter = null; + this._twoTouchFrames = 0; + this._twoTouchFrameThreshold = 10; this._foregroundCanvas = null; this._fgDevice = null; @@ -1168,8 +1170,10 @@ var WWTControl$ = { var newRect = new Array(2); newRect[0] = Vector2d.create(t0.pageX, t0.pageY); newRect[1] = Vector2d.create(t1.pageX, t1.pageY); + this._twoTouchFrames += 1; - if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null && this._twoTouchCenter != null) { + if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null && + this._twoTouchCenter != null && this._twoTouchFrames > this._twoTouchFrameThreshold) { this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); var delta1 = Vector2d.subtract(newRect[0], this._pinchingZoomRect[0]); var delta2 = Vector2d.subtract(newRect[1], this._pinchingZoomRect[1]); @@ -1186,7 +1190,7 @@ var WWTControl$ = { var radialMagnitude = radialComponent1.get_length() + radialComponent2.get_length(); var angularMagnitude = angularComponent1.get_length() + angularComponent2.get_length(); - if (radialMagnitude > 1.25 * angularMagnitude && !this._rotating) { + if (radialMagnitude > angularMagnitude && !this._rotating) { var oldDist = this.getDistance(this._pinchingZoomRect[0], this._pinchingZoomRect[1]); var newDist = this.getDistance(newRect[0], newRect[1]); var ratio = oldDist / newDist; @@ -1251,6 +1255,7 @@ var WWTControl$ = { if (ev.touches.length < 2) { this._hasTwoTouches = false; this._twoTouchCenter = null; + this._twoTouchFrames = 0; } return; } From 642f09c008bdf1a3e2885fb842005aca5033bf03 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Wed, 7 Feb 2024 17:43:02 -0500 Subject: [PATCH 6/7] We need an extra rectangle to implement this idea properly. --- engine/esm/wwt_control.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 0e8cb6e7..2f1854d8 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -119,6 +119,7 @@ export function WWTControl() { this._rotating = false; this._dragThreshold = 8; this._twoTouchCenter = null; + this._lastTouchRect = new Array(2); this._twoTouchFrames = 0; this._twoTouchFrameThreshold = 10; @@ -1148,6 +1149,8 @@ var WWTControl$ = { var t0 = ev.touches[0]; var t1 = ev.touches[1]; this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); + this._lastTouchRect[0] = Vector2d.create(t0.pageX, t0.pageY); + this._lastTouchRect[1] = Vector2d.create(t1.pageX, t1.pageY); return; } if (this.uiController != null) { @@ -1172,13 +1175,13 @@ var WWTControl$ = { newRect[1] = Vector2d.create(t1.pageX, t1.pageY); this._twoTouchFrames += 1; - if (!this._dragging && this._pinchingZoomRect[0] != null && this._pinchingZoomRect[1] != null && + if (!this._dragging && this._lastTouchRect[0] != null && this._lastTouchRect[1] != null && this._twoTouchCenter != null && this._twoTouchFrames > this._twoTouchFrameThreshold) { - this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); - var delta1 = Vector2d.subtract(newRect[0], this._pinchingZoomRect[0]); - var delta2 = Vector2d.subtract(newRect[1], this._pinchingZoomRect[1]); - var radialDirection1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); - var radialDirection2 = Vector2d.subtract(this._pinchingZoomRect[1], this._twoTouchCenter); + + var delta1 = Vector2d.subtract(newRect[0], this._lastTouchRect[0]); + var delta2 = Vector2d.subtract(newRect[1], this._lastTouchRect[1]); + var radialDirection1 = Vector2d.subtract(this._lastTouchRect[0], this._twoTouchCenter); + var radialDirection2 = Vector2d.subtract(this._lastTouchRect[1], this._twoTouchCenter); radialDirection1.normalize(); radialDirection2.normalize(); var radialDot1 = delta1.x * radialDirection1.x + delta1.y * radialDirection1.y; @@ -1191,14 +1194,14 @@ var WWTControl$ = { var angularMagnitude = angularComponent1.get_length() + angularComponent2.get_length(); if (radialMagnitude > angularMagnitude && !this._rotating) { - var oldDist = this.getDistance(this._pinchingZoomRect[0], this._pinchingZoomRect[1]); + var oldDist = this.getDistance(this._lastTouchRect[0], this._lastTouchRect[1]); var newDist = this.getDistance(newRect[0], newRect[1]); var ratio = oldDist / newDist; this.zoom(ratio); this._zooming = true; } else if (!this._zooming && radialMagnitude > 0) { - var oldCenterDelta1 = Vector2d.subtract(this._pinchingZoomRect[0], this._twoTouchCenter); - var oldCenterDelta2 = Vector2d.subtract(this._pinchingZoomRect[1], this._twoTouchCenter); + var oldCenterDelta1 = Vector2d.subtract(this._lastTouchRect[0], this._twoTouchCenter); + var oldCenterDelta2 = Vector2d.subtract(this._lastTouchRect[1], this._twoTouchCenter); var newCenterDelta1 = Vector2d.subtract(newRect[0], this._twoTouchCenter); var newCenterDelta2 = Vector2d.subtract(newRect[1], this._twoTouchCenter); var cross1 = this.crossProductZ(oldCenterDelta1, newCenterDelta1); @@ -1215,6 +1218,9 @@ var WWTControl$ = { this._rotating = true; } } + this._twoTouchCenter = Vector2d.create(0.5 * (t0.pageX + t1.pageX), 0.5 * (t0.pageY + t1.pageY)); + this._lastTouchRect[0] = newRect[0]; + this._lastTouchRect[1] = newRect[1]; } this._pinchingZoomRect = newRect; @@ -1254,6 +1260,8 @@ var WWTControl$ = { if (this._hasTwoTouches) { if (ev.touches.length < 2) { this._hasTwoTouches = false; + this._lastTouchRect[0] = null; + this._lastTouchRect[1] = null; this._twoTouchCenter = null; this._twoTouchFrames = 0; } From 2e607717835a50bd28f457bdcd63c693861ecbd5 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Wed, 7 Feb 2024 17:48:39 -0500 Subject: [PATCH 7/7] Variable renaming. --- engine/esm/wwt_control.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/esm/wwt_control.js b/engine/esm/wwt_control.js index 2f1854d8..7fdd2234 100644 --- a/engine/esm/wwt_control.js +++ b/engine/esm/wwt_control.js @@ -120,8 +120,8 @@ export function WWTControl() { this._dragThreshold = 8; this._twoTouchCenter = null; this._lastTouchRect = new Array(2); - this._twoTouchFrames = 0; - this._twoTouchFrameThreshold = 10; + this._twoTouchEvents = 0; + this._twoTouchEventThreshold = 10; this._foregroundCanvas = null; this._fgDevice = null; @@ -1173,10 +1173,10 @@ var WWTControl$ = { var newRect = new Array(2); newRect[0] = Vector2d.create(t0.pageX, t0.pageY); newRect[1] = Vector2d.create(t1.pageX, t1.pageY); - this._twoTouchFrames += 1; + this._twoTouchEvents += 1; if (!this._dragging && this._lastTouchRect[0] != null && this._lastTouchRect[1] != null && - this._twoTouchCenter != null && this._twoTouchFrames > this._twoTouchFrameThreshold) { + this._twoTouchCenter != null && this._twoTouchEvents > this._twoTouchEventThreshold) { var delta1 = Vector2d.subtract(newRect[0], this._lastTouchRect[0]); var delta2 = Vector2d.subtract(newRect[1], this._lastTouchRect[1]); @@ -1263,7 +1263,7 @@ var WWTControl$ = { this._lastTouchRect[0] = null; this._lastTouchRect[1] = null; this._twoTouchCenter = null; - this._twoTouchFrames = 0; + this._twoTouchEvents = 0; } return; }