From c4cad3c6e4d4e3fac0e68a7c49e5f820152794ed Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Fri, 17 Jun 2016 14:26:04 -0700 Subject: [PATCH] Cache screen CTM for performance improvement. --- core/scrollbar.js | 3 ++- core/utils.js | 5 ++--- core/workspace_svg.js | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/core/scrollbar.js b/core/scrollbar.js index ee080b0bc..6381b928f 100644 --- a/core/scrollbar.js +++ b/core/scrollbar.js @@ -606,7 +606,8 @@ Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) { e.stopPropagation(); return; } - var mouseXY = Blockly.mouseToSvg(e, this.workspace_.getParentSvg()); + var mouseXY = Blockly.mouseToSvg(e, this.workspace_.getParentSvg(), + this.workspace_.getInverseScreenCTM()); var mouseLocation = this.horizontal_ ? mouseXY.x : mouseXY.y; var handleXY = Blockly.getSvgXY_(this.svgHandle_, this.workspace_); diff --git a/core/utils.js b/core/utils.js index 9b9e04d60..19ccc4cc8 100644 --- a/core/utils.js +++ b/core/utils.js @@ -308,14 +308,13 @@ Blockly.isRightButton = function(e) { * The origin (0,0) is the top-left corner of the Blockly svg. * @param {!Event} e Mouse event. * @param {!Element} svg SVG element. + * @param {SVGMatrix} matrix Inverted screen CTM to use. * @return {!Object} Object with .x and .y properties. */ -Blockly.mouseToSvg = function(e, svg) { +Blockly.mouseToSvg = function(e, svg, matrix) { var svgPoint = svg.createSVGPoint(); svgPoint.x = e.clientX; svgPoint.y = e.clientY; - var matrix = svg.getScreenCTM(); - matrix = matrix.inverse(); return svgPoint.matrixTransform(matrix); }; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index de636a7a2..4816349d2 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -144,6 +144,28 @@ Blockly.WorkspaceSvg.prototype.scrollbar = null; */ Blockly.WorkspaceSvg.prototype.lastSound_ = null; +/** + * Inverted screen CTM, for use in mouseToSvg. + * @type {SVGMatrix} + * @private + */ +Blockly.WorkspaceSvg.prototype.inverseScreenCTM_ = null; + +/** + * Getter for the inverted screen CTM. + * @return {SVGMatrix} The matrix to use in mouseToSvg + */ +Blockly.WorkspaceSvg.prototype.getInverseScreenCTM = function() { + return this.inverseScreenCTM_; +}; + +/** + * Update the inverted screen CTM. + */ +Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM = function() { + this.inverseScreenCTM_ = this.getParentSvg().getScreenCTM().inverse(); +}; + /** * Save resize handler data so we can delete it later in dispose. * @param {!Array.} handler Data that can be passed to unbindEvent_. @@ -330,6 +352,7 @@ Blockly.WorkspaceSvg.prototype.resizeContents = function() { // based on contents. this.scrollbar.resize(); } + this.updateInverseScreenCTM(); }; /** @@ -355,6 +378,7 @@ Blockly.WorkspaceSvg.prototype.resize = function() { if (this.scrollbar) { this.scrollbar.resize(); } + this.updateInverseScreenCTM(); }; /** @@ -661,7 +685,8 @@ Blockly.WorkspaceSvg.prototype.onMouseDown_ = function(e) { */ Blockly.WorkspaceSvg.prototype.startDrag = function(e, xy) { // Record the starting offset between the bubble's location and the mouse. - var point = Blockly.mouseToSvg(e, this.getParentSvg()); + var point = Blockly.mouseToSvg(e, this.getParentSvg(), + this.getInverseScreenCTM()); // Fix scale of mouse event. point.x /= this.scale; point.y /= this.scale; @@ -674,7 +699,8 @@ Blockly.WorkspaceSvg.prototype.startDrag = function(e, xy) { * @return {!goog.math.Coordinate} New location of object. */ Blockly.WorkspaceSvg.prototype.moveDrag = function(e) { - var point = Blockly.mouseToSvg(e, this.getParentSvg()); + var point = Blockly.mouseToSvg(e, this.getParentSvg(), + this.getInverseScreenCTM()); // Fix scale of mouse event. point.x /= this.scale; point.y /= this.scale; @@ -690,7 +716,8 @@ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { // TODO: Remove terminateDrag and compensate for coordinate skew during zoom. Blockly.terminateDrag_(); var delta = e.deltaY > 0 ? -1 : 1; - var position = Blockly.mouseToSvg(e, this.getParentSvg()); + var position = Blockly.mouseToSvg(e, this.getParentSvg(), + this.getInverseScreenCTM()); this.zoom(position.x, position.y, delta); e.preventDefault(); };