export abstract class Shape { abstract move(x, y); abstract scale(n, anchorX, anchorY); } export class Rectangle extends Shape { public static from({ x, y, width, height }) { return new Rectangle({ top: y, left: x, right: x + width, bottom: y + height }); } public readonly left: number; public readonly top: number; public readonly right: number; public readonly bottom: number; constructor({ top, left, right, bottom, anchorX = 0, anchorY = 0 } ) { super(); this.top = top; this.right = right; this.bottom = bottom; this.left = left; // console.log({ top, left, right, bottom }); } move(tx: any, ty: any) { let { top , left, right, bottom } = this; top += ty; bottom += ty; right += tx; left += tx; return new Rectangle({ top, left, right, bottom }) } scale(s: any, anchorX = 0, anchorY = 0) { // move to anchor... if (anchorX === 0 && anchorY === 0) { let { top , left, right, bottom } = this; top *= s; left *= s; right *= s; bottom *= s; return new Rectangle({ top, left,right,bottom }); } return this.move(-anchorX, -anchorY) .scale(s) .move(anchorX, anchorY); } }