openpencil/packages/core/src/copy.ts
2026-03-24 17:02:01 +03:00

79 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Typed shallow-copy helpers for Fill, Stroke, Effect, and StyleRun.
*
* These replace `structuredClone` for known scene-graph array types,
* avoiding the ~24× overhead of the generic deep-clone algorithm.
* Each helper spreads the top-level object and any nested objects
* (color, offset, gradientStops, dashPattern, style) to ensure
* no shared references between source and copy.
*/
import type { Effect, Fill, GeometryPath, GradientStop, Stroke, StyleRun } from './scene-graph'
// --- Individual copy functions ---
export function copyFill(f: Fill): Fill {
const copy: Fill = { ...f, color: { ...f.color } }
if (f.gradientStops) copy.gradientStops = f.gradientStops.map(copyGradientStop)
if (f.gradientTransform) copy.gradientTransform = { ...f.gradientTransform }
if (f.imageTransform) copy.imageTransform = { ...f.imageTransform }
return copy
}
export function copyStroke(s: Stroke): Stroke {
const copy: Stroke = { ...s, color: { ...s.color } }
if (s.dashPattern) {
copy.dashPattern = [...s.dashPattern]
}
return copy
}
export function copyEffect(e: Effect): Effect {
return {
...e,
color: { ...e.color },
offset: { ...e.offset }
}
}
export function copyStyleRun(r: StyleRun): StyleRun {
return {
...r,
style: {
...r.style,
fills: r.style.fills ? r.style.fills.map(copyFill) : undefined
}
}
}
// --- Array copy functions ---
export function copyFills(fills: Fill[]): Fill[] {
return fills.map(copyFill)
}
export function copyStrokes(strokes: Stroke[]): Stroke[] {
return strokes.map(copyStroke)
}
export function copyEffects(effects: Effect[]): Effect[] {
return effects.map(copyEffect)
}
export function copyStyleRuns(runs: StyleRun[]): StyleRun[] {
return runs.map(copyStyleRun)
}
export function copyGeometryPaths(paths: GeometryPath[]): GeometryPath[] {
return paths.map((p) => ({
windingRule: p.windingRule,
commandsBlob: p.commandsBlob.slice()
}))
}
// --- Internal helpers ---
function copyGradientStop(gs: GradientStop): GradientStop {
return { color: { ...gs.color }, position: gs.position }
}