mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
103 lines
2.0 KiB
TypeScript
103 lines
2.0 KiB
TypeScript
import type { ElementWithBounds } from "./element-bounds";
|
|
import type { ElementRef } from "@/lib/timeline/types";
|
|
|
|
function pointInRotatedRect({
|
|
px,
|
|
py,
|
|
cx,
|
|
cy,
|
|
width,
|
|
height,
|
|
rotation,
|
|
}: {
|
|
px: number;
|
|
py: number;
|
|
cx: number;
|
|
cy: number;
|
|
width: number;
|
|
height: number;
|
|
rotation: number;
|
|
}): boolean {
|
|
const angleRad = (rotation * Math.PI) / 180;
|
|
const cos = Math.cos(-angleRad);
|
|
const sin = Math.sin(-angleRad);
|
|
const dx = px - cx;
|
|
const dy = py - cy;
|
|
const localX = dx * cos - dy * sin;
|
|
const localY = dx * sin + dy * cos;
|
|
const halfW = Math.abs(width) / 2;
|
|
const halfH = Math.abs(height) / 2;
|
|
return (
|
|
localX >= -halfW && localX <= halfW && localY >= -halfH && localY <= halfH
|
|
);
|
|
}
|
|
|
|
export function getHitElements({
|
|
canvasX,
|
|
canvasY,
|
|
elementsWithBounds,
|
|
}: {
|
|
canvasX: number;
|
|
canvasY: number;
|
|
elementsWithBounds: ElementWithBounds[];
|
|
}): ElementWithBounds[] {
|
|
const hits: ElementWithBounds[] = [];
|
|
|
|
for (let i = elementsWithBounds.length - 1; i >= 0; i--) {
|
|
const { bounds } = elementsWithBounds[i];
|
|
if (
|
|
pointInRotatedRect({
|
|
px: canvasX,
|
|
py: canvasY,
|
|
cx: bounds.cx,
|
|
cy: bounds.cy,
|
|
width: bounds.width,
|
|
height: bounds.height,
|
|
rotation: bounds.rotation,
|
|
})
|
|
) {
|
|
hits.push(elementsWithBounds[i]);
|
|
}
|
|
}
|
|
|
|
return hits;
|
|
}
|
|
|
|
export function hitTest({
|
|
canvasX,
|
|
canvasY,
|
|
elementsWithBounds,
|
|
}: {
|
|
canvasX: number;
|
|
canvasY: number;
|
|
elementsWithBounds: ElementWithBounds[];
|
|
}): ElementWithBounds | null {
|
|
return (
|
|
getHitElements({
|
|
canvasX,
|
|
canvasY,
|
|
elementsWithBounds,
|
|
})[0] ?? null
|
|
);
|
|
}
|
|
|
|
export function resolvePreferredHit({
|
|
hits,
|
|
preferredElements,
|
|
}: {
|
|
hits: ElementWithBounds[];
|
|
preferredElements: ElementRef[];
|
|
}): ElementWithBounds | null {
|
|
if (preferredElements.length === 0) return null;
|
|
|
|
return (
|
|
hits.find((hit) =>
|
|
preferredElements.some(
|
|
(preferredElement) =>
|
|
preferredElement.trackId === hit.trackId &&
|
|
preferredElement.elementId === hit.elementId,
|
|
),
|
|
) ?? null
|
|
);
|
|
}
|