@clipkit/editor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +51 -0
  3. package/dist/Editor.d.ts +3 -0
  4. package/dist/Editor.d.ts.map +1 -0
  5. package/dist/Editor.js +73 -0
  6. package/dist/Editor.js.map +1 -0
  7. package/dist/ExportDialog.d.ts +12 -0
  8. package/dist/ExportDialog.d.ts.map +1 -0
  9. package/dist/ExportDialog.js +30 -0
  10. package/dist/ExportDialog.js.map +1 -0
  11. package/dist/MotionPathOverlay.d.ts +5 -0
  12. package/dist/MotionPathOverlay.d.ts.map +1 -0
  13. package/dist/MotionPathOverlay.js +156 -0
  14. package/dist/MotionPathOverlay.js.map +1 -0
  15. package/dist/PerfHud.d.ts +2 -0
  16. package/dist/PerfHud.d.ts.map +1 -0
  17. package/dist/PerfHud.js +85 -0
  18. package/dist/PerfHud.js.map +1 -0
  19. package/dist/Stage.d.ts +2 -0
  20. package/dist/Stage.d.ts.map +1 -0
  21. package/dist/Stage.js +406 -0
  22. package/dist/Stage.js.map +1 -0
  23. package/dist/StageOverlay.d.ts +7 -0
  24. package/dist/StageOverlay.d.ts.map +1 -0
  25. package/dist/StageOverlay.js +508 -0
  26. package/dist/StageOverlay.js.map +1 -0
  27. package/dist/commands.d.ts +18 -0
  28. package/dist/commands.d.ts.map +1 -0
  29. package/dist/commands.js +103 -0
  30. package/dist/commands.js.map +1 -0
  31. package/dist/configuration.d.ts +9 -0
  32. package/dist/configuration.d.ts.map +1 -0
  33. package/dist/configuration.js +21 -0
  34. package/dist/configuration.js.map +1 -0
  35. package/dist/controls/AnimationsStack.d.ts +8 -0
  36. package/dist/controls/AnimationsStack.d.ts.map +1 -0
  37. package/dist/controls/AnimationsStack.js +188 -0
  38. package/dist/controls/AnimationsStack.js.map +1 -0
  39. package/dist/controls/CameraControl.d.ts +19 -0
  40. package/dist/controls/CameraControl.d.ts.map +1 -0
  41. package/dist/controls/CameraControl.js +47 -0
  42. package/dist/controls/CameraControl.js.map +1 -0
  43. package/dist/controls/CaptionLengthControl.d.ts +5 -0
  44. package/dist/controls/CaptionLengthControl.d.ts.map +1 -0
  45. package/dist/controls/CaptionLengthControl.js +11 -0
  46. package/dist/controls/CaptionLengthControl.js.map +1 -0
  47. package/dist/controls/CaptionTranscribe.d.ts +2 -0
  48. package/dist/controls/CaptionTranscribe.d.ts.map +1 -0
  49. package/dist/controls/CaptionTranscribe.js +95 -0
  50. package/dist/controls/CaptionTranscribe.js.map +1 -0
  51. package/dist/controls/ColorPicker.d.ts +17 -0
  52. package/dist/controls/ColorPicker.d.ts.map +1 -0
  53. package/dist/controls/ColorPicker.js +354 -0
  54. package/dist/controls/ColorPicker.js.map +1 -0
  55. package/dist/controls/ControlRenderer.d.ts +20 -0
  56. package/dist/controls/ControlRenderer.d.ts.map +1 -0
  57. package/dist/controls/ControlRenderer.js +106 -0
  58. package/dist/controls/ControlRenderer.js.map +1 -0
  59. package/dist/controls/CropControl.d.ts +2 -0
  60. package/dist/controls/CropControl.d.ts.map +1 -0
  61. package/dist/controls/CropControl.js +177 -0
  62. package/dist/controls/CropControl.js.map +1 -0
  63. package/dist/controls/EffectsStack.d.ts +8 -0
  64. package/dist/controls/EffectsStack.d.ts.map +1 -0
  65. package/dist/controls/EffectsStack.js +89 -0
  66. package/dist/controls/EffectsStack.js.map +1 -0
  67. package/dist/controls/GradeControl.d.ts +2 -0
  68. package/dist/controls/GradeControl.d.ts.map +1 -0
  69. package/dist/controls/GradeControl.js +120 -0
  70. package/dist/controls/GradeControl.js.map +1 -0
  71. package/dist/controls/KeyframeDiamond.d.ts +11 -0
  72. package/dist/controls/KeyframeDiamond.d.ts.map +1 -0
  73. package/dist/controls/KeyframeDiamond.js +87 -0
  74. package/dist/controls/KeyframeDiamond.js.map +1 -0
  75. package/dist/controls/LightingControls.d.ts +24 -0
  76. package/dist/controls/LightingControls.d.ts.map +1 -0
  77. package/dist/controls/LightingControls.js +108 -0
  78. package/dist/controls/LightingControls.js.map +1 -0
  79. package/dist/controls/ShapePresetControl.d.ts +4 -0
  80. package/dist/controls/ShapePresetControl.d.ts.map +1 -0
  81. package/dist/controls/ShapePresetControl.js +30 -0
  82. package/dist/controls/ShapePresetControl.js.map +1 -0
  83. package/dist/controls/ValueField.d.ts +10 -0
  84. package/dist/controls/ValueField.d.ts.map +1 -0
  85. package/dist/controls/ValueField.js +158 -0
  86. package/dist/controls/ValueField.js.map +1 -0
  87. package/dist/controls/VolumeControl.d.ts +10 -0
  88. package/dist/controls/VolumeControl.d.ts.map +1 -0
  89. package/dist/controls/VolumeControl.js +75 -0
  90. package/dist/controls/VolumeControl.js.map +1 -0
  91. package/dist/controls/compound.d.ts +46 -0
  92. package/dist/controls/compound.d.ts.map +1 -0
  93. package/dist/controls/compound.js +160 -0
  94. package/dist/controls/compound.js.map +1 -0
  95. package/dist/controls/layout.d.ts +38 -0
  96. package/dist/controls/layout.d.ts.map +1 -0
  97. package/dist/controls/layout.js +162 -0
  98. package/dist/controls/layout.js.map +1 -0
  99. package/dist/controls/primitives.d.ts +83 -0
  100. package/dist/controls/primitives.d.ts.map +1 -0
  101. package/dist/controls/primitives.js +194 -0
  102. package/dist/controls/primitives.js.map +1 -0
  103. package/dist/controls/transcribe.worker.d.ts +2 -0
  104. package/dist/controls/transcribe.worker.d.ts.map +1 -0
  105. package/dist/controls/transcribe.worker.js +22 -0
  106. package/dist/controls/transcribe.worker.js.map +1 -0
  107. package/dist/frame/AddElementBar.d.ts +2 -0
  108. package/dist/frame/AddElementBar.d.ts.map +1 -0
  109. package/dist/frame/AddElementBar.js +103 -0
  110. package/dist/frame/AddElementBar.js.map +1 -0
  111. package/dist/frame/Breadcrumbs.d.ts +2 -0
  112. package/dist/frame/Breadcrumbs.d.ts.map +1 -0
  113. package/dist/frame/Breadcrumbs.js +32 -0
  114. package/dist/frame/Breadcrumbs.js.map +1 -0
  115. package/dist/frame/GroupFlash.d.ts +2 -0
  116. package/dist/frame/GroupFlash.d.ts.map +1 -0
  117. package/dist/frame/GroupFlash.js +65 -0
  118. package/dist/frame/GroupFlash.js.map +1 -0
  119. package/dist/frame/Resizable.d.ts +12 -0
  120. package/dist/frame/Resizable.d.ts.map +1 -0
  121. package/dist/frame/Resizable.js +37 -0
  122. package/dist/frame/Resizable.js.map +1 -0
  123. package/dist/frame/Section.d.ts +23 -0
  124. package/dist/frame/Section.d.ts.map +1 -0
  125. package/dist/frame/Section.js +23 -0
  126. package/dist/frame/Section.js.map +1 -0
  127. package/dist/frame/ZoomControl.d.ts +9 -0
  128. package/dist/frame/ZoomControl.d.ts.map +1 -0
  129. package/dist/frame/ZoomControl.js +15 -0
  130. package/dist/frame/ZoomControl.js.map +1 -0
  131. package/dist/index.d.ts +9 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +13 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lib/camera-gizmo.d.ts +15 -0
  136. package/dist/lib/camera-gizmo.d.ts.map +1 -0
  137. package/dist/lib/camera-gizmo.js +57 -0
  138. package/dist/lib/camera-gizmo.js.map +1 -0
  139. package/dist/lib/camera-tool.d.ts +43 -0
  140. package/dist/lib/camera-tool.d.ts.map +1 -0
  141. package/dist/lib/camera-tool.js +80 -0
  142. package/dist/lib/camera-tool.js.map +1 -0
  143. package/dist/lib/caption-segments.d.ts +17 -0
  144. package/dist/lib/caption-segments.d.ts.map +1 -0
  145. package/dist/lib/caption-segments.js +50 -0
  146. package/dist/lib/caption-segments.js.map +1 -0
  147. package/dist/lib/group.d.ts +12 -0
  148. package/dist/lib/group.d.ts.map +1 -0
  149. package/dist/lib/group.js +61 -0
  150. package/dist/lib/group.js.map +1 -0
  151. package/dist/lib/keyframes.d.ts +29 -0
  152. package/dist/lib/keyframes.d.ts.map +1 -0
  153. package/dist/lib/keyframes.js +92 -0
  154. package/dist/lib/keyframes.js.map +1 -0
  155. package/dist/lib/sfx-preview.d.ts +18 -0
  156. package/dist/lib/sfx-preview.d.ts.map +1 -0
  157. package/dist/lib/sfx-preview.js +74 -0
  158. package/dist/lib/sfx-preview.js.map +1 -0
  159. package/dist/lib/shape-presets.d.ts +35 -0
  160. package/dist/lib/shape-presets.d.ts.map +1 -0
  161. package/dist/lib/shape-presets.js +81 -0
  162. package/dist/lib/shape-presets.js.map +1 -0
  163. package/dist/lib/ungroup.d.ts +12 -0
  164. package/dist/lib/ungroup.d.ts.map +1 -0
  165. package/dist/lib/ungroup.js +40 -0
  166. package/dist/lib/ungroup.js.map +1 -0
  167. package/dist/lib/utils.d.ts +3 -0
  168. package/dist/lib/utils.d.ts.map +1 -0
  169. package/dist/lib/utils.js +9 -0
  170. package/dist/lib/utils.js.map +1 -0
  171. package/dist/panels/AssetsPanel.d.ts +2 -0
  172. package/dist/panels/AssetsPanel.d.ts.map +1 -0
  173. package/dist/panels/AssetsPanel.js +108 -0
  174. package/dist/panels/AssetsPanel.js.map +1 -0
  175. package/dist/panels/InspectorPanel.d.ts +2 -0
  176. package/dist/panels/InspectorPanel.d.ts.map +1 -0
  177. package/dist/panels/InspectorPanel.js +286 -0
  178. package/dist/panels/InspectorPanel.js.map +1 -0
  179. package/dist/panels/InterpolationPanel.d.ts +2 -0
  180. package/dist/panels/InterpolationPanel.d.ts.map +1 -0
  181. package/dist/panels/InterpolationPanel.js +226 -0
  182. package/dist/panels/InterpolationPanel.js.map +1 -0
  183. package/dist/panels/LayersTree.d.ts +4 -0
  184. package/dist/panels/LayersTree.d.ts.map +1 -0
  185. package/dist/panels/LayersTree.js +137 -0
  186. package/dist/panels/LayersTree.js.map +1 -0
  187. package/dist/panels/LeftRail.d.ts +6 -0
  188. package/dist/panels/LeftRail.d.ts.map +1 -0
  189. package/dist/panels/LeftRail.js +35 -0
  190. package/dist/panels/LeftRail.js.map +1 -0
  191. package/dist/panels/SourcePanel.d.ts +2 -0
  192. package/dist/panels/SourcePanel.d.ts.map +1 -0
  193. package/dist/panels/SourcePanel.js +470 -0
  194. package/dist/panels/SourcePanel.js.map +1 -0
  195. package/dist/panels/TimelinePanel.d.ts +11 -0
  196. package/dist/panels/TimelinePanel.d.ts.map +1 -0
  197. package/dist/panels/TimelinePanel.js +98 -0
  198. package/dist/panels/TimelinePanel.js.map +1 -0
  199. package/dist/panels/assets/SfxBrowser.d.ts +2 -0
  200. package/dist/panels/assets/SfxBrowser.d.ts.map +1 -0
  201. package/dist/panels/assets/SfxBrowser.js +49 -0
  202. package/dist/panels/assets/SfxBrowser.js.map +1 -0
  203. package/dist/panels/assets/use-assets.d.ts +11 -0
  204. package/dist/panels/assets/use-assets.d.ts.map +1 -0
  205. package/dist/panels/assets/use-assets.js +84 -0
  206. package/dist/panels/assets/use-assets.js.map +1 -0
  207. package/dist/panels/assets/use-sfx.d.ts +6 -0
  208. package/dist/panels/assets/use-sfx.d.ts.map +1 -0
  209. package/dist/panels/assets/use-sfx.js +47 -0
  210. package/dist/panels/assets/use-sfx.js.map +1 -0
  211. package/dist/panels/timeline/CanvasTimeline.d.ts +7 -0
  212. package/dist/panels/timeline/CanvasTimeline.d.ts.map +1 -0
  213. package/dist/panels/timeline/CanvasTimeline.js +1536 -0
  214. package/dist/panels/timeline/CanvasTimeline.js.map +1 -0
  215. package/dist/panels/timeline/Clip.d.ts +37 -0
  216. package/dist/panels/timeline/Clip.d.ts.map +1 -0
  217. package/dist/panels/timeline/Clip.js +176 -0
  218. package/dist/panels/timeline/Clip.js.map +1 -0
  219. package/dist/panels/timeline/CurveEditor.d.ts +2 -0
  220. package/dist/panels/timeline/CurveEditor.d.ts.map +1 -0
  221. package/dist/panels/timeline/CurveEditor.js +233 -0
  222. package/dist/panels/timeline/CurveEditor.js.map +1 -0
  223. package/dist/panels/timeline/MixerRail.d.ts +7 -0
  224. package/dist/panels/timeline/MixerRail.d.ts.map +1 -0
  225. package/dist/panels/timeline/MixerRail.js +295 -0
  226. package/dist/panels/timeline/MixerRail.js.map +1 -0
  227. package/dist/panels/timeline/Waveform.d.ts +11 -0
  228. package/dist/panels/timeline/Waveform.d.ts.map +1 -0
  229. package/dist/panels/timeline/Waveform.js +63 -0
  230. package/dist/panels/timeline/Waveform.js.map +1 -0
  231. package/dist/panels/timeline/clip-style.d.ts +10 -0
  232. package/dist/panels/timeline/clip-style.d.ts.map +1 -0
  233. package/dist/panels/timeline/clip-style.js +20 -0
  234. package/dist/panels/timeline/clip-style.js.map +1 -0
  235. package/dist/panels/timeline/filmstrip.d.ts +7 -0
  236. package/dist/panels/timeline/filmstrip.d.ts.map +1 -0
  237. package/dist/panels/timeline/filmstrip.js +135 -0
  238. package/dist/panels/timeline/filmstrip.js.map +1 -0
  239. package/dist/panels/timeline/timeline-layout.d.ts +65 -0
  240. package/dist/panels/timeline/timeline-layout.d.ts.map +1 -0
  241. package/dist/panels/timeline/timeline-layout.js +118 -0
  242. package/dist/panels/timeline/timeline-layout.js.map +1 -0
  243. package/dist/types.d.ts +68 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +3 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +56 -0
  248. package/src/styles.css +185 -0
@@ -0,0 +1,85 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // PerfHud — small floating overlay showing live engine stats while
3
+ // preview is running. Useful for diagnosing choppiness: at a glance
4
+ // you can tell whether the bottleneck is the worker (frames not
5
+ // arriving fast enough), the main thread (paint gap jitter), or
6
+ // buffer starvation (engine can't keep up with playback).
7
+ //
8
+ // Toggled by Shift+P (wired in Editor.tsx). Polls engine.getStats()
9
+ // every 250ms — cheap enough to not affect the metrics it measures.
10
+ import { useEffect, useState } from 'react';
11
+ import { useEditorContext } from '@clipkit/editor-core';
12
+ import { useEditorStore } from '@clipkit/editor-core';
13
+ const POLL_MS = 250;
14
+ export function PerfHud() {
15
+ const { engine } = useEditorContext();
16
+ const open = useEditorStore((s) => s.ui.perfHudOpen);
17
+ const [stats, setStats] = useState(null);
18
+ useEffect(() => {
19
+ if (!open || !engine)
20
+ return;
21
+ const tick = () => setStats(engine.getStats());
22
+ tick();
23
+ const id = window.setInterval(tick, POLL_MS);
24
+ return () => window.clearInterval(id);
25
+ }, [open, engine]);
26
+ if (!open || !stats)
27
+ return null;
28
+ return (_jsxs("div", { role: "status", "aria-label": "Playback performance", className: "pointer-events-none absolute top-2 right-2 z-40 select-none rounded-md px-2.5 py-2 font-mono text-[10.5px] leading-tight", style: {
29
+ background: 'rgba(0, 0, 0, 0.78)',
30
+ color: 'var(--color-foreground)',
31
+ backdropFilter: 'blur(6px)',
32
+ minWidth: 168,
33
+ }, children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-3 text-muted-foreground/70 uppercase tracking-wider", children: [_jsx("span", { children: "perf" }), _jsx("span", { className: "text-[9px] opacity-70", children: "shift+p" })] }), _jsx(Row, { label: "fps", value: `${stats.fps} / ${stats.targetFps}`, tone: fpsTone(stats) }), _jsx(Row, { label: "buffer", value: `${stats.bufferAheadSec.toFixed(2)}s`, tone: bufferTone(stats) }), _jsx(Row, { label: "gap", value: `${stats.frameGapMs.toFixed(1)} (${stats.frameGapMaxMs.toFixed(0)})`, tone: gapTone(stats) }), _jsx(Row, { label: "worker", value: `${stats.workerLatencyMs.toFixed(1)}ms`, tone: workerTone(stats) }), _jsx(Row, { label: "\u21B3 decode", value: `${stats.prepareMs.toFixed(1)}ms`, tone: subTone(stats.prepareMs, stats.targetFps) }), _jsx(Row, { label: "\u21B3 render", value: `${stats.renderMs.toFixed(1)}ms`, tone: subTone(stats.renderMs, stats.targetFps) }), _jsx(Row, { label: "\u21B3 readback", value: `${stats.videoFrameMs.toFixed(1)}ms`, tone: subTone(stats.videoFrameMs, stats.targetFps) }), _jsx(Row, { label: "blur smp", value: stats.blurSamples.toFixed(1), tone: "muted" }), _jsx(Row, { label: "\u21B3 total", value: `${stats.workerTotalMs.toFixed(1)}ms`, tone: subTone(stats.workerTotalMs, stats.targetFps) }), _jsx(Row, { label: "queue lag", value: `${stats.queueLagMs.toFixed(1)}ms`, tone: subTone(stats.queueLagMs, stats.targetFps) }), _jsx(Row, { label: "drawImage", value: `${stats.drawImageMs.toFixed(1)}ms`, tone: subTone(stats.drawImageMs, stats.targetFps) }), _jsx(Row, { label: "starve", value: `${stats.starvationCount}`, tone: stats.starvationCount > 0 ? 'red' : 'green' }), _jsx(Row, { label: "inflight", value: `${stats.inflight}`, tone: "muted" })] }));
34
+ }
35
+ function Row({ label, value, tone, }) {
36
+ return (_jsxs("div", { className: "flex items-center justify-between gap-3 tabular-nums", children: [_jsx("span", { className: "text-muted-foreground/70", children: label }), _jsx("span", { style: { color: toneColor(tone) }, children: value })] }));
37
+ }
38
+ function toneColor(t) {
39
+ switch (t) {
40
+ case 'green': return 'oklch(0.78 0.18 145)';
41
+ case 'yellow': return 'oklch(0.82 0.18 90)';
42
+ case 'red': return 'oklch(0.70 0.25 25)';
43
+ case 'muted': return 'var(--color-muted-foreground)';
44
+ }
45
+ }
46
+ // ── Threshold rules ───────────────────────────────────────────────
47
+ function fpsTone(s) {
48
+ if (s.fps >= s.targetFps * 0.95)
49
+ return 'green';
50
+ if (s.fps >= s.targetFps * 0.8)
51
+ return 'yellow';
52
+ return 'red';
53
+ }
54
+ function bufferTone(s) {
55
+ if (s.bufferAheadSec >= 0.5)
56
+ return 'green';
57
+ if (s.bufferAheadSec >= 0.15)
58
+ return 'yellow';
59
+ return 'red';
60
+ }
61
+ function gapTone(s) {
62
+ const targetGap = 1000 / s.targetFps;
63
+ if (s.frameGapMaxMs <= targetGap * 1.5)
64
+ return 'green';
65
+ if (s.frameGapMaxMs <= targetGap * 2.5)
66
+ return 'yellow';
67
+ return 'red';
68
+ }
69
+ function workerTone(s) {
70
+ const budget = 1000 / s.targetFps;
71
+ if (s.workerLatencyMs <= budget)
72
+ return 'green';
73
+ if (s.workerLatencyMs <= budget * 2)
74
+ return 'yellow';
75
+ return 'red';
76
+ }
77
+ function subTone(ms, targetFps) {
78
+ const budget = 1000 / targetFps;
79
+ if (ms <= budget)
80
+ return 'green';
81
+ if (ms <= budget * 2)
82
+ return 'yellow';
83
+ return 'red';
84
+ }
85
+ //# sourceMappingURL=PerfHud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerfHud.js","sourceRoot":"","sources":["../src/PerfHud.tsx"],"names":[],"mappings":";AAAA,mEAAmE;AACnE,oEAAoE;AACpE,gEAAgE;AAChE,gEAAgE;AAChE,0DAA0D;AAC1D,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AAEpE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB,MAAM,UAAU,OAAO;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAE7D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAC7B,MAAM,IAAI,GAAG,GAAS,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrD,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,gBACF,sBAAsB,EACjC,SAAS,EAAC,0HAA0H,EACpI,KAAK,EAAE;YACL,UAAU,EAAE,qBAAqB;YACjC,KAAK,EAAE,yBAAyB;YAChC,cAAc,EAAE,WAAW;YAC3B,QAAQ,EAAE,GAAG;SACd,aAED,eAAK,SAAS,EAAC,gGAAgG,aAC7G,kCAAiB,EACjB,eAAM,SAAS,EAAC,uBAAuB,wBAAe,IAClD,EACN,KAAC,GAAG,IAAC,KAAK,EAAC,KAAK,EAAC,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GAAI,EACrF,KAAC,GAAG,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,GAAI,EAC7F,KAAC,GAAG,IACF,KAAK,EAAC,KAAK,EACX,KAAK,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAC3E,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,GACpB,EACF,KAAC,GAAG,IACF,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE,GAAG,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAC9C,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,GACvB,EACF,KAAC,GAAG,IACF,KAAK,EAAC,eAAU,EAChB,KAAK,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EACxC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,GAC/C,EACF,KAAC,GAAG,IACF,KAAK,EAAC,eAAU,EAChB,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EACvC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,GAC9C,EACF,KAAC,GAAG,IACF,KAAK,EAAC,iBAAY,EAClB,KAAK,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAC3C,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,GAClD,EACF,KAAC,GAAG,IAAC,KAAK,EAAC,UAAU,EAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAC,OAAO,GAAG,EAC1E,KAAC,GAAG,IACF,KAAK,EAAC,cAAS,EACf,KAAK,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAC5C,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,GACnD,EACF,KAAC,GAAG,IACF,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EACzC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,GAChD,EACF,KAAC,GAAG,IACF,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAC1C,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,GACjD,EACF,KAAC,GAAG,IACF,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE,GAAG,KAAK,CAAC,eAAe,EAAE,EACjC,IAAI,EAAE,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GACjD,EACF,KAAC,GAAG,IAAC,KAAK,EAAC,UAAU,EAAC,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAC,OAAO,GAAG,IAC7D,CACP,CAAC;AACJ,CAAC;AAID,SAAS,GAAG,CAAC,EACX,KAAK,EACL,KAAK,EACL,IAAI,GAKL;IACC,OAAO,CACL,eAAK,SAAS,EAAC,sDAAsD,aACnE,eAAM,SAAS,EAAC,0BAA0B,YAAE,KAAK,GAAQ,EACzD,eAAM,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,YAAG,KAAK,GAAQ,IACnD,CACP,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,CAAO;IACxB,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,OAAO,CAAC,CAAE,OAAO,sBAAsB,CAAC;QAC7C,KAAK,QAAQ,CAAC,CAAC,OAAO,qBAAqB,CAAC;QAC5C,KAAK,KAAK,CAAC,CAAI,OAAO,qBAAqB,CAAC;QAC5C,KAAK,OAAO,CAAC,CAAE,OAAO,+BAA+B,CAAC;IACxD,CAAC;AACH,CAAC;AAED,qEAAqE;AAErE,SAAS,OAAO,CAAC,CAAc;IAC7B,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,GAAG,IAAI;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,CAAc;IAChC,IAAI,CAAC,CAAC,cAAc,IAAI,GAAG;QAAE,OAAO,OAAO,CAAC;IAC5C,IAAI,CAAC,CAAC,cAAc,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,OAAO,CAAC,CAAc;IAC7B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC;IACrC,IAAI,CAAC,CAAC,aAAa,IAAI,SAAS,GAAG,GAAG;QAAE,OAAO,OAAO,CAAC;IACvD,IAAI,CAAC,CAAC,aAAa,IAAI,SAAS,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IACxD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,CAAc;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC,CAAC,eAAe,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,CAAC,eAAe,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,OAAO,CAAC,EAAU,EAAE,SAAiB;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,IAAI,EAAE,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IACjC,IAAI,EAAE,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const Stage: import("react").ForwardRefExoticComponent<import("react").RefAttributes<HTMLCanvasElement>>;
2
+ //# sourceMappingURL=Stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stage.d.ts","sourceRoot":"","sources":["../src/Stage.tsx"],"names":[],"mappings":"AAsDA,eAAO,MAAM,KAAK,6FA0chB,CAAC"}
package/dist/Stage.js ADDED
@@ -0,0 +1,406 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Stage — viewport for the rendered preview. Canvas displays at its
3
+ // natural source dimensions (1920 × 1080, 1080 × 1920, etc.) transformed
4
+ // by a zoom + pan applied to the wrapping div. Standard video-editor
5
+ // canvas behavior:
6
+ //
7
+ // - Wheel → zoom (centered on cursor)
8
+ // - Cmd/Ctrl + wheel → zoom (alt, also catches trackpad pinch)
9
+ // - Click + drag on background → pan
10
+ // - Space + click + drag → pan (always, even over clip overlays)
11
+ // - Zoom controls in the bottom-right corner
12
+ // - Fit-to-screen computed once on first viewport measurement
13
+ //
14
+ // Zoom + pan live in `ui.stageZoom` and `ui.stagePan` (Zustand). They
15
+ // don't go into history — pure viewport state.
16
+ import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState, } from 'react';
17
+ import { useEditor } from '@clipkit/editor-core';
18
+ import { useEditorContext } from '@clipkit/editor-core';
19
+ import { PerfHud } from './PerfHud.js';
20
+ import { useEditorStore } from '@clipkit/editor-core';
21
+ import { StageOverlay } from './StageOverlay.js';
22
+ import { MotionPathOverlay } from './MotionPathOverlay.js';
23
+ import { ZoomControl } from './frame/ZoomControl.js';
24
+ import { AddElementBar } from './frame/AddElementBar.js';
25
+ import { Breadcrumbs } from './frame/Breadcrumbs.js';
26
+ import { cn } from './lib/utils.js';
27
+ import { hitTest, screenToSource, boxSelect, resolveGroupPath } from '@clipkit/editor-core';
28
+ import { cameraGizmosActive, cameraHitTest } from './lib/camera-gizmo.js';
29
+ const VIEWPORT_PADDING = 32;
30
+ const MIN_ZOOM = 0.05;
31
+ const MAX_ZOOM = 16;
32
+ const ZOOM_STEP = 0.15;
33
+ // Wheel/trackpad zoom is per-event (and trackpads fire many events per gesture),
34
+ // so it gets a gentler step than the +/- buttons.
35
+ const WHEEL_ZOOM_STEP = 0.06;
36
+ const CLICK_VS_DRAG_THRESHOLD_PX = 4;
37
+ export const Stage = forwardRef(function Stage(_, ref) {
38
+ // Note on playback.time: we deliberately do NOT subscribe. It updates
39
+ // ~10×/sec during playback and Stage doesn't render anything that
40
+ // depends on it — the only consumer is the click-to-hit-test path,
41
+ // which reads the latest value via store.getState() on demand.
42
+ const { store } = useEditorContext();
43
+ const ready = useEditorStore((s) => s.playback.ready);
44
+ const error = useEditorStore((s) => s.playback.error);
45
+ const source = useEditorStore((s) => s.source);
46
+ const selection = useEditorStore((s) => s.selection);
47
+ // playback.duration changes only on source updates, not per frame.
48
+ const playbackDuration = useEditorStore((s) => s.playback.duration);
49
+ const playing = useEditorStore((s) => s.playback.playing);
50
+ const zoom = useEditorStore((s) => s.ui.stageZoom);
51
+ const pan = useEditorStore((s) => s.ui.stagePan);
52
+ const stageView = useEditorStore((s) => s.ui.stageView);
53
+ const tool = useEditorStore((s) => s.ui.tool);
54
+ const groupPath = useEditorStore((s) => s.ui.groupPath);
55
+ const _scope = resolveGroupPath(source.elements, groupPath);
56
+ const scopedElements = _scope.elements;
57
+ const groupOffset = _scope.timeOffset;
58
+ const groupPos = _scope.offset;
59
+ const { clearSelection, setSelection, selectOne, setUiState, pause, patchSource, pushHistory, setInteractive, flushPendingSource, } = useEditor();
60
+ const srcW = source.width ?? 1920;
61
+ const srcH = source.height ?? 1080;
62
+ const viewportRef = useRef(null);
63
+ const panRef = useRef({
64
+ panning: false,
65
+ startX: 0,
66
+ startY: 0,
67
+ startPan: { x: 0, y: 0 },
68
+ });
69
+ const spaceHeldRef = useRef(false);
70
+ // ── Fit-to-screen ────────────────────────────────────────────────
71
+ const fitToScreen = useCallback(() => {
72
+ const viewport = viewportRef.current;
73
+ if (!viewport)
74
+ return;
75
+ const vw = viewport.clientWidth - VIEWPORT_PADDING * 2;
76
+ const vh = viewport.clientHeight - VIEWPORT_PADDING * 2;
77
+ if (vw <= 0 || vh <= 0)
78
+ return;
79
+ const fitZoom = Math.min(vw / srcW, vh / srcH);
80
+ const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, fitZoom));
81
+ const centerX = (viewport.clientWidth - srcW * newZoom) / 2;
82
+ const centerY = (viewport.clientHeight - srcH * newZoom) / 2;
83
+ setUiState({ stageZoom: newZoom, stagePan: { x: centerX, y: centerY } });
84
+ }, [srcW, srcH, setUiState]);
85
+ // ── Initial auto-fit on mount (zoom=0 sentinel) ──────────────────
86
+ useLayoutEffect(() => {
87
+ if (zoom === 0)
88
+ fitToScreen();
89
+ // Refit if the source dimensions change (rare — happens on
90
+ // setSource to a different composition).
91
+ // eslint-disable-next-line react-hooks/exhaustive-deps
92
+ }, [srcW, srcH]);
93
+ // ── Wheel = zoom (cursor-centered) ──────────────────────────────
94
+ // Registered via a manual addEventListener with passive: false so
95
+ // we can call preventDefault inside (React's synthetic wheel handler
96
+ // is forced-passive and warns when you preventDefault). Reads zoom/
97
+ // pan via refs so the listener doesn't need to be re-attached on
98
+ // every state change.
99
+ const zoomLiveRef = useRef(zoom);
100
+ zoomLiveRef.current = zoom;
101
+ const panZoomLiveRef = useRef(pan);
102
+ panZoomLiveRef.current = pan;
103
+ useEffect(() => {
104
+ const viewport = viewportRef.current;
105
+ if (!viewport)
106
+ return;
107
+ const onWheel = (e) => {
108
+ e.preventDefault();
109
+ const currentZoom = zoomLiveRef.current;
110
+ const currentPan = panZoomLiveRef.current;
111
+ const rect = viewport.getBoundingClientRect();
112
+ const cx = e.clientX - rect.left;
113
+ const cy = e.clientY - rect.top;
114
+ const direction = -Math.sign(e.deltaY);
115
+ const factor = 1 + direction * WHEEL_ZOOM_STEP;
116
+ const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, (currentZoom || 1) * factor));
117
+ if (newZoom === currentZoom)
118
+ return;
119
+ const canvasPointX = (cx - currentPan.x) / (currentZoom || 1);
120
+ const canvasPointY = (cy - currentPan.y) / (currentZoom || 1);
121
+ setUiState({
122
+ stageZoom: newZoom,
123
+ stagePan: {
124
+ x: cx - canvasPointX * newZoom,
125
+ y: cy - canvasPointY * newZoom,
126
+ },
127
+ });
128
+ };
129
+ viewport.addEventListener('wheel', onWheel, { passive: false });
130
+ return () => {
131
+ viewport.removeEventListener('wheel', onWheel);
132
+ };
133
+ }, [setUiState]);
134
+ // ── Stay-centered on viewport resize ────────────────────────────
135
+ // When the viewport's size changes (Panel sliding in/out, JsonView
136
+ // toggling, window resize), shift pan by half the size delta. This
137
+ // keeps the source-space point that was at the viewport center
138
+ // before the resize at the viewport center after — so a centered
139
+ // canvas stays centered, and any intentional pan offset is
140
+ // preserved relative to the new center.
141
+ //
142
+ // Uses live refs for pan/zoom so the observer doesn't need to be
143
+ // re-attached on every state change.
144
+ useEffect(() => {
145
+ const viewport = viewportRef.current;
146
+ if (!viewport)
147
+ return;
148
+ let prevW = viewport.clientWidth;
149
+ let prevH = viewport.clientHeight;
150
+ const observer = new ResizeObserver(() => {
151
+ const w = viewport.clientWidth;
152
+ const h = viewport.clientHeight;
153
+ const dW = w - prevW;
154
+ const dH = h - prevH;
155
+ prevW = w;
156
+ prevH = h;
157
+ if (dW === 0 && dH === 0)
158
+ return;
159
+ // Zoom = 0 means "not yet fit-to-screen'd"; skip — the
160
+ // fit-to-screen effect will set the right pan once dims are
161
+ // known.
162
+ if (zoomLiveRef.current === 0)
163
+ return;
164
+ const currentPan = panZoomLiveRef.current;
165
+ setUiState({
166
+ stagePan: {
167
+ x: currentPan.x + dW / 2,
168
+ y: currentPan.y + dH / 2,
169
+ },
170
+ });
171
+ });
172
+ observer.observe(viewport);
173
+ return () => observer.disconnect();
174
+ }, [setUiState]);
175
+ // Keep a live ref to the current pan so the mousedown handler can
176
+ // capture it without binding a stale closure.
177
+ const panLiveRef = useRef(pan);
178
+ panLiveRef.current = pan;
179
+ const toolRef = useRef(tool);
180
+ toolRef.current = tool;
181
+ // Marquee box-select rectangle, in viewport (client-relative) px.
182
+ const [marquee, setMarquee] = useState(null);
183
+ // Live refs so closures inside listeners read fresh values.
184
+ const selectionLiveRef = useRef(selection);
185
+ selectionLiveRef.current = selection;
186
+ // ── Viewport mousedown — unified handler for pan vs click-select ──
187
+ //
188
+ // - Mousedown on viewport background or with space held →
189
+ // watch for movement. If the cursor moves > threshold, switch to
190
+ // pan mode and follow drag. If mouseup without crossing the
191
+ // threshold, treat as a click → hit-test, select/clear.
192
+ // - Mousedown on a selection box (handled by StageOverlay) →
193
+ // overlay stops propagation, so we never get here.
194
+ // Marquee box-select on the canvas (Select tool). Drag a rectangle over empty
195
+ // canvas → select every element whose box it covers (Shift adds). Coords are
196
+ // viewport-relative for the visual; corners convert to source space for the hit.
197
+ const startMarquee = (e) => {
198
+ const viewport = viewportRef.current;
199
+ if (!viewport)
200
+ return;
201
+ const rect = viewport.getBoundingClientRect();
202
+ const additive = e.shiftKey;
203
+ const base = additive ? selectionLiveRef.current : [];
204
+ const sx = e.clientX, sy = e.clientY;
205
+ const x0 = sx - rect.left, y0 = sy - rect.top;
206
+ setMarquee({ x0, y0, x1: x0, y1: y0 });
207
+ let moved = false;
208
+ const onMove = (ev) => {
209
+ const x1 = ev.clientX - rect.left, y1 = ev.clientY - rect.top;
210
+ if (Math.abs(x1 - x0) > CLICK_VS_DRAG_THRESHOLD_PX || Math.abs(y1 - y0) > CLICK_VS_DRAG_THRESHOLD_PX)
211
+ moved = true;
212
+ setMarquee({ x0, y0, x1, y1 });
213
+ };
214
+ const onUp = (ev) => {
215
+ window.removeEventListener('mousemove', onMove);
216
+ window.removeEventListener('mouseup', onUp);
217
+ setMarquee(null);
218
+ if (!moved) {
219
+ if (!additive)
220
+ clearSelection(); // plain click on empty = clear
221
+ return;
222
+ }
223
+ const z = zoom || 1;
224
+ const p0 = screenToSource(sx, sy, rect, z, panLiveRef.current);
225
+ const p1 = screenToSource(ev.clientX, ev.clientY, rect, z, panLiveRef.current);
226
+ const sourceDuration = playbackDuration > 0 ? playbackDuration : 1e9;
227
+ const t = store.getState().playback.time;
228
+ const hits = boxSelect(scopedElements, source, { x0: p0.x - groupPos.x, y0: p0.y - groupPos.y, x1: p1.x - groupPos.x, y1: p1.y - groupPos.y }, t - groupOffset, sourceDuration);
229
+ setSelection(additive ? [...new Set([...base, ...hits])] : hits);
230
+ };
231
+ window.addEventListener('mousemove', onMove);
232
+ window.addEventListener('mouseup', onUp);
233
+ };
234
+ const onMouseDown = (e) => {
235
+ const isMiddle = e.button === 1;
236
+ const isLeft = e.button === 0;
237
+ const onBackground = e.target === viewportRef.current;
238
+ const canPanOnly = isMiddle && !onBackground;
239
+ const canClickOrPan = isLeft && (onBackground || spaceHeldRef.current);
240
+ if (!isMiddle && !isLeft)
241
+ return;
242
+ if (!canPanOnly && !canClickOrPan)
243
+ return;
244
+ e.preventDefault();
245
+ // Playing → left-click pauses (unless space is held, in which
246
+ // case the user is panning the viewport, not interacting with
247
+ // content). Skips the hit-test/selection logic below; the user
248
+ // gets a second click to actually select once paused.
249
+ if (isLeft && playing && !spaceHeldRef.current) {
250
+ pause();
251
+ return;
252
+ }
253
+ // Select tool: left-drag on empty canvas marquees instead of panning. Space
254
+ // still pans (temporary hand), and the Hand tool falls through to the pan
255
+ // path below.
256
+ if (isLeft && onBackground && !spaceHeldRef.current && toolRef.current === 'select') {
257
+ startMarquee(e);
258
+ return;
259
+ }
260
+ const startX = e.clientX;
261
+ const startY = e.clientY;
262
+ const startPan = { ...panLiveRef.current };
263
+ let dragging = false;
264
+ const onMove = (ev) => {
265
+ const dx = ev.clientX - startX;
266
+ const dy = ev.clientY - startY;
267
+ if (!dragging) {
268
+ if (dx * dx + dy * dy < CLICK_VS_DRAG_THRESHOLD_PX ** 2)
269
+ return;
270
+ dragging = true;
271
+ panRef.current.panning = true;
272
+ }
273
+ setUiState({
274
+ stagePan: { x: startPan.x + dx, y: startPan.y + dy },
275
+ });
276
+ };
277
+ const onUp = (ev) => {
278
+ window.removeEventListener('mousemove', onMove);
279
+ window.removeEventListener('mouseup', onUp);
280
+ panRef.current.panning = false;
281
+ if (dragging)
282
+ return;
283
+ // It was a click — hit-test against active elements.
284
+ const viewport = viewportRef.current;
285
+ if (!viewport || !isLeft || spaceHeldRef.current)
286
+ return;
287
+ const rect = viewport.getBoundingClientRect();
288
+ const sourceDuration = playbackDuration > 0 ? playbackDuration : 1e9;
289
+ const t = store.getState().playback.time;
290
+ // Camera view: hit-test against the elements' PROJECTED quads so a
291
+ // click selects what's actually on top under the camera.
292
+ const hit = cameraGizmosActive(source, stageView)
293
+ ? cameraHitTest(source, {
294
+ x: (ev.clientX - rect.left - pan.x) / (zoom || 1),
295
+ y: (ev.clientY - rect.top - pan.y) / (zoom || 1),
296
+ }, t, sourceDuration)
297
+ : (() => {
298
+ const p = screenToSource(ev.clientX, ev.clientY, rect, zoom, pan);
299
+ return hitTest(scopedElements, source, { x: p.x - groupPos.x, y: p.y - groupPos.y }, t - groupOffset, sourceDuration);
300
+ })();
301
+ if (hit?.id) {
302
+ if (ev.shiftKey) {
303
+ const sel = selectionLiveRef.current;
304
+ if (sel.includes(hit.id)) {
305
+ setSelection(sel.filter((s) => s !== hit.id));
306
+ }
307
+ else {
308
+ setSelection([...sel, hit.id]);
309
+ }
310
+ }
311
+ else {
312
+ selectOne(hit.id);
313
+ }
314
+ }
315
+ else {
316
+ clearSelection();
317
+ }
318
+ };
319
+ window.addEventListener('mousemove', onMove);
320
+ window.addEventListener('mouseup', onUp);
321
+ };
322
+ // ── Space key tracking (hold space + drag to pan over anything) ─
323
+ useEffect(() => {
324
+ const onKeyDown = (e) => {
325
+ if (e.code === 'Space' && !isTypingTarget(e.target)) {
326
+ spaceHeldRef.current = true;
327
+ if (viewportRef.current)
328
+ viewportRef.current.style.cursor = 'grab';
329
+ }
330
+ };
331
+ const onKeyUp = (e) => {
332
+ if (e.code === 'Space') {
333
+ spaceHeldRef.current = false;
334
+ if (viewportRef.current)
335
+ viewportRef.current.style.cursor = '';
336
+ }
337
+ };
338
+ window.addEventListener('keydown', onKeyDown);
339
+ window.addEventListener('keyup', onKeyUp);
340
+ return () => {
341
+ window.removeEventListener('keydown', onKeyDown);
342
+ window.removeEventListener('keyup', onKeyUp);
343
+ };
344
+ }, []);
345
+ // ── Zoom controls ───────────────────────────────────────────────
346
+ const zoomBy = (factor) => {
347
+ const viewport = viewportRef.current;
348
+ if (!viewport)
349
+ return;
350
+ const rect = viewport.getBoundingClientRect();
351
+ const cx = rect.width / 2;
352
+ const cy = rect.height / 2;
353
+ const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, (zoom || 1) * factor));
354
+ if (newZoom === zoom)
355
+ return;
356
+ const canvasPointX = (cx - pan.x) / (zoom || 1);
357
+ const canvasPointY = (cy - pan.y) / (zoom || 1);
358
+ setUiState({
359
+ stageZoom: newZoom,
360
+ stagePan: {
361
+ x: cx - canvasPointX * newZoom,
362
+ y: cy - canvasPointY * newZoom,
363
+ },
364
+ });
365
+ };
366
+ const effectiveZoom = zoom || 1;
367
+ const canvasStyle = {
368
+ position: 'absolute',
369
+ left: pan.x,
370
+ top: pan.y,
371
+ width: srcW * effectiveZoom,
372
+ height: srcH * effectiveZoom,
373
+ background: '#000',
374
+ boxShadow: '0 8px 40px rgba(0,0,0,0.5)',
375
+ borderRadius: 4,
376
+ cursor: spaceHeldRef.current ? 'grab' : 'default',
377
+ // Let clicks pass through to the viewport so the unified pan-vs-click
378
+ // handler runs. Without this, e.target is the canvas, onBackground
379
+ // is false, and Stage's onMouseDown early-returns — so clicks on the
380
+ // canvas (including on rendered elements) never selected anything.
381
+ pointerEvents: 'none',
382
+ };
383
+ return (_jsx("div", { className: "flex-1 flex flex-col min-h-0 min-w-0 bg-stage overflow-hidden", children: _jsxs("div", { ref: viewportRef, className: "relative flex-1 min-h-0 min-w-0 overflow-hidden", onMouseDown: onMouseDown, style: {
384
+ cursor: tool === 'hand' ? 'grab' : 'default',
385
+ // CSS vars (defined in styles.css) flip per theme so the
386
+ // checker pattern adapts to light mode without re-rendering.
387
+ backgroundImage: 'repeating-conic-gradient(var(--color-stage-checker-a) 0% 25%, var(--color-stage-checker-b) 0% 50%)',
388
+ backgroundSize: '24px 24px',
389
+ }, children: [_jsx("canvas", { ref: ref, style: canvasStyle }), _jsx(StageOverlay, { viewportRef: viewportRef }), _jsx(MotionPathOverlay, { viewportRef: viewportRef }), _jsx(PerfHud, {}), marquee && (_jsx("div", { className: "absolute pointer-events-none border border-primary bg-primary/10 z-10", style: {
390
+ left: Math.min(marquee.x0, marquee.x1),
391
+ top: Math.min(marquee.y0, marquee.y1),
392
+ width: Math.abs(marquee.x1 - marquee.x0),
393
+ height: Math.abs(marquee.y1 - marquee.y0),
394
+ } })), !ready && !error && (_jsx("div", { className: "absolute inset-0 grid place-items-center text-muted-foreground text-sm pointer-events-none", children: "Initializing\u2026" })), error && (_jsx("div", { className: "absolute inset-0 grid place-items-center text-destructive text-sm p-6 text-center pointer-events-none", children: error })), _jsxs("div", { className: "absolute bottom-3 left-3 z-10 flex flex-col gap-1 items-start", children: [source.camera && (_jsx("div", { className: "flex items-center gap-0.5 bg-background/90 backdrop-blur-sm border border-border rounded-md p-0.5", children: ['flat', 'camera'].map((v) => (_jsx("button", { type: "button", className: cn('h-6 px-2 rounded-sm text-[10px] font-medium capitalize transition-colors', stageView === v
395
+ ? 'text-foreground bg-secondary'
396
+ : 'text-muted-foreground hover:text-foreground hover:bg-secondary/60'), onClick: () => setUiState({ stageView: v }), "aria-pressed": stageView === v, title: v === 'flat'
397
+ ? 'Flat view — ignore the camera (orthographic, for editing)'
398
+ : 'Camera view — render through the scene camera', children: v }, v))) })), _jsx(Breadcrumbs, {})] }), _jsx("div", { className: "absolute bottom-3 right-3 bg-background/90 backdrop-blur-sm border border-border rounded-md px-0.5 py-0.5", children: _jsx(ZoomControl, { readout: `${Math.round(effectiveZoom * 100)}%`, onZoomOut: () => zoomBy(1 - ZOOM_STEP), onZoomIn: () => zoomBy(1 + ZOOM_STEP), onFit: fitToScreen, fitLabel: "Fit to screen" }) }), _jsx(AddElementBar, {})] }) }));
399
+ });
400
+ function isTypingTarget(target) {
401
+ if (!(target instanceof HTMLElement))
402
+ return false;
403
+ const tag = target.tagName;
404
+ return tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable;
405
+ }
406
+ //# sourceMappingURL=Stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stage.js","sourceRoot":"","sources":["../src/Stage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type RefObject } from 'react';
2
+ interface Props {
3
+ viewportRef: RefObject<HTMLDivElement | null>;
4
+ }
5
+ export declare function StageOverlay({ viewportRef }: Props): import("react").JSX.Element | null;
6
+ export {};
7
+ //# sourceMappingURL=StageOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StageOverlay.d.ts","sourceRoot":"","sources":["../src/StageOverlay.tsx"],"names":[],"mappings":"AAeA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA+Bf,UAAU,KAAK;IACb,WAAW,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC/C;AAqDD,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,EAAE,KAAK,sCAwlBlD"}