mirror of
https://github.com/google/blockly.git
synced 2026-01-09 18:10:08 +01:00
At a high-level, this change ensures that cleaning up a workspace doesn't move blocks in a way that overlaps with immovable blocks. It also adds missing testing coverage for both Rect (used for bounding box calculations during workspace cleanup) and WorkspaceSvg (for verifying the updated clean up functionality). This also renames the clean up function to be 'tidyUp' since that better suits what's happening (as opposed to other clean-up routines which are actually deinitializing objects).
117 lines
3.4 KiB
TypeScript
117 lines
3.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2019 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* Utility methods for rectangle manipulation.
|
|
* These methods are not specific to Blockly, and could be factored out into
|
|
* a JavaScript framework such as Closure.
|
|
*
|
|
* @class
|
|
*/
|
|
// Former goog.module ID: Blockly.utils.Rect
|
|
|
|
import {Coordinate} from './coordinate.js';
|
|
|
|
/**
|
|
* Class for representing rectangular regions.
|
|
*/
|
|
export class Rect {
|
|
/**
|
|
* @param top Top.
|
|
* @param bottom Bottom.
|
|
* @param left Left.
|
|
* @param right Right.
|
|
*/
|
|
constructor(
|
|
public top: number,
|
|
public bottom: number,
|
|
public left: number,
|
|
public right: number,
|
|
) {}
|
|
|
|
/**
|
|
* Creates a new copy of this rectangle.
|
|
*
|
|
* @returns A copy of this Rect.
|
|
*/
|
|
clone(): Rect {
|
|
return new Rect(this.top, this.bottom, this.left, this.right);
|
|
}
|
|
|
|
/** Returns the height of this rectangle. */
|
|
getHeight(): number {
|
|
return this.bottom - this.top;
|
|
}
|
|
|
|
/** Returns the width of this rectangle. */
|
|
getWidth(): number {
|
|
return this.right - this.left;
|
|
}
|
|
|
|
/**
|
|
* Tests whether this rectangle contains a x/y coordinate.
|
|
*
|
|
* @param x The x coordinate to test for containment.
|
|
* @param y The y coordinate to test for containment.
|
|
* @returns Whether this rectangle contains given coordinate.
|
|
*/
|
|
contains(x: number, y: number): boolean {
|
|
return (
|
|
x >= this.left && x <= this.right && y >= this.top && y <= this.bottom
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Tests whether this rectangle intersects the provided rectangle.
|
|
* Assumes that the coordinate system increases going down and left.
|
|
*
|
|
* @param other The other rectangle to check for intersection with.
|
|
* @returns Whether this rectangle intersects the provided rectangle.
|
|
*/
|
|
intersects(other: Rect): boolean {
|
|
// The following logic can be derived and then simplified from a longer form symmetrical check
|
|
// of verifying each rectangle's borders with the other rectangle by checking if either end of
|
|
// the border's line segment is contained within the other rectangle. The simplified version
|
|
// used here can be logically interpreted as ensuring that each line segment of 'this' rectangle
|
|
// is not outside the bounds of the 'other' rectangle (proving there's an intersection).
|
|
return (this.left <= other.right)
|
|
&& (this.right >= other.left)
|
|
&& (this.bottom >= other.top)
|
|
&& (this.top <= other.bottom);
|
|
}
|
|
|
|
/**
|
|
* Compares bounding rectangles for equality.
|
|
*
|
|
* @param a A Rect.
|
|
* @param b A Rect.
|
|
* @returns True iff the bounding rectangles are equal, or if both are null.
|
|
*/
|
|
static equals(a?: Rect | null, b?: Rect | null): boolean {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
if (!a || !b) {
|
|
return false;
|
|
}
|
|
return a.top === b.top && a.bottom === b.bottom && a.left === b.left && a.right === b.right;
|
|
}
|
|
|
|
/**
|
|
* Creates a new Rect using a position and supplied dimensions.
|
|
*
|
|
* @param position The upper left coordinate of the new rectangle.
|
|
* @param width The width of the rectangle, in pixels.
|
|
* @param height The height of the rectangle, in pixels.
|
|
* @returns A newly created Rect using the provided Coordinate and dimensions.
|
|
*/
|
|
static createFromPoint(position: Coordinate, width: number, height: number): Rect {
|
|
const left = position.x;
|
|
const top = position.y;
|
|
return new Rect(top, top + height, left, left + width);
|
|
}
|
|
}
|