RotatedDOMRect
This commit is contained in:
parent
14d94f83e7
commit
da4d15f97c
|
|
@ -153,29 +153,7 @@ export class DistanceField extends HTMLElement {
|
||||||
// Collect positions and assign unique IDs to all shapes
|
// Collect positions and assign unique IDs to all shapes
|
||||||
this.shapes.forEach((geometry, index) => {
|
this.shapes.forEach((geometry, index) => {
|
||||||
const rect = geometry.getClientRect();
|
const rect = geometry.getClientRect();
|
||||||
const rotation = (geometry.rotation * Math.PI) / 180; // Convert to radians
|
const [topLeft, topRight, bottomRight, bottomLeft] = rect.corners();
|
||||||
|
|
||||||
// Calculate the center of the rectangle
|
|
||||||
const centerX = (rect.left + rect.right) / 2;
|
|
||||||
const centerY = (rect.top + rect.bottom) / 2;
|
|
||||||
|
|
||||||
// Function to rotate a point around the center
|
|
||||||
const rotatePoint = (x: number, y: number) => {
|
|
||||||
const dx = x - centerX;
|
|
||||||
const dy = y - centerY;
|
|
||||||
const cos = Math.cos(rotation);
|
|
||||||
const sin = Math.sin(rotation);
|
|
||||||
return {
|
|
||||||
x: centerX + dx * cos - dy * sin,
|
|
||||||
y: centerY + dx * sin + dy * cos,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rotate each corner of the rectangle
|
|
||||||
const topLeft = rotatePoint(rect.left, rect.top);
|
|
||||||
const topRight = rotatePoint(rect.right, rect.top);
|
|
||||||
const bottomLeft = rotatePoint(rect.left, rect.bottom);
|
|
||||||
const bottomRight = rotatePoint(rect.right, rect.bottom);
|
|
||||||
|
|
||||||
// Convert rotated coordinates to NDC
|
// Convert rotated coordinates to NDC
|
||||||
const x1 = (topLeft.x / windowWidth) * 2 - 1;
|
const x1 = (topLeft.x / windowWidth) * 2 - 1;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,24 @@
|
||||||
import { css, html } from './common/tags';
|
import { css, html } from './common/tags';
|
||||||
import { ResizeObserverManager } from './common/resize-observer';
|
import { ResizeObserverManager } from './common/resize-observer';
|
||||||
|
import type { Vector2 } from './common/Vector2';
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserverManager();
|
const resizeObserver = new ResizeObserverManager();
|
||||||
|
|
||||||
export type Shape = 'rectangle' | 'circle' | 'triangle';
|
export type Shape = 'rectangle' | 'circle' | 'triangle';
|
||||||
|
|
||||||
type RotatedDOMRect = DOMRect & { rotation: number };
|
type RotatedDOMRect = DOMRect & {
|
||||||
|
// In degrees
|
||||||
|
rotation: number;
|
||||||
|
|
||||||
|
// Returns the center point in worldspace coordinates
|
||||||
|
center(): Vector2;
|
||||||
|
|
||||||
|
// Returns the four corners in worldspace coordinates, in clockwise order
|
||||||
|
corners(): [Vector2, Vector2, Vector2, Vector2];
|
||||||
|
|
||||||
|
// Returns all the vertices in worldspace coordinates
|
||||||
|
vertices(): Vector2[];
|
||||||
|
};
|
||||||
export type MoveEventDetail = { movementX: number; movementY: number };
|
export type MoveEventDetail = { movementX: number; movementY: number };
|
||||||
|
|
||||||
export class MoveEvent extends CustomEvent<MoveEventDetail> {
|
export class MoveEvent extends CustomEvent<MoveEventDetail> {
|
||||||
|
|
@ -286,6 +298,7 @@ export class FolkShape extends HTMLElement {
|
||||||
|
|
||||||
getClientRect(): RotatedDOMRect {
|
getClientRect(): RotatedDOMRect {
|
||||||
const { x, y, width, height, rotation } = this;
|
const { x, y, width, height, rotation } = this;
|
||||||
|
const radians = (rotation * Math.PI) / 180;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
x,
|
x,
|
||||||
|
|
@ -297,9 +310,43 @@ export class FolkShape extends HTMLElement {
|
||||||
right: x + width,
|
right: x + width,
|
||||||
bottom: y + height,
|
bottom: y + height,
|
||||||
rotation,
|
rotation,
|
||||||
|
|
||||||
|
center(): Vector2 {
|
||||||
|
return {
|
||||||
|
x: this.x + this.width / 2,
|
||||||
|
y: this.y + this.height / 2,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
vertices(): Vector2[] {
|
||||||
|
// TODO: Implement
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
|
||||||
|
corners(): [Vector2, Vector2, Vector2, Vector2] {
|
||||||
|
const center = this.center();
|
||||||
|
const cos = Math.cos(radians);
|
||||||
|
const sin = Math.sin(radians);
|
||||||
|
|
||||||
|
const halfWidth = this.width / 2;
|
||||||
|
const halfHeight = this.height / 2;
|
||||||
|
|
||||||
|
// Helper to rotate a point around the center
|
||||||
|
const rotatePoint = (dx: number, dy: number): Vector2 => ({
|
||||||
|
x: center.x + dx * cos - dy * sin,
|
||||||
|
y: center.y + dx * sin + dy * cos,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return vertices in clockwise order: top-left, top-right, bottom-right, bottom-left
|
||||||
|
return [
|
||||||
|
rotatePoint(-halfWidth, -halfHeight), // Top-left
|
||||||
|
rotatePoint(halfWidth, -halfHeight), // Top-right
|
||||||
|
rotatePoint(halfWidth, halfHeight), // Bottom-right
|
||||||
|
rotatePoint(-halfWidth, halfHeight), // Bottom-left
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
toJSON: undefined as any,
|
toJSON: undefined as any,
|
||||||
};
|
};
|
||||||
// return DOMRectReadOnly.fromRect({ x: this.x, y: this.y, width: this.width, height: this.height });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to `Element.getClientBoundingRect()`, but returns an SVG path that precisely outlines the shape.
|
// Similar to `Element.getClientBoundingRect()`, but returns an SVG path that precisely outlines the shape.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue