@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.
- package/LICENSE +201 -0
- package/README.md +51 -0
- package/dist/Editor.d.ts +3 -0
- package/dist/Editor.d.ts.map +1 -0
- package/dist/Editor.js +73 -0
- package/dist/Editor.js.map +1 -0
- package/dist/ExportDialog.d.ts +12 -0
- package/dist/ExportDialog.d.ts.map +1 -0
- package/dist/ExportDialog.js +30 -0
- package/dist/ExportDialog.js.map +1 -0
- package/dist/MotionPathOverlay.d.ts +5 -0
- package/dist/MotionPathOverlay.d.ts.map +1 -0
- package/dist/MotionPathOverlay.js +156 -0
- package/dist/MotionPathOverlay.js.map +1 -0
- package/dist/PerfHud.d.ts +2 -0
- package/dist/PerfHud.d.ts.map +1 -0
- package/dist/PerfHud.js +85 -0
- package/dist/PerfHud.js.map +1 -0
- package/dist/Stage.d.ts +2 -0
- package/dist/Stage.d.ts.map +1 -0
- package/dist/Stage.js +406 -0
- package/dist/Stage.js.map +1 -0
- package/dist/StageOverlay.d.ts +7 -0
- package/dist/StageOverlay.d.ts.map +1 -0
- package/dist/StageOverlay.js +508 -0
- package/dist/StageOverlay.js.map +1 -0
- package/dist/commands.d.ts +18 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +103 -0
- package/dist/commands.js.map +1 -0
- package/dist/configuration.d.ts +9 -0
- package/dist/configuration.d.ts.map +1 -0
- package/dist/configuration.js +21 -0
- package/dist/configuration.js.map +1 -0
- package/dist/controls/AnimationsStack.d.ts +8 -0
- package/dist/controls/AnimationsStack.d.ts.map +1 -0
- package/dist/controls/AnimationsStack.js +188 -0
- package/dist/controls/AnimationsStack.js.map +1 -0
- package/dist/controls/CameraControl.d.ts +19 -0
- package/dist/controls/CameraControl.d.ts.map +1 -0
- package/dist/controls/CameraControl.js +47 -0
- package/dist/controls/CameraControl.js.map +1 -0
- package/dist/controls/CaptionLengthControl.d.ts +5 -0
- package/dist/controls/CaptionLengthControl.d.ts.map +1 -0
- package/dist/controls/CaptionLengthControl.js +11 -0
- package/dist/controls/CaptionLengthControl.js.map +1 -0
- package/dist/controls/CaptionTranscribe.d.ts +2 -0
- package/dist/controls/CaptionTranscribe.d.ts.map +1 -0
- package/dist/controls/CaptionTranscribe.js +95 -0
- package/dist/controls/CaptionTranscribe.js.map +1 -0
- package/dist/controls/ColorPicker.d.ts +17 -0
- package/dist/controls/ColorPicker.d.ts.map +1 -0
- package/dist/controls/ColorPicker.js +354 -0
- package/dist/controls/ColorPicker.js.map +1 -0
- package/dist/controls/ControlRenderer.d.ts +20 -0
- package/dist/controls/ControlRenderer.d.ts.map +1 -0
- package/dist/controls/ControlRenderer.js +106 -0
- package/dist/controls/ControlRenderer.js.map +1 -0
- package/dist/controls/CropControl.d.ts +2 -0
- package/dist/controls/CropControl.d.ts.map +1 -0
- package/dist/controls/CropControl.js +177 -0
- package/dist/controls/CropControl.js.map +1 -0
- package/dist/controls/EffectsStack.d.ts +8 -0
- package/dist/controls/EffectsStack.d.ts.map +1 -0
- package/dist/controls/EffectsStack.js +89 -0
- package/dist/controls/EffectsStack.js.map +1 -0
- package/dist/controls/GradeControl.d.ts +2 -0
- package/dist/controls/GradeControl.d.ts.map +1 -0
- package/dist/controls/GradeControl.js +120 -0
- package/dist/controls/GradeControl.js.map +1 -0
- package/dist/controls/KeyframeDiamond.d.ts +11 -0
- package/dist/controls/KeyframeDiamond.d.ts.map +1 -0
- package/dist/controls/KeyframeDiamond.js +87 -0
- package/dist/controls/KeyframeDiamond.js.map +1 -0
- package/dist/controls/LightingControls.d.ts +24 -0
- package/dist/controls/LightingControls.d.ts.map +1 -0
- package/dist/controls/LightingControls.js +108 -0
- package/dist/controls/LightingControls.js.map +1 -0
- package/dist/controls/ShapePresetControl.d.ts +4 -0
- package/dist/controls/ShapePresetControl.d.ts.map +1 -0
- package/dist/controls/ShapePresetControl.js +30 -0
- package/dist/controls/ShapePresetControl.js.map +1 -0
- package/dist/controls/ValueField.d.ts +10 -0
- package/dist/controls/ValueField.d.ts.map +1 -0
- package/dist/controls/ValueField.js +158 -0
- package/dist/controls/ValueField.js.map +1 -0
- package/dist/controls/VolumeControl.d.ts +10 -0
- package/dist/controls/VolumeControl.d.ts.map +1 -0
- package/dist/controls/VolumeControl.js +75 -0
- package/dist/controls/VolumeControl.js.map +1 -0
- package/dist/controls/compound.d.ts +46 -0
- package/dist/controls/compound.d.ts.map +1 -0
- package/dist/controls/compound.js +160 -0
- package/dist/controls/compound.js.map +1 -0
- package/dist/controls/layout.d.ts +38 -0
- package/dist/controls/layout.d.ts.map +1 -0
- package/dist/controls/layout.js +162 -0
- package/dist/controls/layout.js.map +1 -0
- package/dist/controls/primitives.d.ts +83 -0
- package/dist/controls/primitives.d.ts.map +1 -0
- package/dist/controls/primitives.js +194 -0
- package/dist/controls/primitives.js.map +1 -0
- package/dist/controls/transcribe.worker.d.ts +2 -0
- package/dist/controls/transcribe.worker.d.ts.map +1 -0
- package/dist/controls/transcribe.worker.js +22 -0
- package/dist/controls/transcribe.worker.js.map +1 -0
- package/dist/frame/AddElementBar.d.ts +2 -0
- package/dist/frame/AddElementBar.d.ts.map +1 -0
- package/dist/frame/AddElementBar.js +103 -0
- package/dist/frame/AddElementBar.js.map +1 -0
- package/dist/frame/Breadcrumbs.d.ts +2 -0
- package/dist/frame/Breadcrumbs.d.ts.map +1 -0
- package/dist/frame/Breadcrumbs.js +32 -0
- package/dist/frame/Breadcrumbs.js.map +1 -0
- package/dist/frame/GroupFlash.d.ts +2 -0
- package/dist/frame/GroupFlash.d.ts.map +1 -0
- package/dist/frame/GroupFlash.js +65 -0
- package/dist/frame/GroupFlash.js.map +1 -0
- package/dist/frame/Resizable.d.ts +12 -0
- package/dist/frame/Resizable.d.ts.map +1 -0
- package/dist/frame/Resizable.js +37 -0
- package/dist/frame/Resizable.js.map +1 -0
- package/dist/frame/Section.d.ts +23 -0
- package/dist/frame/Section.d.ts.map +1 -0
- package/dist/frame/Section.js +23 -0
- package/dist/frame/Section.js.map +1 -0
- package/dist/frame/ZoomControl.d.ts +9 -0
- package/dist/frame/ZoomControl.d.ts.map +1 -0
- package/dist/frame/ZoomControl.js +15 -0
- package/dist/frame/ZoomControl.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/camera-gizmo.d.ts +15 -0
- package/dist/lib/camera-gizmo.d.ts.map +1 -0
- package/dist/lib/camera-gizmo.js +57 -0
- package/dist/lib/camera-gizmo.js.map +1 -0
- package/dist/lib/camera-tool.d.ts +43 -0
- package/dist/lib/camera-tool.d.ts.map +1 -0
- package/dist/lib/camera-tool.js +80 -0
- package/dist/lib/camera-tool.js.map +1 -0
- package/dist/lib/caption-segments.d.ts +17 -0
- package/dist/lib/caption-segments.d.ts.map +1 -0
- package/dist/lib/caption-segments.js +50 -0
- package/dist/lib/caption-segments.js.map +1 -0
- package/dist/lib/group.d.ts +12 -0
- package/dist/lib/group.d.ts.map +1 -0
- package/dist/lib/group.js +61 -0
- package/dist/lib/group.js.map +1 -0
- package/dist/lib/keyframes.d.ts +29 -0
- package/dist/lib/keyframes.d.ts.map +1 -0
- package/dist/lib/keyframes.js +92 -0
- package/dist/lib/keyframes.js.map +1 -0
- package/dist/lib/sfx-preview.d.ts +18 -0
- package/dist/lib/sfx-preview.d.ts.map +1 -0
- package/dist/lib/sfx-preview.js +74 -0
- package/dist/lib/sfx-preview.js.map +1 -0
- package/dist/lib/shape-presets.d.ts +35 -0
- package/dist/lib/shape-presets.d.ts.map +1 -0
- package/dist/lib/shape-presets.js +81 -0
- package/dist/lib/shape-presets.js.map +1 -0
- package/dist/lib/ungroup.d.ts +12 -0
- package/dist/lib/ungroup.d.ts.map +1 -0
- package/dist/lib/ungroup.js +40 -0
- package/dist/lib/ungroup.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/panels/AssetsPanel.d.ts +2 -0
- package/dist/panels/AssetsPanel.d.ts.map +1 -0
- package/dist/panels/AssetsPanel.js +108 -0
- package/dist/panels/AssetsPanel.js.map +1 -0
- package/dist/panels/InspectorPanel.d.ts +2 -0
- package/dist/panels/InspectorPanel.d.ts.map +1 -0
- package/dist/panels/InspectorPanel.js +286 -0
- package/dist/panels/InspectorPanel.js.map +1 -0
- package/dist/panels/InterpolationPanel.d.ts +2 -0
- package/dist/panels/InterpolationPanel.d.ts.map +1 -0
- package/dist/panels/InterpolationPanel.js +226 -0
- package/dist/panels/InterpolationPanel.js.map +1 -0
- package/dist/panels/LayersTree.d.ts +4 -0
- package/dist/panels/LayersTree.d.ts.map +1 -0
- package/dist/panels/LayersTree.js +137 -0
- package/dist/panels/LayersTree.js.map +1 -0
- package/dist/panels/LeftRail.d.ts +6 -0
- package/dist/panels/LeftRail.d.ts.map +1 -0
- package/dist/panels/LeftRail.js +35 -0
- package/dist/panels/LeftRail.js.map +1 -0
- package/dist/panels/SourcePanel.d.ts +2 -0
- package/dist/panels/SourcePanel.d.ts.map +1 -0
- package/dist/panels/SourcePanel.js +470 -0
- package/dist/panels/SourcePanel.js.map +1 -0
- package/dist/panels/TimelinePanel.d.ts +11 -0
- package/dist/panels/TimelinePanel.d.ts.map +1 -0
- package/dist/panels/TimelinePanel.js +98 -0
- package/dist/panels/TimelinePanel.js.map +1 -0
- package/dist/panels/assets/SfxBrowser.d.ts +2 -0
- package/dist/panels/assets/SfxBrowser.d.ts.map +1 -0
- package/dist/panels/assets/SfxBrowser.js +49 -0
- package/dist/panels/assets/SfxBrowser.js.map +1 -0
- package/dist/panels/assets/use-assets.d.ts +11 -0
- package/dist/panels/assets/use-assets.d.ts.map +1 -0
- package/dist/panels/assets/use-assets.js +84 -0
- package/dist/panels/assets/use-assets.js.map +1 -0
- package/dist/panels/assets/use-sfx.d.ts +6 -0
- package/dist/panels/assets/use-sfx.d.ts.map +1 -0
- package/dist/panels/assets/use-sfx.js +47 -0
- package/dist/panels/assets/use-sfx.js.map +1 -0
- package/dist/panels/timeline/CanvasTimeline.d.ts +7 -0
- package/dist/panels/timeline/CanvasTimeline.d.ts.map +1 -0
- package/dist/panels/timeline/CanvasTimeline.js +1536 -0
- package/dist/panels/timeline/CanvasTimeline.js.map +1 -0
- package/dist/panels/timeline/Clip.d.ts +37 -0
- package/dist/panels/timeline/Clip.d.ts.map +1 -0
- package/dist/panels/timeline/Clip.js +176 -0
- package/dist/panels/timeline/Clip.js.map +1 -0
- package/dist/panels/timeline/CurveEditor.d.ts +2 -0
- package/dist/panels/timeline/CurveEditor.d.ts.map +1 -0
- package/dist/panels/timeline/CurveEditor.js +233 -0
- package/dist/panels/timeline/CurveEditor.js.map +1 -0
- package/dist/panels/timeline/MixerRail.d.ts +7 -0
- package/dist/panels/timeline/MixerRail.d.ts.map +1 -0
- package/dist/panels/timeline/MixerRail.js +295 -0
- package/dist/panels/timeline/MixerRail.js.map +1 -0
- package/dist/panels/timeline/Waveform.d.ts +11 -0
- package/dist/panels/timeline/Waveform.d.ts.map +1 -0
- package/dist/panels/timeline/Waveform.js +63 -0
- package/dist/panels/timeline/Waveform.js.map +1 -0
- package/dist/panels/timeline/clip-style.d.ts +10 -0
- package/dist/panels/timeline/clip-style.d.ts.map +1 -0
- package/dist/panels/timeline/clip-style.js +20 -0
- package/dist/panels/timeline/clip-style.js.map +1 -0
- package/dist/panels/timeline/filmstrip.d.ts +7 -0
- package/dist/panels/timeline/filmstrip.d.ts.map +1 -0
- package/dist/panels/timeline/filmstrip.js +135 -0
- package/dist/panels/timeline/filmstrip.js.map +1 -0
- package/dist/panels/timeline/timeline-layout.d.ts +65 -0
- package/dist/panels/timeline/timeline-layout.d.ts.map +1 -0
- package/dist/panels/timeline/timeline-layout.js +118 -0
- package/dist/panels/timeline/timeline-layout.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
- package/src/styles.css +185 -0
package/dist/PerfHud.js
ADDED
|
@@ -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":"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"}
|
package/dist/Stage.d.ts
ADDED
|
@@ -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"}
|