- Strip tools/schema.ts from 1831 to 65 lines (remove duplicate tool defs) - Fix tools/index.ts to export ALL_TOOLS from registry instead of schema - Fix renderJsx → renderJSX typo in tools/create.ts and structure.ts - Add geometry.ts with shared rotation/coordinate math utilities - Add isArrayMixed() helper to use-multi-props.ts, deduplicate FillSection/StrokeSection/EffectsSection - Fix broken test imports: use @open-pencil/core instead of relative paths into packages/core/src/ - Merge duplicate import statements across all test files - Export profiler internals and style-run helpers from core index.ts - Add 6 new test files: color, undo, snap, vector, style-runs, text-editor (98 new tests) - Update renderer-effects test for renderer/ directory split
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import type { Vector } from './types'
|
|
|
|
export function degToRad(degrees: number): number {
|
|
return (degrees * Math.PI) / 180
|
|
}
|
|
|
|
export function radToDeg(radians: number): number {
|
|
return (radians * 180) / Math.PI
|
|
}
|
|
|
|
export function rotatePoint(
|
|
px: number,
|
|
py: number,
|
|
cx: number,
|
|
cy: number,
|
|
rad: number
|
|
): Vector {
|
|
const cos = Math.cos(rad)
|
|
const sin = Math.sin(rad)
|
|
return {
|
|
x: cx + (px - cx) * cos - (py - cy) * sin,
|
|
y: cy + (px - cx) * sin + (py - cy) * cos
|
|
}
|
|
}
|
|
|
|
export function rotatedCorners(
|
|
cx: number,
|
|
cy: number,
|
|
hw: number,
|
|
hh: number,
|
|
rotationDeg: number
|
|
): [Vector, Vector, Vector, Vector] {
|
|
const rad = degToRad(rotationDeg)
|
|
const cos = Math.cos(rad)
|
|
const sin = Math.sin(rad)
|
|
return [
|
|
{ x: cx + -hw * cos - -hh * sin, y: cy + -hw * sin + -hh * cos },
|
|
{ x: cx + hw * cos - -hh * sin, y: cy + hw * sin + -hh * cos },
|
|
{ x: cx + hw * cos - hh * sin, y: cy + hw * sin + hh * cos },
|
|
{ x: cx + -hw * cos - hh * sin, y: cy + -hw * sin + hh * cos }
|
|
]
|
|
}
|
|
|
|
export function rotatedBBox(
|
|
x: number,
|
|
y: number,
|
|
w: number,
|
|
h: number,
|
|
rotationDeg: number
|
|
): { left: number; right: number; top: number; bottom: number; centerX: number; centerY: number } {
|
|
if (rotationDeg === 0) {
|
|
return {
|
|
left: x,
|
|
right: x + w,
|
|
top: y,
|
|
bottom: y + h,
|
|
centerX: x + w / 2,
|
|
centerY: y + h / 2
|
|
}
|
|
}
|
|
const corners = rotatedCorners(x + w / 2, y + h / 2, w / 2, h / 2, rotationDeg)
|
|
let left = Infinity,
|
|
right = -Infinity,
|
|
top = Infinity,
|
|
bottom = -Infinity
|
|
for (const c of corners) {
|
|
left = Math.min(left, c.x)
|
|
right = Math.max(right, c.x)
|
|
top = Math.min(top, c.y)
|
|
bottom = Math.max(bottom, c.y)
|
|
}
|
|
return { left, right, top, bottom, centerX: (left + right) / 2, centerY: (top + bottom) / 2 }
|
|
}
|