UNPKG

@dominicstop/utils

Version:

Yet another event emitter written in typescript.

327 lines (326 loc) 8.13 kB
import { Point } from "./Point"; export class Rect { constructor(args) { switch (args.mode) { case 'originAndSize': this.origin = new Point(args.origin); this.size = args.size; break; case 'corners': this.origin = new Point({ x: args.minX, y: args.minY }); this.size = { width: args.maxX - args.minX, height: args.maxY - args.minY }; break; default: this.origin = Point.zero; this.size = { width: 0, height: 0 }; break; } ; } ; ; // MARK: Getter + Setter // --------------------- get minX() { return this.origin.x; } ; set minX(value) { this.origin.x = value; } ; get minY() { return this.origin.y; } ; set minY(value) { this.origin.y = value; } ; get midX() { return this.origin.x + (this.size.width / 2); } ; set midX(value) { this.origin.x = value - (this.width / 2); } ; get midY() { return this.origin.y + (this.size.height / 2); } ; set midY(value) { this.origin.y = value - (this.height / 2); } ; get maxX() { return this.origin.x + this.size.width; } ; set maxX(value) { this.origin.x = value - this.width; } ; get maxY() { return this.origin.y + this.size.height; } ; set maxY(value) { this.origin.y = value - this.height; } ; // MARK: Computed Properties // ------------------------- get asValue() { return { origin: this.origin, size: this.size, }; } ; get boundingBox() { return new Rect({ mode: 'originAndSize', ...this.asValue, }); } ; get width() { return this.size.width; } ; get height() { return this.size.height; } ; get isNaN() { return (Number.isNaN(this.origin.x) || Number.isNaN(this.origin.y) || Number.isNaN(this.size.width) || Number.isNaN(this.size.height)); } ; get area() { return this.width * this.height; } ; // MARK: Computed Properties - Points // ---------------------------------- get minMaxDimensions() { return { minX: this.minX, minY: this.minY, maxX: this.maxX, maxY: this.maxY, }; } ; get center() { return new Point({ x: this.midX, y: this.midY }); } ; get topMidPoint() { return new Point({ x: this.midX, y: this.minY }); } ; get bottomMidPoint() { return new Point({ x: this.midX, y: this.maxY }); } ; get leftMidPoint() { return new Point({ x: this.minX, y: this.midY }); } ; get rightMidPoint() { return new Point({ x: this.maxX, y: this.midY }); } ; get topLeftPoint() { return new Point({ x: this.minX, y: this.minY }); } ; get topRightPoint() { return new Point({ x: this.maxX, y: this.minY }); } get bottomLeftPoint() { return new Point({ x: this.minX, y: this.maxY }); } get bottomRightPoint() { return new Point({ x: this.maxX, y: this.maxY }); } ; get cornerPointsAsArray() { return [ this.topLeftPoint, this.topRightPoint, this.bottomLeftPoint, this.bottomRightPoint, ]; } ; // MARK: Methods // ------------- clone() { return new Rect({ mode: 'originAndSize', origin: this.origin, size: this.size, }); } ; computeDistanceToOther(other) { return this.center.getDistance(other.center); } ; isPointInside(pointValue) { const { x, y } = pointValue; return (x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY); } isEdgeToEdgeWithOther(other) { return (this.maxX === other.minX || this.minX === other.maxX || this.maxY === other.minY || this.minY === other.maxY) && (this.maxY >= other.minY && this.minY <= other.maxY && this.maxX >= other.minX && this.minX <= other.maxX); } ; isCollidingWithOther(other) { return !(this.maxX <= other.minX || this.minX >= other.maxX || this.maxY <= other.minY || this.minY >= other.maxY); } ; setPointCenter(newCenterPoint) { const newX = newCenterPoint.x - (this.width / 2); const newY = newCenterPoint.y - (this.height / 2); this.origin.x = newX; this.origin.y = newY; } ; getCornerPoint(cornerKey) { switch (cornerKey) { case 'topLeftPoint': return this.topLeftPoint.clone(); case 'bottomLeftPoint': return this.bottomLeftPoint.clone(); case 'bottomRightPoint': return this.bottomRightPoint.clone(); case 'topRightPoint': return this.topRightPoint.clone(); } ; } ; setCornerPoint(cornerKey, newValue) { switch (cornerKey) { case 'topLeftPoint': this.minX = newValue.x; this.minY = newValue.y; break; case 'bottomLeftPoint': this.minX = newValue.x; this.maxY = newValue.y; break; case 'bottomRightPoint': this.maxX = newValue.x; this.maxY = newValue.y; break; case 'topRightPoint': this.maxX = newValue.x; this.maxY = newValue.y; break; } ; } ; applyScaleToNewSize(newSize) { let center = this.center; let newX = center.x - (newSize.width / 2); let newY = center.y - (newSize.height / 2); this.origin.x = newX; this.origin.y = newY; } ; applyUniformScaleByFactor(args) { const scaleFactor = args.percentAmount; let anchor = (() => { switch (args.anchorReference.mode) { case 'relativeToOrigin': return this.origin.clone(); case 'relativeToCenter': return this.center; case 'relativeToRectCorner': return this.getCornerPoint(args.anchorReference.cornerKey); } ; })(); const newWidth = this.width * scaleFactor; const newHeight = this.height * scaleFactor; this.size = { width: newWidth, height: newHeight, }; switch (args.anchorReference.mode) { case 'relativeToOrigin': this.origin = anchor; break; case 'relativeToCenter': this.setPointCenter(anchor); break; case 'relativeToRectCorner': this.setCornerPoint(args.anchorReference.cornerKey, anchor); break; } ; } scaledUniformallyByFactor(args) { const clone = this.clone(); clone.applyUniformScaleByFactor(args); return clone; } ; // MARK: - Static Members - Alias Init // ----------------------------------- static initFromValue(args) { return new Rect({ mode: 'originAndSize', ...args, }); } ; }