diff --git a/plugins/zoom-to-fit/src/index.js b/plugins/zoom-to-fit/src/index.js index 8bbf97b57e..3fe8649186 100644 --- a/plugins/zoom-to-fit/src/index.js +++ b/plugins/zoom-to-fit/src/index.js @@ -31,28 +31,28 @@ export class ZoomToFitControl { this.workspace_ = workspace; /** - * The SVG group containing the zoom controls. + * The SVG group containing the zoom-to-fit control. * @type {SVGElement} * @private */ this.svgGroup_ = null; /** - * Left coordinate of the zoom controls. + * Left coordinate of the zoom-to-fit control. * @type {number} * @private */ this.left_ = 0; /** - * Top coordinate of the zoom controls. + * Top coordinate of the zoom-to-fit control. * @type {number} * @private */ this.top_ = 0; /** - * Width of the zoom controls. + * Width of the zoom-to-fit control. * @type {number} * @const * @private @@ -60,7 +60,7 @@ export class ZoomToFitControl { this.WIDTH_ = 32; /** - * Height of the zoom controls. + * Height of the zoom-to-fit control. * @type {number} * @const * @private @@ -68,19 +68,20 @@ export class ZoomToFitControl { this.HEIGHT_ = 32; /** - * Distance between zoom controls and bottom edge of workspace. + * Distance between zoom-to-fit control and bottom or top edge of workspace. * @type {number} + * @const * @private */ - this.MARGIN_BOTTOM_ = 20; + this.MARGIN_VERTICAL_ = 20; /** - * Distance between zoom controls and right edge of workspace. + * Distance between zoom-to-fit control and right or left edge of workspace. * @type {number} * @const * @private */ - this.MARGIN_SIDE_ = 20; + this.MARGIN_HORIZONTAL_ = 20; /** * Whether this has been initialized. @@ -184,51 +185,47 @@ export class ZoomToFitControl { (this.workspace_.horizontalLayout && !this.workspace_.RTL)) { // Right corner placement. this.left_ = metrics.absoluteMetrics.left + metrics.viewMetrics.width - - this.WIDTH_ - this.MARGIN_SIDE_; + this.WIDTH_ - this.MARGIN_HORIZONTAL_; if (hasVerticalScrollbars && !this.workspace_.RTL) { this.left_ -= Blockly.Scrollbar.scrollbarThickness; } } else { // Left corner placement. - this.left_ = this.MARGIN_SIDE_; + this.left_ = this.MARGIN_HORIZONTAL_; if (hasVerticalScrollbars && this.workspace_.RTL) { this.left_ += Blockly.Scrollbar.scrollbarThickness; } } - // Upper corner placement - let minTop = metrics.absoluteMetrics.top + this.MARGIN_BOTTOM_; - if (hasHorizontalScrollbars) { - minTop += Blockly.Scrollbar.scrollbarThickness; - } - - // Bottom corner placement - const maxTop = metrics.absoluteMetrics.top + metrics.viewMetrics.height - - this.HEIGHT_ - this.MARGIN_BOTTOM_; - if (hasHorizontalScrollbars) { - minTop -= Blockly.Scrollbar.scrollbarThickness; - } - const bumpUp = + const startAtBottom = metrics.toolboxMetrics.position !== Blockly.TOOLBOX_AT_BOTTOM; - this.top_ = bumpUp ? maxTop : minTop; + if (startAtBottom) { + // Bottom corner placement + this.top_ = metrics.absoluteMetrics.top + metrics.viewMetrics.height - + this.HEIGHT_ - this.MARGIN_VERTICAL_; + if (hasHorizontalScrollbars) { + // The horizontal scrollbars are always positioned on the bottom. + this.top_ -= Blockly.Scrollbar.scrollbarThickness; + } + } else { + // Upper corner placement + this.top_ = metrics.absoluteMetrics.top + this.MARGIN_VERTICAL_; + } // Check for collision and bump if needed. let boundingRect = this.getBoundingRectangle(); for (let i = 0, otherEl; (otherEl = savedPositions[i]); i++) { if (boundingRect.intersects(otherEl)) { - if (bumpUp) { - // Bump up - this.top_ = otherEl.top - this.HEIGHT_ - this.MARGIN_BOTTOM_; - } else { - this.top_ = otherEl.bottom + this.MARGIN_BOTTOM_; + if (startAtBottom) { // Bump up. + this.top_ = otherEl.top - this.HEIGHT_ - this.MARGIN_VERTICAL_; + } else { // Bump down. + this.top_ = otherEl.bottom + this.MARGIN_VERTICAL_; } // Recheck other savedPositions boundingRect = this.getBoundingRectangle(); i = -1; } } - // Clamp top value within valid range. - this.top_ = Blockly.utils.math.clamp(minTop, this.top_, maxTop); this.svgGroup_.setAttribute('transform', 'translate(' + this.left_ + ',' + this.top_ + ')');