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 fdf9d37fbdc..66553e72364 100644
--- a/src/plots/gl2d/camera.js
+++ b/src/plots/gl2d/camera.js
@@ -256,40 +256,35 @@ 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];
 
-        switch(scene.fullLayout.dragmode) {
-            case 'zoom':
-                break;
+        var scale = Math.exp(5.0 * dy / (viewBox[3] - viewBox[1]));
 
-            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];
 
-                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;
 
-                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);
 
-                scene.setRanges(dataBox);
-
-                result.lastInputTime = Date.now();
-                unSetAutoRange();
-                scene.cameraChanged();
-                scene.handleAnnotations();
-                scene.relayoutCallback();
-                break;
-        }
+        result.lastInputTime = Date.now();
+        unSetAutoRange();
+        scene.cameraChanged();
+        scene.handleAnnotations();
+        scene.relayoutCallback();
 
         return true;
     });
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 29cdbec1eb5..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()) / 100.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);
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();
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);
     });
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]);
         });
     });