diff --git a/src/__tests__/TransformDOMRect.test.ts b/src/__tests__/TransformDOMRect.test.ts index 2c561b4..e8d2605 100644 --- a/src/__tests__/TransformDOMRect.test.ts +++ b/src/__tests__/TransformDOMRect.test.ts @@ -103,6 +103,127 @@ describe('TransformDOMRect', () => { expectPointClose(backToLocal, point); }); + + test('coordinate transformations with rotation and translation', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + rotation: Math.PI / 4, // 45 degrees + }); + + // Test multiple points + const testPoints = [ + { x: -100, y: 100 }, // Origin point + { x: 200, y: 150 }, // Middle point + { x: 300, y: 200 }, // Far point + ]; + + testPoints.forEach((point) => { + const localPoint = rect.toLocalSpace(point); + const backToParent = rect.toParentSpace(localPoint); + expectPointClose(backToParent, point); + }); + }); + + describe('corner setters', () => { + test('setTopLeft maintains rectangle properties', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + }); + + rect.setTopLeft({ x: 50, y: 50 }); + expect(rect.x).toBe(50); + expect(rect.y).toBe(50); + expect(rect.width).toBe(250); // Increased by 50 + expect(rect.height).toBe(150); // Increased by 50 + }); + + test('setTopRight maintains rectangle properties', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + }); + + rect.setTopRight({ x: 350, y: 50 }); + expect(rect.x).toBe(100); + expect(rect.y).toBe(50); + expect(rect.width).toBe(350); + expect(rect.height).toBe(150); + }); + + test('setBottomRight maintains rectangle properties', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + }); + + rect.setBottomRight({ x: 350, y: 250 }); + expect(rect.x).toBe(100); + expect(rect.y).toBe(100); + expect(rect.width).toBe(350); + expect(rect.height).toBe(250); + }); + + test('setBottomLeft maintains rectangle properties', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + }); + + rect.setBottomLeft({ x: 50, y: 250 }); + expect(rect.x).toBe(50); + expect(rect.y).toBe(100); + expect(rect.width).toBe(250); + expect(rect.height).toBe(250); + }); + + test('corner setters work with rotation', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + rotation: Math.PI / 4, // 45 degrees + }); + + const newTopLeft = rect.toParentSpace({ x: 0, y: 0 }); + rect.setTopLeft(newTopLeft); + + const transformedTopLeft = rect.toLocalSpace(newTopLeft); + expectPointClose(transformedTopLeft, { x: 0, y: 0 }); + }); + + test('setBottomRight works with upside down rotation', () => { + const rect = new TransformDOMRect({ + x: 100, + y: 100, + width: 200, + height: 100, + rotation: Math.PI, // 180 degrees - upside down + }); + + rect.setBottomRight({ x: 350, y: 250 }); + expect(rect.x).toBe(100); + expect(rect.y).toBe(100); + expect(rect.width).toBe(250); + expect(rect.height).toBe(150); + + // Verify the corner is actually at the expected position + const transformedBottomRight = rect.toParentSpace(rect.bottomRight); + expectPointClose(transformedBottomRight, { x: 350, y: 250 }); + }); + }); }); describe('TransformDOMRectReadonly', () => { diff --git a/src/common/TransformDOMRect.ts b/src/common/TransformDOMRect.ts index 15845b0..dd5a114 100644 --- a/src/common/TransformDOMRect.ts +++ b/src/common/TransformDOMRect.ts @@ -173,19 +173,19 @@ export class TransformDOMRect implements DOMRect { } setTopLeft(point: Point) { - const oldBottomRight = this.bottomRight; - this._width = oldBottomRight.x - point.x; - this._height = oldBottomRight.y - point.y; + const oldBottomRight = this.toParentSpace(this.bottomRight); this._x = point.x; this._y = point.y; + this._width = oldBottomRight.x - point.x; + this._height = oldBottomRight.y - point.y; this.#updateMatrices(); } setTopRight(point: Point) { - const oldBottomLeft = this.bottomLeft; - this._width = point.x; - this._height = oldBottomLeft.y - point.y; + const oldBottomLeft = this.toParentSpace(this.bottomLeft); this._y = point.y; + this._width = point.x - this._x; + this._height = oldBottomLeft.y - point.y; this.#updateMatrices(); } @@ -196,10 +196,10 @@ export class TransformDOMRect implements DOMRect { } setBottomLeft(point: Point) { - const oldTopRight = this.topRight; - this._width = oldTopRight.x - point.x; - this._height = point.y; + const oldTopRight = this.toParentSpace(this.topRight); this._x = point.x; + this._width = oldTopRight.x - point.x; + this._height = point.y - this._y; this.#updateMatrices(); }