Scale the flyout as the workspace zooms.

This commit is contained in:
Neil Fraser 2015-09-01 20:00:13 +01:00
parent 8f73c6b042
commit 7568015c8c
3 changed files with 36 additions and 45 deletions

View file

@ -363,6 +363,7 @@ Blockly.Flyout.prototype.show = function(xmlList) {
}
this.buttons_.length = 0;
this.workspace_.scale = this.targetWorkspace_.scale;
var margin = this.CORNER_RADIUS;
this.svgGroup_.style.display = 'block';
@ -630,34 +631,20 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) {
throw 'originBlock is not rendered.';
}
var xyOld = Blockly.getSvgXY_(svgRootOld, workspace);
// Scale the scroll (getSvgXY_ did not do this).
xyOld.x += flyout.workspace_.scrollX / flyout.workspace_.scale -
flyout.workspace_.scrollX;
xyOld.y += flyout.workspace_.scrollY / flyout.workspace_.scale -
flyout.workspace_.scrollY;
var svgRootNew = block.getSvgRoot();
if (!svgRootNew) {
throw 'block is not rendered.';
}
if (workspace.scale == 1) {
// No scaling issues.
var xyNew = Blockly.getSvgXY_(svgRootNew, workspace);
block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y);
} else {
// Scale the block while keeping the mouse location constant.
var mouseXY = Blockly.mouseToSvg(e, workspace.options.svg);
// Relative mouse position to the block.
var rMouseX = mouseXY.x - xyOld.x;
var rMouseY = mouseXY.y - xyOld.y;
// Fix scale.
xyOld.x /= workspace.scale;
xyOld.y /= workspace.scale;
// Calculate the position to create the block, fixing scale.
var xyCanvastoSvg = Blockly.getRelativeXY_(workspace.getCanvas());
var xyNewtoCanvas = Blockly.getRelativeXY_(svgRootNew);
var newX = xyCanvastoSvg.x / workspace.scale + xyNewtoCanvas.x;
var newY = xyCanvastoSvg.y / workspace.scale + xyNewtoCanvas.y;
var placePositionX = xyOld.x - newX;
var placePositionY = xyOld.y - newY;
var dx = rMouseX - rMouseX / workspace.scale;
var dy = rMouseY - rMouseY / workspace.scale;
block.moveBy(placePositionX - dx, placePositionY - dy);
}
var xyNew = Blockly.getSvgXY_(svgRootNew, workspace);
// Scale the scroll (getSvgXY_ did not do this).
xyNew.x += workspace.scrollX / workspace.scale - workspace.scrollX;
xyNew.y += workspace.scrollY / workspace.scale - workspace.scrollY;
block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y);
if (flyout.autoClose) {
flyout.hide();
} else {

View file

@ -251,11 +251,11 @@ Blockly.isTargetInput_ = function(e) {
* Return the coordinates of the top-left corner of this element relative to
* its parent. Only for SVG elements and children (e.g. rect, g, path).
* @param {!Element} element SVG element to find the coordinates of.
* @return {!Object} Object with .x and .y properties.
* @return {!goog.math.Coordinate} Object with .x and .y properties.
* @private
*/
Blockly.getRelativeXY_ = function(element) {
var xy = {x: 0, y: 0};
var xy = new goog.math.Coordinate(0, 0);
// First, check for x and y attributes.
var x = element.getAttribute('x');
if (x) {
@ -301,24 +301,22 @@ Blockly.getRelativeXY_.XY_REGEXP_ =
Blockly.getSvgXY_ = function(element, workspace) {
var x = 0;
var y = 0;
// Evaluate if element isn't child of a canvas.
var inCanvas = goog.dom.contains(workspace.getCanvas(), element) ||
goog.dom.contains(workspace.getBubbleCanvas(), element);
var scale = 1;
if (goog.dom.contains(workspace.getCanvas(), element) ||
goog.dom.contains(workspace.getBubbleCanvas(), element)) {
// Before the SVG canvas, scale the coordinates.
scale = workspace.scale;
}
do {
// Loop through this block and every parent.
var xy = Blockly.getRelativeXY_(element);
if (element == workspace.getCanvas() ||
element == workspace.getBubbleCanvas()) {
inCanvas = false;
}
// Before the SVG canvas scale the coordinates.
if (inCanvas) {
x += xy.x * workspace.scale;
y += xy.y * workspace.scale;
} else {
x += xy.x;
y += xy.y;
// After the SVG canvas, don't scale the coordinates.
scale = 1;
}
x += xy.x * scale;
y += xy.y * scale;
element = element.parentNode;
} while (element && element != workspace.options.svg);
return new goog.math.Coordinate(x, y);

View file

@ -635,7 +635,6 @@ Blockly.WorkspaceSvg.prototype.moveDrag = function(e) {
* @private
*/
Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) {
Blockly.hideChaff(true);
// TODO: Remove terminateDrag and compensate for coordinate skew during zoom.
Blockly.terminateDrag_();
var delta = e.deltaY > 0 ? -1 : 1;
@ -881,12 +880,19 @@ Blockly.WorkspaceSvg.prototype.zoom = function(x, y, type) {
.translate(x * (1 - scaleChange), y * (1 - scaleChange))
.scale(scaleChange);
// newScale and matrix.a should be identical (within a rounding error).
if (this.scale != matrix.a) {
this.scale = matrix.a;
this.scrollX = matrix.e - metrics.absoluteLeft;
this.scrollY = matrix.f - metrics.absoluteTop;
this.updateGridPattern_();
this.scrollbar.resize();
if (this.scale == matrix.a) {
return; // No change in zoom.
}
this.scale = matrix.a;
this.scrollX = matrix.e - metrics.absoluteLeft;
this.scrollY = matrix.f - metrics.absoluteTop;
this.updateGridPattern_();
this.scrollbar.resize();
Blockly.hideChaff(false);
if (this.flyout_) {
// No toolbox, resize flyout.
this.flyout_.workspace_.scale = this.scale;
this.flyout_.reflow();
}
};