From 18d346f3b82e443a1781884a21805cebab728ca9 Mon Sep 17 00:00:00 2001 From: max bittker Date: Sat, 28 Dec 2019 12:42:47 -0600 Subject: [PATCH 1/5] one finger rotate --- regl-camera.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/regl-camera.js b/regl-camera.js index 9885074..d2a791d 100644 --- a/regl-camera.js +++ b/regl-camera.js @@ -75,6 +75,46 @@ function createCamera (regl, props_) { prevY = y }) + + source.addEventListener("touchstart", function(ev) { + if (event.cancelable) { + event.preventDefault(); + } + var touch = ev.touches[0]; + var bounds = source.getBoundingClientRect(); + var x = touch.clientX - bounds.left; + var y = touch.clientY - bounds.top; + prevX = x + prevY = y + }); + + source.addEventListener("touchend", function(event) { + if (event.cancelable) { + event.preventDefault(); + } + }); + + source.addEventListener("touchmove", function(ev) { + if (ev.cancelable) { + ev.preventDefault(); + } + + var touch = ev.touches[0]; + var bounds = source.getBoundingClientRect(); + var x = touch.clientX - bounds.left; + var y = touch.clientY - bounds.top; + + var dx = (x - prevX) / getWidth() + var dy = (y - prevY) / getHeight() + + cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx + cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy + cameraState.dirty = true; + + prevX = x + prevY = y + }); + mouseWheel(source, function (dx, dy) { ddistance += dy / getHeight() * cameraState.zoomSpeed cameraState.dirty = true; From f2e3f6432fc6fc01e404212f37e06850bece93f6 Mon Sep 17 00:00:00 2001 From: max bittker Date: Sat, 28 Dec 2019 12:55:23 -0600 Subject: [PATCH 2/5] 2 finger pinch zoom --- regl-camera.js | 58 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/regl-camera.js b/regl-camera.js index d2a791d..4d28c07 100644 --- a/regl-camera.js +++ b/regl-camera.js @@ -50,6 +50,7 @@ function createCamera (regl, props_) { var prevX = 0 var prevY = 0 + var prevDistance = null; if (isBrowser && props.mouse !== false) { var source = element || regl._gl.canvas @@ -75,7 +76,6 @@ function createCamera (regl, props_) { prevY = y }) - source.addEventListener("touchstart", function(ev) { if (event.cancelable) { event.preventDefault(); @@ -84,35 +84,51 @@ function createCamera (regl, props_) { var bounds = source.getBoundingClientRect(); var x = touch.clientX - bounds.left; var y = touch.clientY - bounds.top; - prevX = x - prevY = y + prevX = x; + prevY = y; }); - source.addEventListener("touchend", function(event) { - if (event.cancelable) { - event.preventDefault(); - } + source.addEventListener("touchend", function(ev) { + prevDistance = null; }); source.addEventListener("touchmove", function(ev) { if (ev.cancelable) { ev.preventDefault(); } + // One touch, treat as a rotate + if (ev.touches.length == 1) { + var touch = ev.touches[0]; + var bounds = source.getBoundingClientRect(); + var x = touch.clientX - bounds.left; + var y = touch.clientY - bounds.top; + + var dx = (x - prevX) / getWidth(); + var dy = (y - prevY) / getHeight(); + + cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx; + cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy; + cameraState.dirty = true; - var touch = ev.touches[0]; - var bounds = source.getBoundingClientRect(); - var x = touch.clientX - bounds.left; - var y = touch.clientY - bounds.top; - - var dx = (x - prevX) / getWidth() - var dy = (y - prevY) / getHeight() - - cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx - cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy - cameraState.dirty = true; - - prevX = x - prevY = y + prevX = x; + prevY = y; + // Two fingers, treat as a pinch zoom + } else if (ev.touches.length == 2) { + var touch1 = ev.touches[0]; + var touch2 = ev.touches[1]; + + var dx = touch1.clientX - touch2.clientX; + var dy = touch1.clientY - touch2.clientY; + var distance = Math.sqrt(dx * dx + dy * dy); + if (prevDistance != null) { + var distance_delta = prevDistance - distance; + ddistance += + (distance_delta / getHeight()) * cameraState.zoomSpeed * 2.0; + cameraState.dirty = true; + } + + prevDistance = distance; + } }); mouseWheel(source, function (dx, dy) { From f21042f7f8449bcf82eb57eb2d7ce0c2ad6c8745 Mon Sep 17 00:00:00 2001 From: max bittker Date: Sat, 28 Dec 2019 13:09:06 -0600 Subject: [PATCH 3/5] prevent jumpyness --- regl-camera.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/regl-camera.js b/regl-camera.js index 4d28c07..8b48661 100644 --- a/regl-camera.js +++ b/regl-camera.js @@ -90,6 +90,16 @@ function createCamera (regl, props_) { source.addEventListener("touchend", function(ev) { prevDistance = null; + + // reset prevX and prevY to prevent jumping + if (ev.touches.length == 1) { + var touch = ev.touches[0]; + var bounds = source.getBoundingClientRect(); + var x = touch.clientX - bounds.left; + var y = touch.clientY - bounds.top; + prevX = x; + prevY = y; + } }); source.addEventListener("touchmove", function(ev) { From 1d1fed9a7170a9a543e58252c661acd9347a2fb1 Mon Sep 17 00:00:00 2001 From: max bittker Date: Sat, 28 Dec 2019 13:15:03 -0600 Subject: [PATCH 4/5] lint fixes (including npm run lint-fix) --- regl-camera.js | 112 ++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/regl-camera.js b/regl-camera.js index 8b48661..66a0526 100644 --- a/regl-camera.js +++ b/regl-camera.js @@ -13,7 +13,7 @@ function createCamera (regl, props_) { // Preserve backward-compatibilty while renaming preventDefault -> noScroll if (typeof props.noScroll === 'undefined') { - props.noScroll = props.preventDefault; + props.noScroll = props.preventDefault } var cameraState = { @@ -50,7 +50,7 @@ function createCamera (regl, props_) { var prevX = 0 var prevY = 0 - var prevDistance = null; + var prevDistance = null if (isBrowser && props.mouse !== false) { var source = element || regl._gl.canvas @@ -70,80 +70,80 @@ function createCamera (regl, props_) { cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy - cameraState.dirty = true; + cameraState.dirty = true } prevX = x prevY = y }) - source.addEventListener("touchstart", function(ev) { - if (event.cancelable) { - event.preventDefault(); + source.addEventListener('touchstart', function (ev) { + if (ev.cancelable) { + ev.preventDefault() } - var touch = ev.touches[0]; - var bounds = source.getBoundingClientRect(); - var x = touch.clientX - bounds.left; - var y = touch.clientY - bounds.top; - prevX = x; - prevY = y; - }); + var touch = ev.touches[0] + var bounds = source.getBoundingClientRect() + var x = touch.clientX - bounds.left + var y = touch.clientY - bounds.top + prevX = x + prevY = y + }) - source.addEventListener("touchend", function(ev) { - prevDistance = null; + source.addEventListener('touchend', function (ev) { + prevDistance = null // reset prevX and prevY to prevent jumping - if (ev.touches.length == 1) { - var touch = ev.touches[0]; - var bounds = source.getBoundingClientRect(); - var x = touch.clientX - bounds.left; - var y = touch.clientY - bounds.top; - prevX = x; - prevY = y; + if (ev.touches.length === 1) { + var touch = ev.touches[0] + var bounds = source.getBoundingClientRect() + var x = touch.clientX - bounds.left + var y = touch.clientY - bounds.top + prevX = x + prevY = y } - }); + }) - source.addEventListener("touchmove", function(ev) { + source.addEventListener('touchmove', function (ev) { if (ev.cancelable) { - ev.preventDefault(); + ev.preventDefault() } // One touch, treat as a rotate - if (ev.touches.length == 1) { - var touch = ev.touches[0]; - var bounds = source.getBoundingClientRect(); - var x = touch.clientX - bounds.left; - var y = touch.clientY - bounds.top; + if (ev.touches.length === 1) { + var touch = ev.touches[0] + var bounds = source.getBoundingClientRect() + var x = touch.clientX - bounds.left + var y = touch.clientY - bounds.top - var dx = (x - prevX) / getWidth(); - var dy = (y - prevY) / getHeight(); + var dx = (x - prevX) / getWidth() + var dy = (y - prevY) / getHeight() - cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx; - cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy; - cameraState.dirty = true; + cameraState.dtheta += cameraState.rotationSpeed * 4.0 * dx + cameraState.dphi += cameraState.rotationSpeed * 4.0 * dy + cameraState.dirty = true - prevX = x; - prevY = y; + prevX = x + prevY = y // Two fingers, treat as a pinch zoom - } else if (ev.touches.length == 2) { - var touch1 = ev.touches[0]; - var touch2 = ev.touches[1]; + } else if (ev.touches.length === 2) { + var touch1 = ev.touches[0] + var touch2 = ev.touches[1] - var dx = touch1.clientX - touch2.clientX; - var dy = touch1.clientY - touch2.clientY; - var distance = Math.sqrt(dx * dx + dy * dy); + var pinchX = touch1.clientX - touch2.clientX + var pinchY = touch1.clientY - touch2.clientY + var distance = Math.sqrt(pinchX * pinchX + pinchY * pinchY) if (prevDistance != null) { - var distance_delta = prevDistance - distance; + var distanceDelta = prevDistance - distance ddistance += - (distance_delta / getHeight()) * cameraState.zoomSpeed * 2.0; - cameraState.dirty = true; + (distanceDelta / getHeight()) * cameraState.zoomSpeed * 2.0 + cameraState.dirty = true } - prevDistance = distance; + prevDistance = distance } - }); + }) mouseWheel(source, function (dx, dy) { ddistance += dy / getHeight() * cameraState.zoomSpeed - cameraState.dirty = true; + cameraState.dirty = true }, props.noScroll) } @@ -152,7 +152,7 @@ function createCamera (regl, props_) { if (Math.abs(xd) < 0.1) { return 0 } - cameraState.dirty = true; + cameraState.dirty = true return xd } @@ -200,12 +200,12 @@ function createCamera (regl, props_) { lookAt(cameraState.view, eye, center, up) } - cameraState.dirty = true; + cameraState.dirty = true var injectContext = regl({ context: Object.assign({}, cameraState, { dirty: function () { - return cameraState.dirty; + return cameraState.dirty }, projection: function (context) { perspective(cameraState.projection, @@ -226,14 +226,14 @@ function createCamera (regl, props_) { function setupCamera (props, block) { if (typeof setupCamera.dirty !== 'undefined') { cameraState.dirty = setupCamera.dirty || cameraState.dirty - setupCamera.dirty = undefined; + setupCamera.dirty = undefined } if (props && block) { - cameraState.dirty = true; + cameraState.dirty = true } - if (cameraState.renderOnDirty && !cameraState.dirty) return; + if (cameraState.renderOnDirty && !cameraState.dirty) return if (!block) { block = props @@ -242,7 +242,7 @@ function createCamera (regl, props_) { updateCamera(props) injectContext(block) - cameraState.dirty = false; + cameraState.dirty = false } Object.keys(cameraState).forEach(function (name) { From c874ad4e98daf013e1ec9ec2d74b615cfd4de96e Mon Sep 17 00:00:00 2001 From: max bittker Date: Sat, 28 Dec 2019 13:15:11 -0600 Subject: [PATCH 5/5] rebuild example --- docs/example.js | 4 ++-- docs/index.html | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/example.js b/docs/example.js index 7760fee..3fc35db 100644 --- a/docs/example.js +++ b/docs/example.js @@ -12,8 +12,8 @@ var bunny = require('bunny') var normals = require('angle-normals') window.addEventListener('resize', function () { - camera.dirty = true; -}); + camera.dirty = true +}) var drawBunny = regl({ frag: ` diff --git a/docs/index.html b/docs/index.html index 5698609..aaec0e4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -25,12 +25,11 @@