diff --git a/core/constants.js b/core/constants.js index 229ca0d4d..a786c173a 100644 --- a/core/constants.js +++ b/core/constants.js @@ -26,6 +26,17 @@ goog.provide('Blockly.constants'); +/** + * The multiplier for scroll wheel deltas using the line delta mode. + * @type {number} + */ +Blockly.LINE_MODE_MULTIPLIER = 40; + +/** + * The multiplier for scroll wheel deltas using the page delta mode. + * @type {number} + */ +Blockly.PAGE_MODE_MULTIPLIER = 125; /** * Number of pixels the mouse must move before a drag starts. diff --git a/core/flyout_horizontal.js b/core/flyout_horizontal.js index ac3c3dc1f..0dad7570c 100644 --- a/core/flyout_horizontal.js +++ b/core/flyout_horizontal.js @@ -217,14 +217,10 @@ Blockly.HorizontalFlyout.prototype.scrollToStart = function() { * @private */ Blockly.HorizontalFlyout.prototype.wheel_ = function(e) { - var delta = e.deltaX || e.deltaY; + var scrollDelta = Blockly.utils.getScrollDeltaPixels(e); + var delta = scrollDelta.x || scrollDelta.y; if (delta) { - // Firefox's mouse wheel deltas are a tenth that of Chrome/Safari. - // DeltaMode is 1 for a mouse wheel, but not for a trackpad scroll event - if (goog.userAgent.GECKO && (e.deltaMode === 1)) { - delta *= 10; - } var metrics = this.getMetrics_(); var pos = metrics.viewLeft + delta; var limit = metrics.contentWidth - metrics.viewWidth; diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js index 65886f384..3fc36962c 100644 --- a/core/flyout_vertical.js +++ b/core/flyout_vertical.js @@ -207,16 +207,11 @@ Blockly.VerticalFlyout.prototype.scrollToStart = function() { * @private */ Blockly.VerticalFlyout.prototype.wheel_ = function(e) { - var delta = e.deltaY; + var scrollDelta = Blockly.utils.getScrollDeltaPixels(e); - if (delta) { - // Firefox's mouse wheel deltas are a tenth that of Chrome/Safari. - // DeltaMode is 1 for a mouse wheel, but not for a trackpad scroll event - if (goog.userAgent.GECKO && (e.deltaMode === 1)) { - delta *= 10; - } + if (scrollDelta.y) { var metrics = this.getMetrics_(); - var pos = (metrics.viewTop - metrics.contentTop) + delta; + var pos = (metrics.viewTop - metrics.contentTop) + scrollDelta.y; var limit = metrics.contentHeight - metrics.viewHeight; pos = Math.min(pos, limit); pos = Math.max(pos, 0); diff --git a/core/utils.js b/core/utils.js index 2ec39feee..2d4db0154 100644 --- a/core/utils.js +++ b/core/utils.js @@ -304,6 +304,32 @@ Blockly.utils.mouseToSvg = function(e, svg, matrix) { return svgPoint.matrixTransform(matrix); }; +/** + * Get the scroll delta of a mouse event in pixel units. + * @param {!Event} e Mouse event. + * @return {{x: number, y: number}} Scroll delta object with .x and .y + * properties. + */ +Blockly.utils.getScrollDeltaPixels = function(e) { + switch (e.deltaMode) { + case 0x00: // Pixel mode. + return { + x: e.deltaX, + y: e.deltaY + }; + case 0x01: // Line mode. + return { + x: e.deltaX * Blockly.LINE_MODE_MULTIPLIER, + y: e.deltaY * Blockly.LINE_MODE_MULTIPLIER + }; + case 0x02: // Page mode. + return { + x: e.deltaX * Blockly.PAGE_MODE_MULTIPLIER, + y: e.deltaY * Blockly.PAGE_MODE_MULTIPLIER + }; + } +}; + /** * Given an array of strings, return the length of the shortest one. * @param {!Array.} array Array of strings. diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 8a58c9bdc..1ec2c706f 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1316,27 +1316,24 @@ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { this.currentGesture_.cancel(); } - // TODO (#2301): Change '10' from magic number to constant variable. Also - // change in flyout_vertical.js and flyout_horizontal.js. - // Multiplier variable, so that non-pixel-deltaModes are supported. - var multiplier = e.deltaMode === 0x1 ? 10 : 1; + var scrollDelta = Blockly.utils.getScrollDeltaPixels(e); if (canWheelZoom && (e.ctrlKey || !canWheelMove)) { // The vertical scroll distance that corresponds to a click of a zoom button. var PIXELS_PER_ZOOM_STEP = 50; - var delta = -e.deltaY / PIXELS_PER_ZOOM_STEP * multiplier; + var delta = -scrollDelta.y / PIXELS_PER_ZOOM_STEP; var position = Blockly.utils.mouseToSvg(e, this.getParentSvg(), this.getInverseScreenCTM()); this.zoom(position.x, position.y, delta); } else { - var x = this.scrollX - e.deltaX * multiplier; - var y = this.scrollY - e.deltaY * multiplier; + var x = this.scrollX - scrollDelta.x; + var y = this.scrollY - scrollDelta.y; - if (e.shiftKey && e.deltaX === 0) { + if (e.shiftKey && !scrollDelta.x) { // Scroll horizontally (based on vertical scroll delta) // This is needed as for some browser/system combinations which do not // set deltaX. - x = this.scrollX - e.deltaY * multiplier; + x = this.scrollX - scrollDelta.y; y = this.scrollY; // Don't scroll vertically } this.scroll(x, y);