| 220 | // Carry x/y forward across keyframes that only set one axis, so the path is |
| 221 | // continuous (GSAP holds the last value for an unspecified property). |
| 222 | function positionPath(keyframes: KeyframePoint[]): Array<{ x: number; y: number }> | null { |
| 223 | if (keyframes.length === 0) return null; |
| 224 | let lastX = 0; |
| 225 | let lastY = 0; |
| 226 | return keyframes.map((kf) => { |
| 227 | const x = num(kf.properties.x); |
| 228 | const y = num(kf.properties.y); |
| 229 | if (x !== null) lastX = x; |
| 230 | if (y !== null) lastY = y; |
| 231 | return { x: lastX, y: lastY }; |
| 232 | }); |
| 233 | } |
| 234 | |
| 235 | // ── Composition surfacing ──────────────────────────────────────────────────── |
| 236 | |