From 17af987de0de726528033f24a5916418b82acb54 Mon Sep 17 00:00:00 2001 From: Monica Kozbial Date: Fri, 25 Oct 2019 16:45:55 -0700 Subject: [PATCH] Adding pinch zoom config option. (#3317) * Adding pinch zoom config option. --- core/options.js | 5 ++++ core/touch_gesture.js | 67 +++++++++++++++++++++++++++---------------- core/workspace_svg.js | 16 ++++------- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/core/options.js b/core/options.js index 68884d608..6c054dd27 100644 --- a/core/options.js +++ b/core/options.js @@ -247,6 +247,11 @@ Blockly.Options.parseZoomOptions_ = function(options) { } else { zoomOptions.scaleSpeed = Number(zoom['scaleSpeed']); } + if (zoom['pinch'] === undefined) { + zoomOptions.pinch = zoomOptions.wheel || zoomOptions.controls; + } else { + zoomOptions.pinch = !!zoom['pinch']; + } return zoomOptions; }; diff --git a/core/touch_gesture.js b/core/touch_gesture.js index 20c838957..00b15d979 100644 --- a/core/touch_gesture.js +++ b/core/touch_gesture.js @@ -85,6 +85,14 @@ Blockly.TouchGesture = function(e, creatorWorkspace) { * @private */ this.onStartWrapper_ = null; + + /** + * Boolean for whether or not the workspace supports pinch-zoom. + * @type {boolean} + * @private + */ + this.isPinchZoomEnabled_ = this.startWorkspace_.options.zoomOptions && + this.startWorkspace_.options.zoomOptions.pinch; }; Blockly.utils.object.inherits(Blockly.TouchGesture, Blockly.Gesture); @@ -233,7 +241,7 @@ Blockly.TouchGesture.prototype.handleTouchStart = function(e) { // store the pointerId in the current list of pointers this.cachedPoints_[pointerId] = this.getTouchPoint(e); var pointers = Object.keys(this.cachedPoints_); - // If two pointers are down, check for pinch gestures + // If two pointers are down, store info if (pointers.length == 2) { var point0 = /** @type {!Blockly.utils.Coordinate} */ ( this.cachedPoints_[pointers[0]]); @@ -257,32 +265,43 @@ Blockly.TouchGesture.prototype.handleTouchMove = function(e) { this.cachedPoints_[pointerId] = this.getTouchPoint(e); var pointers = Object.keys(this.cachedPoints_); - // If two pointers are down, check for pinch gestures - if (pointers.length == 2) { - // Calculate the distance between the two pointers - var point0 = /** @type {!Blockly.utils.Coordinate} */ ( - this.cachedPoints_[pointers[0]]); - var point1 = /** @type {!Blockly.utils.Coordinate} */ ( - this.cachedPoints_[pointers[1]]); - var moveDistance = Blockly.utils.Coordinate.distance(point0, point1); - var startDistance = this.startDistance_; - var scale = this.touchScale_ = moveDistance / startDistance; - - if (this.previousScale_ > 0 && this.previousScale_ < Infinity) { - var gestureScale = scale - this.previousScale_; - var delta = gestureScale > 0 ? - gestureScale * Blockly.TouchGesture.ZOOM_IN_MULTIPLIER : - gestureScale * Blockly.TouchGesture.ZOOM_OUT_MULTIPLIER; - var workspace = this.startWorkspace_; - var position = Blockly.utils.mouseToSvg( - e, workspace.getParentSvg(), workspace.getInverseScreenCTM()); - workspace.zoom(position.x, position.y, delta); - } - this.previousScale_ = scale; - e.preventDefault(); + if (this.isPinchZoomEnabled_ && pointers.length === 2) { + this.handlePinch_(e); + } else { + Blockly.TouchGesture.superClass_.handleMove.call(this, e); } }; +/** +* Handle pinch zoom gesture. +* @param {!Event} e A touch move, or pointer move event. +* @private +*/ +Blockly.TouchGesture.prototype.handlePinch_ = function(e) { + var pointers = Object.keys(this.cachedPoints_); + // Calculate the distance between the two pointers + var point0 = /** @type {!Blockly.utils.Coordinate} */ ( + this.cachedPoints_[pointers[0]]); + var point1 = /** @type {!Blockly.utils.Coordinate} */ ( + this.cachedPoints_[pointers[1]]); + var moveDistance = Blockly.utils.Coordinate.distance(point0, point1); + var scale = moveDistance / this.startDistance_; + + if (this.previousScale_ > 0 && this.previousScale_ < Infinity) { + var gestureScale = scale - this.previousScale_; + var delta = gestureScale > 0 ? + gestureScale * Blockly.TouchGesture.ZOOM_IN_MULTIPLIER : + gestureScale * Blockly.TouchGesture.ZOOM_OUT_MULTIPLIER; + var workspace = this.startWorkspace_; + var position = Blockly.utils.mouseToSvg( + e, workspace.getParentSvg(), workspace.getInverseScreenCTM()); + workspace.zoom(position.x, position.y, delta); + } + this.previousScale_ = this.touchScale_; + e.preventDefault(); +}; + + /** * Handle a touch end or pointer end event and end the gesture. * @param {!Event} e A touch end, or pointer end event. diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 8c676431a..a79cc05bf 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1452,7 +1452,8 @@ Blockly.WorkspaceSvg.prototype.isContentBounded = function() { (this.options.moveOptions && this.options.moveOptions.wheel) || (this.options.moveOptions && this.options.moveOptions.drag) || (this.options.zoomOptions && this.options.zoomOptions.controls) || - (this.options.zoomOptions && this.options.zoomOptions.wheel); + (this.options.zoomOptions && this.options.zoomOptions.wheel) || + (this.options.zoomOptions && this.options.zoomOptions.pinch); }; /** @@ -1460,8 +1461,8 @@ Blockly.WorkspaceSvg.prototype.isContentBounded = function() { * * This means the user can reposition the X Y coordinates of the workspace * through input. This can be through scrollbars, scroll wheel, dragging, or - * through zooming with the scroll wheel (since the zoom is centered on the - * mouse position). This does not include zooming with the zoom controls + * through zooming with the scroll wheel or pinch (since the zoom is centered on + * the mouse position). This does not include zooming with the zoom controls * since the X Y coordinates are decided programmatically. * @return {boolean} True if the workspace is movable, false otherwise. * @package @@ -1470,7 +1471,8 @@ Blockly.WorkspaceSvg.prototype.isMovable = function() { return (this.options.moveOptions && this.options.moveOptions.scrollbars) || (this.options.moveOptions && this.options.moveOptions.wheel) || (this.options.moveOptions && this.options.moveOptions.drag) || - (this.options.zoomOptions && this.options.zoomOptions.wheel); + (this.options.zoomOptions && this.options.zoomOptions.wheel) || + (this.options.zoomOptions && this.options.zoomOptions.pinch); }; /** @@ -1813,12 +1815,6 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() { * amount values zoom in. */ Blockly.WorkspaceSvg.prototype.zoom = function(x, y, amount) { - // TODO (#2782): Consider removing once pinch understands zoom configuration - // Mutators and flyouts don't support zooming, and pinch doesn't understand - // that. - if (this.isFlyout || this.isMutator) { - return; - } // Scale factor. var speed = this.options.zoomOptions.scaleSpeed; var scaleChange = Math.pow(speed, amount);