From 394014efa3918e23986959b83294bc0d35020496 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 27 Sep 2017 18:49:29 -0700 Subject: [PATCH 1/6] Normalize zoom speed and wheel behavior across trace types --- src/components/fx/layout_attributes.js | 11 ++++++ src/components/fx/layout_defaults.js | 1 + src/plots/cartesian/dragbox.js | 2 +- src/plots/gl2d/camera.js | 49 +++++++++++--------------- src/plots/gl3d/camera.js | 2 +- src/plots/gl3d/scene.js | 1 + src/plots/plots.js | 1 + 7 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/components/fx/layout_attributes.js b/src/components/fx/layout_attributes.js index 25c6503a0ce..542062ceb3f 100644 --- a/src/components/fx/layout_attributes.js +++ b/src/components/fx/layout_attributes.js @@ -31,6 +31,17 @@ module.exports = { '3D scenes.' ].join(' ') }, + zoomspeed: { + valType: 'number', + role: 'info', + dflt: 1, + min: 0, + editType: 'none', + description: [ + 'Sets the speed at which the mouse wheel zooms the plot. Larger', + 'values are faster.' + ].join(' ') + }, hovermode: { valType: 'enumerated', role: 'info', diff --git a/src/components/fx/layout_defaults.js b/src/components/fx/layout_defaults.js index a4800d094f0..79590cbaa82 100644 --- a/src/components/fx/layout_defaults.js +++ b/src/components/fx/layout_defaults.js @@ -17,6 +17,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { } coerce('dragmode'); + coerce('zoomspeed'); var hovermodeDflt; if(layoutOut._has('cartesian')) { diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index caacaaa43dc..93d82ea85de 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -380,7 +380,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) { return; } - var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 100), + var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 100 * fullLayout.zoomspeed), gbb = mainplot.draglayer.select('.nsewdrag') .node().getBoundingClientRect(), xfrac = (e.clientX - gbb.left) / gbb.width, diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js index fdf9d37fbdc..cf38f5543c5 100644 --- a/src/plots/gl2d/camera.js +++ b/src/plots/gl2d/camera.js @@ -262,34 +262,27 @@ function createCamera(scene) { var lastX = result.lastPos[0], lastY = result.lastPos[1]; - switch(scene.fullLayout.dragmode) { - case 'zoom': - break; - - case 'pan': - var scale = Math.exp(0.1 * dy / (viewBox[3] - viewBox[1])); - - var cx = lastX / - (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + - dataBox[0]; - var cy = lastY / - (viewBox[3] - viewBox[1]) * (dataBox[3] - dataBox[1]) + - dataBox[1]; - - dataBox[0] = (dataBox[0] - cx) * scale + cx; - dataBox[2] = (dataBox[2] - cx) * scale + cx; - dataBox[1] = (dataBox[1] - cy) * scale + cy; - dataBox[3] = (dataBox[3] - cy) * scale + cy; - - scene.setRanges(dataBox); - - result.lastInputTime = Date.now(); - unSetAutoRange(); - scene.cameraChanged(); - scene.handleAnnotations(); - scene.relayoutCallback(); - break; - } + var scale = Math.exp(scene.fullLayout.zoomspeed * 10.0 * dy / (viewBox[3] - viewBox[1])); + + var cx = lastX / + (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + + dataBox[0]; + var cy = lastY / + (viewBox[3] - viewBox[1]) * (dataBox[3] - dataBox[1]) + + dataBox[1]; + + dataBox[0] = (dataBox[0] - cx) * scale + cx; + dataBox[2] = (dataBox[2] - cx) * scale + cx; + dataBox[1] = (dataBox[1] - cy) * scale + cy; + dataBox[3] = (dataBox[3] - cy) * scale + cy; + + scene.setRanges(dataBox); + + result.lastInputTime = Date.now(); + unSetAutoRange(); + scene.cameraChanged(); + scene.handleAnnotations(); + scene.relayoutCallback(); return true; }); diff --git a/src/plots/gl3d/camera.js b/src/plots/gl3d/camera.js index 29cdbec1eb5..f3c02b6e532 100644 --- a/src/plots/gl3d/camera.js +++ b/src/plots/gl3d/camera.js @@ -256,7 +256,7 @@ function createCamera(element, options) { if(Math.abs(dx) > Math.abs(dy)) { view.rotate(t, 0, 0, -dx * flipX * Math.PI * camera.rotateSpeed / window.innerWidth); } else { - var kzoom = -camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 100.0; + var kzoom = -camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 10.0; view.pan(t, 0, 0, distance * (Math.exp(kzoom) - 1)); } }, true); diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 071310a78ec..cbfb780250c 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -205,6 +205,7 @@ function initializeGLPlot(scene, fullLayout, canvas, gl) { center: [cameraData.center.x, cameraData.center.y, cameraData.center.z], eye: [cameraData.eye.x, cameraData.eye.y, cameraData.eye.z], up: [cameraData.up.x, cameraData.up.y, cameraData.up.z], + zoomSpeed: fullLayout.zoomspeed, zoomMin: 0.1, zoomMax: 100, mode: 'orbit' diff --git a/src/plots/plots.js b/src/plots/plots.js index 64bc8952617..f46160a21bb 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1332,6 +1332,7 @@ plots.purge = function(gd) { delete gd._transitionData; delete gd._transitioning; delete gd._initialAutoSize; + delete gd._transitioningWithDuration; // remove all event listeners if(gd.removeAllListeners) gd.removeAllListeners(); From e489a7271a0ceef314b1aa0fc6a4fd6416fc1f4f Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 27 Sep 2017 20:38:20 -0700 Subject: [PATCH 2/6] Remove zoomspeed parameter --- src/components/fx/layout_attributes.js | 11 ----------- src/components/fx/layout_defaults.js | 1 - src/plots/cartesian/dragbox.js | 2 +- src/plots/gl2d/camera.js | 2 +- src/plots/gl3d/scene.js | 1 - 5 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/components/fx/layout_attributes.js b/src/components/fx/layout_attributes.js index 542062ceb3f..25c6503a0ce 100644 --- a/src/components/fx/layout_attributes.js +++ b/src/components/fx/layout_attributes.js @@ -31,17 +31,6 @@ module.exports = { '3D scenes.' ].join(' ') }, - zoomspeed: { - valType: 'number', - role: 'info', - dflt: 1, - min: 0, - editType: 'none', - description: [ - 'Sets the speed at which the mouse wheel zooms the plot. Larger', - 'values are faster.' - ].join(' ') - }, hovermode: { valType: 'enumerated', role: 'info', diff --git a/src/components/fx/layout_defaults.js b/src/components/fx/layout_defaults.js index 79590cbaa82..a4800d094f0 100644 --- a/src/components/fx/layout_defaults.js +++ b/src/components/fx/layout_defaults.js @@ -17,7 +17,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { } coerce('dragmode'); - coerce('zoomspeed'); var hovermodeDflt; if(layoutOut._has('cartesian')) { diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index 93d82ea85de..caacaaa43dc 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -380,7 +380,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) { return; } - var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 100 * fullLayout.zoomspeed), + var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 100), gbb = mainplot.draglayer.select('.nsewdrag') .node().getBoundingClientRect(), xfrac = (e.clientX - gbb.left) / gbb.width, diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js index cf38f5543c5..7b35a0f9ccb 100644 --- a/src/plots/gl2d/camera.js +++ b/src/plots/gl2d/camera.js @@ -262,7 +262,7 @@ function createCamera(scene) { var lastX = result.lastPos[0], lastY = result.lastPos[1]; - var scale = Math.exp(scene.fullLayout.zoomspeed * 10.0 * dy / (viewBox[3] - viewBox[1])); + var scale = Math.exp(10.0 * dy / (viewBox[3] - viewBox[1])); var cx = lastX / (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index cbfb780250c..071310a78ec 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -205,7 +205,6 @@ function initializeGLPlot(scene, fullLayout, canvas, gl) { center: [cameraData.center.x, cameraData.center.y, cameraData.center.z], eye: [cameraData.eye.x, cameraData.eye.y, cameraData.eye.z], up: [cameraData.up.x, cameraData.up.y, cameraData.up.z], - zoomSpeed: fullLayout.zoomspeed, zoomMin: 0.1, zoomMax: 100, mode: 'orbit' From 99101fe736b75e581742c96a79a1e6b32ed9a455 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 28 Sep 2017 07:01:31 -0700 Subject: [PATCH 3/6] 1/2 zoom speed for all and disableable zoom in scattergl --- src/plots/cartesian/dragbox.js | 2 +- src/plots/gl2d/camera.js | 4 +++- src/plots/gl2d/scene2d.js | 1 + src/plots/gl3d/camera.js | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index caacaaa43dc..4bf2881191e 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -380,7 +380,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) { return; } - var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 100), + var zoom = Math.exp(-Math.min(Math.max(wheelDelta, -20), 20) / 200), gbb = mainplot.draglayer.select('.nsewdrag') .node().getBoundingClientRect(), xfrac = (e.clientX - gbb.left) / gbb.width, diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js index 7b35a0f9ccb..368d2a84801 100644 --- a/src/plots/gl2d/camera.js +++ b/src/plots/gl2d/camera.js @@ -256,13 +256,15 @@ function createCamera(scene) { } result.wheelListener = mouseWheel(element, function(dx, dy) { + if (!scene.scrollZoom) return false; + var dataBox = scene.calcDataBox(), viewBox = plot.viewBox; var lastX = result.lastPos[0], lastY = result.lastPos[1]; - var scale = Math.exp(10.0 * dy / (viewBox[3] - viewBox[1])); + var scale = Math.exp(5.0 * dy / (viewBox[3] - viewBox[1])); var cx = lastX / (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index 57b9e6f9bbf..e0db40f622a 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -36,6 +36,7 @@ function Scene2D(options, fullLayout) { this.pixelRatio = options.plotGlPixelRatio || window.devicePixelRatio; this.id = options.id; this.staticPlot = !!options.staticPlot; + this.scrollZoom = this.graphDiv._context.scrollZoom; this.fullData = null; this.updateRefs(fullLayout); diff --git a/src/plots/gl3d/camera.js b/src/plots/gl3d/camera.js index f3c02b6e532..b1f9a8372b9 100644 --- a/src/plots/gl3d/camera.js +++ b/src/plots/gl3d/camera.js @@ -256,7 +256,7 @@ function createCamera(element, options) { if(Math.abs(dx) > Math.abs(dy)) { view.rotate(t, 0, 0, -dx * flipX * Math.PI * camera.rotateSpeed / window.innerWidth); } else { - var kzoom = -camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 10.0; + var kzoom = -camera.zoomSpeed * flipY * dy / window.innerHeight * (t - view.lastT()) / 20.0; view.pan(t, 0, 0, distance * (Math.exp(kzoom) - 1)); } }, true); From e231233560480287367c159c51327e0075ea3f83 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 28 Sep 2017 07:02:20 -0700 Subject: [PATCH 4/6] Lint it --- src/plots/gl2d/camera.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js index 368d2a84801..66553e72364 100644 --- a/src/plots/gl2d/camera.js +++ b/src/plots/gl2d/camera.js @@ -256,7 +256,7 @@ function createCamera(scene) { } result.wheelListener = mouseWheel(element, function(dx, dy) { - if (!scene.scrollZoom) return false; + if(!scene.scrollZoom) return false; var dataBox = scene.calcDataBox(), viewBox = plot.viewBox; From 8ddb965ba6415d38cdd70ee23a039e08654358b0 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 28 Sep 2017 13:17:45 -0700 Subject: [PATCH 5/6] Modify zoom test values to match new wheel rate --- test/jasmine/tests/cartesian_interact_test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/jasmine/tests/cartesian_interact_test.js b/test/jasmine/tests/cartesian_interact_test.js index 019cbeb519b..6581ac6d785 100644 --- a/test/jasmine/tests/cartesian_interact_test.js +++ b/test/jasmine/tests/cartesian_interact_test.js @@ -367,21 +367,21 @@ describe('axis zoom/pan and main plot zoom', function() { mouseEvent('scroll', mainDragCoords.x, mainDragCoords.y, {deltaY: 20, element: mainDrag}); }) .then(delay(constants.REDRAWDELAY + 10)) - .then(checkRanges({xaxis: [-0.4428, 2], yaxis: [0, 2.4428]}, 'xy main scroll')) + .then(checkRanges({xaxis: [-0.2103, 2], yaxis: [0, 2.2103]}, 'xy main scroll')) .then(function() { var ewDrag = getDragger('xy', 'ew'); var ewDragCoords = getNodeCoords(ewDrag); mouseEvent('scroll', ewDragCoords.x - 50, ewDragCoords.y, {deltaY: -20, element: ewDrag}); }) .then(delay(constants.REDRAWDELAY + 10)) - .then(checkRanges({xaxis: [-0.3321, 1.6679], yaxis: [0, 2.4428]}, 'x scroll')) + .then(checkRanges({xaxis: [-0.1578, 1.8422], yaxis: [0, 2.2103]}, 'x scroll')) .then(function() { var nsDrag = getDragger('xy', 'ns'); var nsDragCoords = getNodeCoords(nsDrag); mouseEvent('scroll', nsDragCoords.x, nsDragCoords.y - 50, {deltaY: -20, element: nsDrag}); }) .then(delay(constants.REDRAWDELAY + 10)) - .then(checkRanges({xaxis: [-0.3321, 1.6679], yaxis: [0.3321, 2.3321]}, 'y scroll')) + .then(checkRanges({xaxis: [-0.1578, 1.8422], yaxis: [0.1578, 2.1578]}, 'y scroll')) .catch(failTest) .then(done); }); @@ -420,7 +420,7 @@ describe('axis zoom/pan and main plot zoom', function() { mouseEvent('scroll', mainDragCoords.x, mainDragCoords.y, {deltaY: 20, element: mainDrag}); }) .then(delay(constants.REDRAWDELAY + 10)) - .then(checkRanges({xaxis: [-0.4428, 2], yaxis: [0, 2.4428], xaxis2: [-0.2214, 2.2214], yaxis2: [-0.2214, 2.2214]}, + .then(checkRanges({xaxis: [-0.2103, 2], yaxis: [0, 2.2103], xaxis2: [-0.1052, 2.1052], yaxis2: [-0.1052, 2.1052]}, 'scroll xy')) .then(function() { var ewDrag = getDragger('xy', 'ew'); @@ -428,7 +428,7 @@ describe('axis zoom/pan and main plot zoom', function() { mouseEvent('scroll', ewDragCoords.x - 50, ewDragCoords.y, {deltaY: -20, element: ewDrag}); }) .then(delay(constants.REDRAWDELAY + 10)) - .then(checkRanges({xaxis: [-0.3321, 1.6679], yaxis: [0.2214, 2.2214]}, 'scroll x')) + .then(checkRanges({xaxis: [-0.1578, 1.8422], yaxis: [0.1052, 2.1052]}, 'scroll x')) .catch(failTest) .then(done); }); From 4265a38f5cf934a5d29a401834526a809359acf9 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Thu, 28 Sep 2017 13:40:16 -0700 Subject: [PATCH 6/6] Fix zoom values in click test --- test/jasmine/tests/click_test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jasmine/tests/click_test.js b/test/jasmine/tests/click_test.js index 77125d01bc9..deb54b228f4 100644 --- a/test/jasmine/tests/click_test.js +++ b/test/jasmine/tests/click_test.js @@ -866,8 +866,8 @@ describe('Test click interactions:', function() { var translate = Drawing.getTranslate(mockEl), scale = Drawing.getScale(mockEl); - expect([translate.x, translate.y]).toBeCloseToArray([-25.941, 43.911]); - expect([scale.x, scale.y]).toBeCloseToArray([1.221, 1.221]); + expect([translate.x, translate.y]).toBeCloseToArray([13.93, 62.86]); + expect([scale.x, scale.y]).toBeCloseToArray([1.105, 1.105]); }); });