UNPKG

@stringsync/vexml

Version:

MusicXML to Vexflow

97 lines (96 loc) 2.96 kB
import { Point } from './point'; /** Represents a rectangle in a 2D coordinate system. */ export class Rect { x; y; w; h; constructor( /** upper-left corner x-coordinate */ x, /** upper-left corner y-coordinate */ y, /** total width */ w, /** total height */ h) { this.x = x; this.y = y; this.w = w; this.h = h; } static fromRectLike(rectLike) { return new Rect(rectLike.x, rectLike.y, rectLike.w, rectLike.h); } static fromShape(shape) { return new Rect(shape.left(), shape.top(), shape.right() - shape.left(), shape.bottom() - shape.top()); } static fromRanges({ xRange, yRange }) { return new Rect(xRange.start, yRange.start, xRange.getSize(), yRange.getSize()); } static empty() { return new Rect(0, 0, 0, 0); } static merge(rects) { if (rects.length === 0) { return Rect.empty(); } const x = Math.min(...rects.map((rect) => rect.x)); const y = Math.min(...rects.map((rect) => rect.y)); const w = Math.max(...rects.map((rect) => rect.x + rect.w)) - x; const h = Math.max(...rects.map((rect) => rect.y + rect.h)) - y; return new Rect(x, y, w, h); } origin() { return new Point(this.x, this.y); } center() { return new Point(this.x + this.w / 2, this.y + this.h / 2); } topLeft() { return new Point(this.x, this.y); } topRight() { return new Point(this.x + this.w, this.y); } bottomLeft() { return new Point(this.x, this.y + this.h); } bottomRight() { return new Point(this.x + this.w, this.y + this.h); } translate(opts) { const dx = opts.dx ?? 0; const dy = opts.dy ?? 0; return new Rect(this.x + dx, this.y + dy, this.w, this.h); } quadrants() { const halfWidth = this.w / 2; const halfHeight = this.h / 2; const topRight = new Rect(this.x + halfWidth, this.y, halfWidth, halfHeight); const topLeft = new Rect(this.x, this.y, halfWidth, halfHeight); const bottomLeft = new Rect(this.x, this.y + halfHeight, halfWidth, halfHeight); const bottomRight = new Rect(this.x + halfWidth, this.y + halfHeight, halfWidth, halfHeight); return [topRight, topLeft, bottomLeft, bottomRight]; } contains(point) { return point.x >= this.x && point.x <= this.x + this.w && point.y >= this.y && point.y <= this.y + this.h; } toRectLike() { return { x: this.x, y: this.y, w: this.w, h: this.h }; } left() { return this.x; } right() { return this.x + this.w; } top() { // NOTE: This assumes that the rectangle is not rotated. return this.y; } bottom() { // NOTE: This assumes that the rectangle is not rotated. return this.y + this.h; } }