Replace the call to getBBox() in getMainWorkspaceMetrics

with a manual calculation. getBBox() can cause the browser to
re-layout the whole page and we have much of the information
(e.g. individual block height and width) we need already cached.

Note that getBoundingRectangle's calculation is slightly different
than the one returned by getBBox.  It is off by 3 in the y direction
due to how one of the curves is drawn. This new calculation is
technically more accurate.
This commit is contained in:
picklesrus 2016-02-29 12:52:38 -08:00
parent fee94ae405
commit a67f841671
3 changed files with 71 additions and 6 deletions

View file

@ -348,6 +348,35 @@ Blockly.BlockSvg.prototype.getHeightWidth = function() {
return {height: height, width: width};
};
/**
* Returns the coordinates of a bounding box describing the dimensions of this block
* and any blocks stacked below it.
* @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}}
* Object with top left and bottom right coordinates of the bounding box.
*/
Blockly.BlockSvg.prototype.getBoundingRectangle = function() {
var blockXY = this.getRelativeToSurfaceXY(this);
var tab = this.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
var blockBounds = this.getHeightWidth();
var topLeft;
var bottomRight;
if (this.RTL) {
// Width has the tab built into it already so subtract it here.
topLeft = new goog.math.Coordinate(blockXY.x - (blockBounds.width - tab), blockXY.y);
// Add the width of the tab/puzzle piece knob to the x coordinate
// since X is the corner of the rectangle, not the whole puzzle piece.
bottomRight = new goog.math.Coordinate(blockXY.x + tab, blockXY.y + blockBounds.height);
} else {
// Subtract the width of the tab/puzzle piece knob to the x coordinate
// since X is the corner of the rectangle, not the whole puzzle piece.
topLeft = new goog.math.Coordinate(blockXY.x - tab, blockXY.y);
// Width has the tab built into it already so subtract it here.
bottomRight = new goog.math.Coordinate(blockXY.x + blockBounds.width - tab,
blockXY.y + blockBounds.height);
}
return { topLeft : topLeft, bottomRight : bottomRight };
};
/**
* Set whether the block is collapsed or not.
* @param {boolean} collapsed True if collapsed.

View file

@ -521,12 +521,8 @@ Blockly.getMainWorkspaceMetrics_ = function() {
var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1;
var viewWidth = svgSize.width - MARGIN;
var viewHeight = svgSize.height - MARGIN;
try {
var blockBox = this.getCanvas().getBBox();
} catch (e) {
// Firefox has trouble with hidden elements (Bug 528969).
return null;
}
var blockBox = this.getBlocksBoundingBox();
// Fix scale.
var contentWidth = blockBox.width * this.scale;
var contentHeight = blockBox.height * this.scale;

View file

@ -660,6 +660,46 @@ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) {
e.preventDefault();
};
/**
* Calculate the bounding box for the blocks on the workspace.
*
* @return {Object} Contains the position and size of the bounding box
* containing the blocks on the workspace.
*/
Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox = function() {
var topBlocks = this.getTopBlocks();
// There are no blocks, return empty rectangle.
if (topBlocks.length <= 0) {
return {x: 0, y: 0, width: 0, height: 0};
}
// Initialize boundary using the first block.
var boundary = topBlocks[0].getBoundingRectangle();
// Start at 1 since the 0th block was used for initialization
for (var i = 1; i < topBlocks.length; i++) {
var blockBoundary = topBlocks[i].getBoundingRectangle();
if (blockBoundary.topLeft.x < boundary.topLeft.x) {
boundary.topLeft.x = blockBoundary.topLeft.x;
}
if (blockBoundary.bottomRight.x > boundary.bottomRight.x) {
boundary.bottomRight.x = blockBoundary.bottomRight.x
}
if (blockBoundary.topLeft.y < boundary.topLeft.y) {
boundary.topLeft.y = blockBoundary.topLeft.y;
}
if (blockBoundary.bottomRight.y > boundary.bottomRight.y) {
boundary.bottomRight.y = blockBoundary.bottomRight.y;
}
}
return {
x: boundary.topLeft.x,
y: boundary.topLeft.y,
width: boundary.bottomRight.x - boundary.topLeft.x,
height: boundary.bottomRight.y - boundary.topLeft.y
};
};
/**
* Clean up the workspace by ordering all the blocks in a column.
* @private