@dailies-studio/shot-editor 0.1.0 → 0.2.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/dist/.vite/manifest.json +382 -0
- package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
- package/dist/assets/AgentPanel-DJEphah0.css +1 -0
- package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
- package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
- package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
- package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
- package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
- package/dist/assets/CurvePane-BjFVabKX.css +1 -0
- package/dist/assets/CurvePane-R22WzllJ.js +1 -0
- package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
- package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
- package/dist/assets/FontPicker-v0IOIArM.css +1 -0
- package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
- package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
- package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
- package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
- package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
- package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
- package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
- package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
- package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
- package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
- package/dist/assets/SoundMode-BmcZru3i.js +3 -0
- package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
- package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
- package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
- package/dist/assets/board-B88EPuLO.css +1 -0
- package/dist/assets/board-CL-he7SL.js +3 -0
- package/dist/assets/components-0oOSPN0l.js +1 -0
- package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
- package/dist/assets/googleFonts-BNon6M7X.js +1 -0
- package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
- package/dist/assets/index-4F5NQmI8.css +1 -0
- package/dist/assets/index-BGHQGV5z.js +117 -0
- package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/assets/libraryModel-CpIwfFha.js +1 -0
- package/dist/assets/lucide-6iK64tTB.js +9319 -0
- package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
- package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
- package/dist/assets/webmcp-BsB9gxWC.js +2 -0
- package/dist/index.html +34 -3
- package/package.json +12 -9
- package/src/addFamilies.ts +66 -0
- package/src/api.ts +1631 -55
- package/src/app/App.tsx +977 -198
- package/src/app/lazyPanel.tsx +137 -0
- package/src/app/lazySurfaces.tsx +203 -0
- package/src/audio/index.tsx +41 -10
- package/src/audio/meter.ts +485 -0
- package/src/audio/meterMath.ts +273 -0
- package/src/audio/meterStore.ts +155 -0
- package/src/audio/offlineMix.ts +289 -0
- package/src/audio/preview.ts +928 -118
- package/src/bridge.ts +15 -5
- package/src/bridgeTypes.ts +1611 -36
- package/src/channels.ts +17 -32
- package/src/fonts/googleFonts.ts +4 -0
- package/src/hostApi.ts +174 -0
- package/src/icons.tsx +770 -0
- package/src/layerWords.ts +61 -0
- package/src/main.tsx +56 -4
- package/src/panels/ResizeHandle.tsx +33 -43
- package/src/panels/agent/AgentDots.tsx +36 -0
- package/src/panels/agent/AgentPanel.tsx +119 -43
- package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
- package/src/panels/agent/agent.css +113 -97
- package/src/panels/agent/agentGate.ts +35 -0
- package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
- package/src/panels/code/CodeStudio.tsx +373 -0
- package/src/panels/code/FileTree.tsx +265 -0
- package/src/panels/code/codeBufferGuard.ts +52 -0
- package/src/panels/code/codeParts.tsx +321 -0
- package/src/panels/comments/CommentComposer.tsx +239 -0
- package/src/panels/comments/CommentThread.tsx +346 -0
- package/src/panels/comments/CommentsPanel.tsx +336 -0
- package/src/panels/comments/InboxButton.tsx +131 -0
- package/src/panels/comments/MentionMenu.tsx +98 -0
- package/src/panels/comments/parts.tsx +171 -0
- package/src/panels/export/ExportDialog.tsx +919 -96
- package/src/panels/export/ExportScrim.tsx +57 -0
- package/src/panels/files/AssetsTab.tsx +656 -0
- package/src/panels/files/FilePanel.tsx +1466 -216
- package/src/panels/files/LayerMarks.tsx +40 -0
- package/src/panels/files/LeftColumn.tsx +37 -0
- package/src/panels/files/McpSection.tsx +690 -47
- package/src/panels/files/MissingAssetsNotice.tsx +60 -0
- package/src/panels/files/assetDrag.ts +79 -0
- package/src/panels/files/resourceParts.tsx +255 -0
- package/src/panels/fonts/FontPicker.tsx +762 -0
- package/src/panels/fonts/faceCache.ts +207 -0
- package/src/panels/fonts/fontPicker.css +271 -0
- package/src/panels/fonts/pickerModel.ts +265 -0
- package/src/panels/fonts/pickerRequest.ts +46 -0
- package/src/panels/header/AccountAvatar.tsx +76 -0
- package/src/panels/header/AgentChip.tsx +77 -0
- package/src/panels/header/AppMenu.tsx +213 -0
- package/src/panels/header/Header.tsx +564 -84
- package/src/panels/header/HistoryControls.tsx +31 -5
- package/src/panels/header/PresenceStack.tsx +329 -0
- package/src/panels/header/ProjectTitle.tsx +232 -0
- package/src/panels/header/ShareButton.tsx +59 -0
- package/src/panels/header/StatusBadges.tsx +358 -27
- package/src/panels/header/SyncDeletedDialog.tsx +88 -0
- package/src/panels/header/ZoomControls.tsx +46 -15
- package/src/panels/header/agentHandoff.ts +52 -0
- package/src/panels/header/leave.ts +26 -0
- package/src/panels/help/HelpSection.tsx +189 -163
- package/src/panels/insert/InsertDrawer.tsx +723 -0
- package/src/panels/insert/iconSet.ts +109 -0
- package/src/panels/inspector/ExposeDot.tsx +117 -0
- package/src/panels/inspector/FramingRows.tsx +314 -44
- package/src/panels/inspector/InspectorFooter.tsx +91 -0
- package/src/panels/inspector/InspectorHead.tsx +425 -0
- package/src/panels/inspector/InspectorPanel.tsx +408 -124
- package/src/panels/inspector/KeyframeDot.tsx +373 -0
- package/src/panels/inspector/KeyframeSection.tsx +257 -0
- package/src/panels/inspector/MarkerSection.tsx +55 -11
- package/src/panels/inspector/ParamRow.tsx +84 -53
- package/src/panels/inspector/RightColumn.tsx +152 -0
- package/src/panels/inspector/TimeSection.tsx +866 -0
- package/src/panels/inspector/animate/EaseControl.tsx +244 -0
- package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
- package/src/panels/inspector/animate/ShotSection.tsx +562 -48
- package/src/panels/inspector/design/AlignRow.tsx +95 -31
- package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
- package/src/panels/inspector/design/ClonerSection.tsx +323 -62
- package/src/panels/inspector/design/ComponentSection.tsx +50 -43
- package/src/panels/inspector/design/CornerSection.tsx +45 -14
- package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
- package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
- package/src/panels/inspector/design/DeviceSection.tsx +210 -0
- package/src/panels/inspector/design/FillSection.tsx +83 -51
- package/src/panels/inspector/design/FontField.tsx +196 -0
- package/src/panels/inspector/design/HtmlSection.tsx +23 -12
- package/src/panels/inspector/design/InstanceSection.tsx +373 -154
- package/src/panels/inspector/design/MaskSection.tsx +84 -0
- package/src/panels/inspector/design/MaterialSection.tsx +177 -0
- package/src/panels/inspector/design/MediaSection.tsx +273 -120
- package/src/panels/inspector/design/MeshSection.tsx +910 -82
- package/src/panels/inspector/design/PaintRows.tsx +550 -0
- package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
- package/src/panels/inspector/design/ShadowSection.tsx +221 -48
- package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
- package/src/panels/inspector/design/StrokeSection.tsx +228 -43
- package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
- package/src/panels/inspector/design/TransformSection.tsx +244 -50
- package/src/panels/inspector/design/TypographySection.tsx +679 -110
- package/src/panels/inspector/layout.ts +295 -0
- package/src/panels/inspector/propValue.ts +199 -0
- package/src/panels/inspector/scene/CameraSection.tsx +232 -22
- package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
- package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
- package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
- package/src/panels/inspector/scene/SceneSection.tsx +219 -44
- package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
- package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
- package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
- package/src/panels/inspector/timeModel.ts +190 -0
- package/src/panels/inspector/useDocWrite.ts +438 -146
- package/src/panels/library/LibraryBrowser.tsx +435 -0
- package/src/panels/library/LibraryGrid.tsx +190 -0
- package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
- package/src/panels/library/LibraryRail.tsx +84 -0
- package/src/panels/library/LibrarySoundPanel.tsx +293 -0
- package/src/panels/library/SoundHistory.tsx +245 -0
- package/src/panels/library/StockSounds.tsx +390 -0
- package/src/panels/library/libraryModel.ts +147 -0
- package/src/panels/library/stockSearch.ts +77 -0
- package/src/panels/maskMarks.tsx +117 -0
- package/src/panels/material/MaterialCommentNode.tsx +54 -0
- package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
- package/src/panels/material/MaterialGraphMenu.tsx +45 -0
- package/src/panels/material/MaterialGroupNode.tsx +56 -0
- package/src/panels/material/MaterialLibrary.tsx +253 -0
- package/src/panels/material/MaterialNode.tsx +453 -0
- package/src/panels/material/MaterialNodePalette.tsx +349 -0
- package/src/panels/material/MaterialParameterControls.tsx +525 -0
- package/src/panels/material/MaterialRerouteNode.tsx +42 -0
- package/src/panels/material/MaterialWorkspace.tsx +501 -0
- package/src/panels/material/NodePreview.tsx +70 -0
- package/src/panels/material/flowModel.ts +441 -0
- package/src/panels/material/parameterValues.ts +231 -0
- package/src/panels/material/previewScheduler.ts +235 -0
- package/src/panels/material/reactFlow.css +6 -0
- package/src/panels/material/socketGlyph.ts +85 -0
- package/src/panels/material/viewportMemory.ts +58 -0
- package/src/panels/preferences/PreferencesDialog.tsx +215 -0
- package/src/panels/share/ShareComponentDialog.tsx +247 -0
- package/src/panels/stage/StageMenu.tsx +35 -5
- package/src/panels/stage/StagePanel.tsx +338 -23
- package/src/panels/stage/cellSlots.tsx +70 -0
- package/src/panels/storyboard/BoardCanvas.tsx +739 -0
- package/src/panels/storyboard/BoardCursors.tsx +158 -0
- package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
- package/src/panels/storyboard/BoardPlan.tsx +42 -0
- package/src/panels/storyboard/ComponentSheet.tsx +187 -0
- package/src/panels/storyboard/ComponentStage.tsx +235 -0
- package/src/panels/storyboard/MiniSketch.tsx +173 -0
- package/src/panels/storyboard/PartPicker.tsx +64 -0
- package/src/panels/storyboard/PlanPanel.tsx +617 -0
- package/src/panels/storyboard/ReferencePreview.tsx +217 -0
- package/src/panels/storyboard/ShotBrief.tsx +360 -0
- package/src/panels/storyboard/ShotCard.tsx +251 -0
- package/src/panels/storyboard/StagePreview.tsx +348 -0
- package/src/panels/storyboard/StillThumbs.tsx +162 -0
- package/src/panels/storyboard/StoryboardView.tsx +79 -0
- package/src/panels/storyboard/board.css +1065 -0
- package/src/panels/storyboard/board.ts +12 -0
- package/src/panels/storyboard/boardClipboard.ts +111 -0
- package/src/panels/storyboard/boardOrder.ts +68 -0
- package/src/panels/storyboard/boardRows.tsx +425 -0
- package/src/panels/storyboard/liveCap.ts +90 -0
- package/src/panels/storyboard/plan.css +295 -0
- package/src/panels/storyboard/posterCache.ts +133 -0
- package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
- package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
- package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
- package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
- package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
- package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
- package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
- package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
- package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
- package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
- package/src/panels/storyboard/shotboard/sketch.css +1392 -0
- package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
- package/src/panels/storyboard/storyboardDrop.ts +164 -0
- package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
- package/src/panels/studio/ComponentSidePanel.tsx +355 -0
- package/src/panels/studio/ComponentStudio.tsx +243 -0
- package/src/panels/studio/ComponentsHome.tsx +318 -0
- package/src/panels/studio/ComponentsPreview.tsx +179 -0
- package/src/panels/studio/EveryUse.tsx +244 -0
- package/src/panels/studio/ThisUsePanel.tsx +679 -0
- package/src/panels/studio/componentParts.tsx +341 -0
- package/src/panels/studio/components.ts +6 -0
- package/src/panels/studio/newCodeComponent.ts +66 -0
- package/src/panels/timeline/AudioFxButton.tsx +290 -0
- package/src/panels/timeline/AudioLane.tsx +674 -85
- package/src/panels/timeline/BlockRow.tsx +154 -85
- package/src/panels/timeline/ChannelRow.tsx +378 -129
- package/src/panels/timeline/CurvePane.tsx +508 -0
- package/src/panels/timeline/Filmstrip.tsx +361 -0
- package/src/panels/timeline/GenerateDrawer.tsx +407 -0
- package/src/panels/timeline/KeyStretch.tsx +115 -0
- package/src/panels/timeline/LifespanRow.tsx +730 -47
- package/src/panels/timeline/MarkerLane.tsx +46 -8
- package/src/panels/timeline/PlayButton.tsx +91 -0
- package/src/panels/timeline/PropertyPicker.tsx +254 -0
- package/src/panels/timeline/ShotRow.tsx +400 -0
- package/src/panels/timeline/SoundMode.tsx +1406 -0
- package/src/panels/timeline/TimelineDock.tsx +2338 -272
- package/src/panels/timeline/TransportVolume.tsx +163 -0
- package/src/panels/timeline/beatRuler.ts +74 -0
- package/src/panels/timeline/curveModel.ts +500 -0
- package/src/panels/timeline/duckUnderVoice.ts +68 -0
- package/src/panels/timeline/keyframeMenu.ts +138 -0
- package/src/panels/timeline/labelWidth.ts +49 -0
- package/src/panels/timeline/marquee.ts +155 -0
- package/src/panels/timeline/model.ts +1860 -199
- package/src/panels/timeline/snap.ts +125 -43
- package/src/panels/timeline/staggerPreview.tsx +92 -0
- package/src/panels/timeline/takeMeasure.ts +72 -0
- package/src/panels/timeline/useLive.ts +48 -0
- package/src/panels/timeline/viewport.ts +234 -0
- package/src/panels/toolbar/BackChip.tsx +116 -0
- package/src/panels/toolbar/CameraViewBar.tsx +118 -49
- package/src/panels/toolbar/CanvasBar.tsx +117 -0
- package/src/panels/toolbar/InsertButton.tsx +38 -0
- package/src/panels/toolbar/IsolationTrail.tsx +156 -0
- package/src/panels/toolbar/PanelToggles.tsx +86 -0
- package/src/panels/toolbar/ShadingBar.tsx +119 -26
- package/src/panels/toolbar/ToolDockBar.tsx +329 -80
- package/src/panels/toolbar/ToolFooter.tsx +102 -0
- package/src/panels/toolbar/ViewModeBar.tsx +247 -38
- package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
- package/src/panels/toolbar/useAddRows.tsx +326 -0
- package/src/panels/toolbar/useDismiss.ts +122 -0
- package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
- package/src/panels/versions/versionModel.ts +103 -0
- package/src/panels/virtualWindow.ts +271 -0
- package/src/shotTokens.css +151 -60
- package/src/stage/FrustumGizmo.tsx +504 -84
- package/src/stage/GridPlane.tsx +225 -16
- package/src/stage/NodePreviews.tsx +628 -0
- package/src/stage/PerfHud.tsx +437 -47
- package/src/stage/SplitRenderer.tsx +816 -169
- package/src/stage/StageApp.tsx +4274 -486
- package/src/stage/StageRootBoundary.tsx +114 -0
- package/src/stage/StageTools.tsx +651 -151
- package/src/stage/TransformGizmo.tsx +696 -0
- package/src/stage/adaptivePresentation.ts +145 -0
- package/src/stage/bridgeClient.ts +2522 -41
- package/src/stage/exportWorker.ts +9 -0
- package/src/stage/feed.ts +305 -14
- package/src/stage/fontPreview.ts +176 -0
- package/src/stage/frustumGeometry.ts +319 -1
- package/src/stage/furnitureTokens.ts +33 -0
- package/src/stage/gizmoMath.ts +508 -16
- package/src/stage/gpuTimer.ts +276 -0
- package/src/stage/instanceModules.ts +194 -33
- package/src/stage/interactions/move.ts +24 -5
- package/src/stage/isolation.ts +291 -33
- package/src/stage/jsSelfProfiler.ts +325 -0
- package/src/stage/main.tsx +116 -16
- package/src/stage/modalState.ts +222 -23
- package/src/stage/moduleEpoch.ts +60 -0
- package/src/stage/motionPathStage.ts +279 -0
- package/src/stage/motionPreview.ts +74 -0
- package/src/stage/overlays/Overlays.tsx +1112 -159
- package/src/stage/overlays/Rulers.tsx +495 -0
- package/src/stage/panes.ts +159 -10
- package/src/stage/project.ts +68 -3
- package/src/stage/renderScaleController.ts +730 -0
- package/src/stage/rulers.ts +129 -0
- package/src/stage/sceneExtent.ts +75 -0
- package/src/stage/shading.ts +20 -0
- package/src/stage/splineStage.ts +632 -0
- package/src/stage/stagePerformanceTelemetry.ts +717 -0
- package/src/stage/stageTheme.ts +36 -0
- package/src/stage/stageWarmup.ts +11 -0
- package/src/stage/textAutoSize.ts +124 -0
- package/src/stage/tier1Export.ts +641 -0
- package/src/stage/tokenColor.ts +14 -9
- package/src/stage/view.ts +56 -9
- package/src/stage/workingView.ts +277 -33
- package/src/state/accountPrefs.ts +261 -0
- package/src/state/agentActions.ts +173 -15
- package/src/state/agentActivity.ts +198 -0
- package/src/state/agentQuestion.ts +239 -0
- package/src/state/bootOpen.ts +42 -0
- package/src/state/cameraVerbs.ts +139 -0
- package/src/state/clientId.ts +6 -1
- package/src/state/comments.ts +1099 -0
- package/src/state/context.tsx +19 -1
- package/src/state/editorPrefs.ts +220 -0
- package/src/state/errorReports.ts +121 -0
- package/src/state/fieldWrite.ts +161 -0
- package/src/state/fontRecents.ts +70 -0
- package/src/state/fonts.ts +656 -0
- package/src/state/graphClipboard.ts +414 -0
- package/src/state/imageThumbs.ts +216 -0
- package/src/state/insert.ts +444 -67
- package/src/state/isolationTrail.ts +92 -0
- package/src/state/keyMoves.ts +134 -0
- package/src/state/keyframeClipboard.ts +177 -0
- package/src/state/keymap.ts +1153 -117
- package/src/state/layoutPrefs.ts +272 -0
- package/src/state/layouts.ts +205 -0
- package/src/state/measureMedia.ts +167 -0
- package/src/state/menu.ts +2341 -28
- package/src/state/motionStamp.ts +7 -0
- package/src/state/panelSize.ts +375 -5
- package/src/state/pendingChanges.ts +119 -0
- package/src/state/playHold.ts +78 -0
- package/src/state/playbackPreparation.ts +562 -0
- package/src/state/posterCapture.ts +242 -0
- package/src/state/presence.ts +254 -0
- package/src/state/projectComponents.ts +160 -0
- package/src/state/renderEvents.ts +298 -18
- package/src/state/runtimeErrors.ts +46 -0
- package/src/state/selection.ts +12 -0
- package/src/state/shortcuts.ts +1606 -0
- package/src/state/sketchGuide.ts +51 -0
- package/src/state/splineRefs.ts +87 -0
- package/src/state/stageHealth.ts +259 -0
- package/src/state/stageWatchdog.ts +47 -0
- package/src/state/stillStage.ts +330 -0
- package/src/state/stillThumbs.ts +474 -0
- package/src/state/store.ts +23591 -2982
- package/src/state/storyboardModel.ts +528 -0
- package/src/state/sync.ts +1257 -0
- package/src/state/syncCache.ts +159 -0
- package/src/state/triangles.ts +13 -0
- package/src/state/types.ts +1698 -55
- package/src/state/unsavedGuard.ts +49 -0
- package/src/state/viewMode.ts +200 -0
- package/src/state/webmcp.ts +1128 -0
- package/src/state/workspace.ts +1147 -0
- package/src/styles/assets-tab.css +304 -0
- package/src/styles/canvas.css +545 -0
- package/src/styles/comments.css +1435 -0
- package/src/styles/controls.css +162 -0
- package/src/styles/dialogs.css +390 -0
- package/src/styles/insert-drawer.css +586 -0
- package/src/styles/inspector-board.css +207 -0
- package/src/styles/inspector-object.css +486 -0
- package/src/styles/inspector-shot.css +252 -0
- package/src/styles/inspector.css +360 -0
- package/src/styles/left-column.css +1628 -0
- package/src/styles/library-preview.css +575 -0
- package/src/styles/library.css +512 -0
- package/src/styles/modes/code.css +569 -0
- package/src/styles/modes/component.css +1561 -0
- package/src/styles/modes/material.css +1201 -0
- package/src/styles/modes/storyboard.css +518 -0
- package/src/styles/share-component.css +49 -0
- package/src/styles/shell.css +653 -0
- package/src/styles/shot-brief.css +360 -0
- package/src/styles/states.css +76 -0
- package/src/styles/sync.css +380 -0
- package/src/styles/timeline-graph.css +384 -0
- package/src/styles/timeline-meters.css +89 -0
- package/src/styles/timeline-rows.css +1959 -0
- package/src/styles/timeline-sound.css +1003 -0
- package/src/styles/timeline.css +754 -0
- package/src/styles/tool-footer.css +525 -0
- package/src/styles/topbar.css +886 -0
- package/src/styles/versions.css +262 -0
- package/src/styles.css +72 -2921
- package/src/tools.ts +108 -23
- package/dist/assets/index-B7notge7.css +0 -1
- package/dist/assets/index-BBE6Ta9L.js +0 -52
- package/src/panels/files/icons.tsx +0 -118
- package/src/panels/header/DocSwitcher.tsx +0 -85
- package/src/panels/header/TransportBar.tsx +0 -86
- package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
- package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
- package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
- package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
- package/src/panels/inspector/animate/useBlocks.ts +0 -43
- package/src/panels/material/MaterialPicker.tsx +0 -172
- package/src/panels/timeline/SceneStrip.tsx +0 -145
- package/src/panels/toolbar/AddMenu.tsx +0 -230
- package/src/stage/MoveGizmo.tsx +0 -411
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// The shot stage's encode worker file: spawned by tier1Export.ts, served
|
|
2
|
+
// through the project's Vite with mediabunny pinned to the studio's copy
|
|
3
|
+
// (cli/src/pins.ts) — the same treatment the motion harness's worker gets.
|
|
4
|
+
// The whole worker lives in @dailies-studio/shot/tier1; this file exists
|
|
5
|
+
// because a Worker needs a URL of its own.
|
|
6
|
+
import { bootExportWorker } from "@dailies-studio/shot/tier1/workerEntry";
|
|
7
|
+
import type { WorkerScope } from "@dailies-studio/shot/tier1";
|
|
8
|
+
|
|
9
|
+
bootExportWorker(self as unknown as WorkerScope);
|
package/src/stage/feed.ts
CHANGED
|
@@ -26,11 +26,60 @@
|
|
|
26
26
|
// COORDINATES ARE PANE-LOCAL CSS px, from the pane's top-left. `paneAt` returns
|
|
27
27
|
// exactly that pairing, so the caller passes through what it was handed and
|
|
28
28
|
// there is no second place where a pane origin gets subtracted.
|
|
29
|
-
import type { Camera, Matrix4, Ray } from "three";
|
|
30
|
-
import type { GestureKind, ResizeHandle } from "@dailies-studio/shot/doc";
|
|
29
|
+
import type { Camera, Matrix4, Ray, Vector3 } from "three";
|
|
30
|
+
import type { CameraGate, GestureKind, ResizeHandle } from "@dailies-studio/shot/doc";
|
|
31
31
|
import type { StagePane } from "./panes.js";
|
|
32
32
|
import type { GizmoGrab } from "./gizmoMath.js";
|
|
33
33
|
import type { LayerFrame, ScreenQuad, WorldQuad } from "./project.js";
|
|
34
|
+
import type { ShotPeerSelection } from "../bridgeTypes.js";
|
|
35
|
+
import type { ScreenMotionPath } from "./motionPathStage.js";
|
|
36
|
+
import type { Vec3 } from "@dailies-studio/engine";
|
|
37
|
+
|
|
38
|
+
/** Another person's selected layer in one pane (bridge v43). `tag` on the
|
|
39
|
+
* first of their layers only; `ring` when this author selected it too, so
|
|
40
|
+
* theirs draws around ours instead of under it (page 21). */
|
|
41
|
+
export interface PeerQuad {
|
|
42
|
+
quad: ScreenQuad;
|
|
43
|
+
name: string;
|
|
44
|
+
color: string;
|
|
45
|
+
tag: boolean;
|
|
46
|
+
ring: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Other people's selections projected into one pane. */
|
|
50
|
+
export function projectPeers(
|
|
51
|
+
peers: readonly ShotPeerSelection[],
|
|
52
|
+
quadFor: (pane: StagePane, layerId: string) => ScreenQuad | null,
|
|
53
|
+
pane: StagePane,
|
|
54
|
+
mine: readonly string[],
|
|
55
|
+
): PeerQuad[] {
|
|
56
|
+
if (peers.length === 0) return [];
|
|
57
|
+
const own = new Set(mine);
|
|
58
|
+
const out: PeerQuad[] = [];
|
|
59
|
+
for (const peer of peers) {
|
|
60
|
+
let tag = true;
|
|
61
|
+
for (const id of peer.ids) {
|
|
62
|
+
const quad = quadFor(pane, id);
|
|
63
|
+
if (quad === null) continue;
|
|
64
|
+
out.push({ quad, name: peer.name, color: peer.color, tag, ring: own.has(id) });
|
|
65
|
+
tag = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A failed layer's outline in one pane, and the name its placeholder says. */
|
|
72
|
+
export interface FailedQuad {
|
|
73
|
+
quad: ScreenQuad;
|
|
74
|
+
label: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** A selected mask's outline in one pane (gap 7). `round` for an ellipse
|
|
78
|
+
* mask, whose outline is the ellipse inscribed in its quad. */
|
|
79
|
+
export interface MaskQuad {
|
|
80
|
+
quad: ScreenQuad;
|
|
81
|
+
round: boolean;
|
|
82
|
+
}
|
|
34
83
|
|
|
35
84
|
/** What a press on the current selection turned out to be. */
|
|
36
85
|
export interface Grab {
|
|
@@ -87,9 +136,16 @@ export interface StageFeed {
|
|
|
87
136
|
* the graph's SHAPE — the matrices inside it are live references, so motion
|
|
88
137
|
* needs no invalidation and neither does a seek that only moves things. What
|
|
89
138
|
* it cannot see is membership, and membership changes for a reason no
|
|
90
|
-
* document value predicts: a GLB
|
|
91
|
-
*
|
|
92
|
-
*
|
|
139
|
+
* document value predicts: a GLB resolves and suspense commits a subtree that
|
|
140
|
+
* was not there a frame ago. This counter is that event, and it is what lets
|
|
141
|
+
* the walk be memoised across an orbit.
|
|
142
|
+
*
|
|
143
|
+
* It moves on a layer group mounting or going (`onLayerGraph`) and on a
|
|
144
|
+
* model reporting (`pushMeshStats`), and on NOTHING ELSE: not on a cut,
|
|
145
|
+
* which only re-parents a resident Shot's group, and not on what a code
|
|
146
|
+
* component renders under its mounted layer (its module landing, its own
|
|
147
|
+
* Suspense, a child it draws on a prop). A walk that needs those (the
|
|
148
|
+
* inside-out shells) walks per draw.
|
|
93
149
|
*/
|
|
94
150
|
sceneEpoch: number;
|
|
95
151
|
/**
|
|
@@ -104,6 +160,13 @@ export interface StageFeed {
|
|
|
104
160
|
* quad re-renders one SVG and zero canvases.
|
|
105
161
|
*/
|
|
106
162
|
onOverlay: (() => void) | null;
|
|
163
|
+
/** True while the pen holds points. Its preview is projected through
|
|
164
|
+
* `paneAt` at render time, so the in-canvas half then also calls
|
|
165
|
+
* `onOverlay` when the frame pane's camera moves (`cameraPose`, the last
|
|
166
|
+
* projection and view matrices it saw), with no pointer move to cause it:
|
|
167
|
+
* the Shot camera, or inside a definition its working camera. */
|
|
168
|
+
penLive: boolean;
|
|
169
|
+
cameraPose: number[] | null;
|
|
107
170
|
/** The CURRENT selection, in the order both quad arrays are parallel to. One
|
|
108
171
|
* list for both panes: the selection is one selection, only its projection
|
|
109
172
|
* differs. */
|
|
@@ -113,6 +176,8 @@ export interface StageFeed {
|
|
|
113
176
|
* overlay drawn from last layout's numbers is worse than no overlay. */
|
|
114
177
|
quadsCamera: ScreenQuad[];
|
|
115
178
|
quadsWorking: ScreenQuad[];
|
|
179
|
+
/** Non-rendering spline drivers remain visible as working-pane guides. */
|
|
180
|
+
splineGuidesWorking: Array<{ id: string; pts: readonly number[]; selected: boolean }>;
|
|
116
181
|
/** Parallel to `ids`: is each selected layer locked? Written here rather than
|
|
117
182
|
* looked up by the overlay because `collectFrames` is the one place that
|
|
118
183
|
* already knows, and a second lookup could disagree with the `grabAt` that
|
|
@@ -150,6 +215,15 @@ export interface StageFeed {
|
|
|
150
215
|
* raycasting, projection, `renderBins` — takes the base class already.
|
|
151
216
|
*/
|
|
152
217
|
workingCamera: Camera | null;
|
|
218
|
+
/**
|
|
219
|
+
* Pose and return the working camera for the current committed view.
|
|
220
|
+
*
|
|
221
|
+
* The normal caller is StageTools' priority-0 frame callback. SplitRenderer
|
|
222
|
+
* also calls it from ClockDriver's compile barrier, before that callback has
|
|
223
|
+
* run, so the programs compiled for a new view are the ones its first draw
|
|
224
|
+
* will actually use.
|
|
225
|
+
*/
|
|
226
|
+
prepareWorkingCamera: (() => Camera | null) | null;
|
|
153
227
|
/** Ray-pick at a point in the pane's own CSS px. Front-most first, where
|
|
154
228
|
* "front-most" is paint order in the camera pane and nearest in the working
|
|
155
229
|
* one. Null until the canvas exists; empty for a pane that is not on
|
|
@@ -169,6 +243,71 @@ export interface StageFeed {
|
|
|
169
243
|
* selects. A second walk here would be that bug.
|
|
170
244
|
*/
|
|
171
245
|
hoverQuad: ((pane: StagePane, x: number, y: number) => ScreenQuad | null) | null;
|
|
246
|
+
/**
|
|
247
|
+
* The layer the CHROME is pointing at — a timeline row under the cursor — or
|
|
248
|
+
* null. Written imperatively by the bridge's `hoverLayer` sink, NEVER
|
|
249
|
+
* through React state: under `frameloop="never"` every stage commit is a GL
|
|
250
|
+
* draw, and a row-hover must cost one SVG leaf repaint and zero draws.
|
|
251
|
+
*/
|
|
252
|
+
hintId: string | null;
|
|
253
|
+
/**
|
|
254
|
+
* `hintId`'s outline, projected per pane. Kept fresh two ways, and both are
|
|
255
|
+
* needed: the sink seeds it at write time (an idle stage runs no frame
|
|
256
|
+
* between the hover and the paint), and `StageTools`' frame run re-projects
|
|
257
|
+
* it (a camera move slides the outline with the layer).
|
|
258
|
+
*/
|
|
259
|
+
hintCamera: ScreenQuad | null;
|
|
260
|
+
hintWorking: ScreenQuad | null;
|
|
261
|
+
/**
|
|
262
|
+
* The layers of the pieces the runtime isolated (pieceFailures.ts), and the
|
|
263
|
+
* one line the overlay says about them, or null with nothing failed. Written
|
|
264
|
+
* imperatively by StageApp's `onPieceFailures` sink, like `hintId`: a
|
|
265
|
+
* failure arrives from inside the apply pass, and a stage commit there would
|
|
266
|
+
* be a second GL draw for a line of SVG.
|
|
267
|
+
*/
|
|
268
|
+
failedIds: readonly string[];
|
|
269
|
+
/** Each failed layer's Layers panel label, for the placeholder's line. */
|
|
270
|
+
failedLabels: ReadonlyMap<string, string>;
|
|
271
|
+
failureText: string | null;
|
|
272
|
+
/**
|
|
273
|
+
* `failedIds`' outlines, projected per pane by `StageTools`' frame run, so
|
|
274
|
+
* the placeholder follows its layer through a camera move. A layer the
|
|
275
|
+
* runtime left out entirely has no group to outline; the bar names it.
|
|
276
|
+
*/
|
|
277
|
+
failedCamera: FailedQuad[];
|
|
278
|
+
failedWorking: FailedQuad[];
|
|
279
|
+
/**
|
|
280
|
+
* THE MASK OF A SELECTED MASK GROUP (gap 7, Paper page 25): the dashed
|
|
281
|
+
* outline of the matte that cuts what the author selected, per pane. A mask
|
|
282
|
+
* that is itself selected has its selection outline instead. Projected by
|
|
283
|
+
* `StageTools`' frame run from the selection and the document, so it needs
|
|
284
|
+
* no bridge message.
|
|
285
|
+
*/
|
|
286
|
+
maskCamera: MaskQuad[];
|
|
287
|
+
maskWorking: MaskQuad[];
|
|
288
|
+
/**
|
|
289
|
+
* OTHER PEOPLE'S SELECTIONS (bridge v43), as the chrome pushed them, and
|
|
290
|
+
* their outlines projected per pane by the same frame run, so a peer's
|
|
291
|
+
* outline follows its layer through a camera move. Paint only.
|
|
292
|
+
*/
|
|
293
|
+
peerSel: readonly ShotPeerSelection[];
|
|
294
|
+
peersCamera: PeerQuad[];
|
|
295
|
+
peersWorking: PeerQuad[];
|
|
296
|
+
/**
|
|
297
|
+
* The layer the open Studio comment is pinned to (bridge v45, S5), and its
|
|
298
|
+
* outline in the camera pane, projected by the same frame run that projects
|
|
299
|
+
* `failedIds`, so the dashed ring rides the layer. Written by StageApp; null with no
|
|
300
|
+
* open pin on a layer in view.
|
|
301
|
+
*/
|
|
302
|
+
pinLayerId: string | null;
|
|
303
|
+
pinLayerCamera: ScreenQuad | null;
|
|
304
|
+
/**
|
|
305
|
+
* Project ONE layer's outline in a pane, by id. `hoverQuad`'s sibling —
|
|
306
|
+
* same closure family, registered by `StageTools` per frame run and
|
|
307
|
+
* pull-based, so it stays answerable while the stage is idle. The hover
|
|
308
|
+
* sink is its one caller.
|
|
309
|
+
*/
|
|
310
|
+
quadForLayer: ((pane: StagePane, layerId: string) => ScreenQuad | null) | null;
|
|
172
311
|
/** Marquee, in the same coordinates. */
|
|
173
312
|
pickRect:
|
|
174
313
|
| ((pane: StagePane, rect: { x0: number; y0: number; x1: number; y1: number }) => string[])
|
|
@@ -183,6 +322,13 @@ export interface StageFeed {
|
|
|
183
322
|
* no ray, and answering with the other pane's would silently drag the layer
|
|
184
323
|
* along a plane the author is not looking at. */
|
|
185
324
|
rayAt: ((pane: StagePane, x: number, y: number) => Ray | null) | null;
|
|
325
|
+
/** `rayAt`'s inverse for the z = 0 design plane: a design point (centre
|
|
326
|
+
* origin, y down) into the pane's own CSS px, through the camera that pane
|
|
327
|
+
* renders. Null where `rayAt` is. */
|
|
328
|
+
paneAt: ((pane: StagePane, design: readonly [number, number]) => [number, number] | null) | null;
|
|
329
|
+
/** A WORLD point into the pane's own CSS px. No near-plane clip, so only for
|
|
330
|
+
* points known to be in front of the camera (a dragged dot's guide). */
|
|
331
|
+
worldToPane: ((pane: StagePane, world: Vector3) => [number, number] | null) | null;
|
|
186
332
|
/**
|
|
187
333
|
* Did a press in the WORKING pane land on the shot camera's frustum gizmo,
|
|
188
334
|
* and on which part?
|
|
@@ -191,32 +337,140 @@ export interface StageFeed {
|
|
|
191
337
|
* frustum gizmo IS the camera pane's camera, drawn as an object. It cannot
|
|
192
338
|
* appear inside the view it represents.
|
|
193
339
|
*/
|
|
194
|
-
frustumHit: ((x: number, y: number) => "body" | "
|
|
340
|
+
frustumHit: ((x: number, y: number) => "body" | "frame" | null) | null;
|
|
341
|
+
/**
|
|
342
|
+
* Did a press in the WORKING pane land on a waypoint of the PATH MOVE under
|
|
343
|
+
* the playhead, and on which one?
|
|
344
|
+
*
|
|
345
|
+
* No pane argument and no shot id, for `frustumHit`'s reasons: the marks are
|
|
346
|
+
* drawn in the working pane alone, and the move they belong to is the one the
|
|
347
|
+
* camera is currently in — the same rule the frustum itself follows. Null when
|
|
348
|
+
* the playhead is not inside a path move, so a press falls straight through to
|
|
349
|
+
* the frustum and then to the orbit.
|
|
350
|
+
*/
|
|
351
|
+
waypointHit: ((x: number, y: number) => number | null) | null;
|
|
352
|
+
/** Which waypoint the pointer is over, or null. `hoverFrustum`'s twin,
|
|
353
|
+
* written by the pointer lane and read in the frame loop. */
|
|
354
|
+
hoverWaypoint: number | null;
|
|
355
|
+
/**
|
|
356
|
+
* The selected layers' motion paths (gap 3), per pane, projected by
|
|
357
|
+
* `StageTools` in the frame pass. Empty when the `motionPaths` pref is off
|
|
358
|
+
* or the stage is playing, watching, exporting or in another gesture.
|
|
359
|
+
*/
|
|
360
|
+
motionPathsCamera: readonly ScreenMotionPath[];
|
|
361
|
+
motionPathsWorking: readonly ScreenMotionPath[];
|
|
362
|
+
/** The motion path key dot under a point in a pane, or null. Registered by
|
|
363
|
+
* `StageTools` beside the paths it answers for. */
|
|
364
|
+
pathKeyHit: ((pane: StagePane, x: number, y: number) => PathKeyRef | null) | null;
|
|
365
|
+
/** The selected dot's Bezier handle tip under a point (schema v40), or null.
|
|
366
|
+
* Asked before `pathKeyHit`: a handle drawn over a dot is the one shown. */
|
|
367
|
+
pathHandleHit: ((pane: StagePane, x: number, y: number) => PathHandleRef | null) | null;
|
|
368
|
+
/** A key dot's world point and its layer's parent `matrixWorld` (copies),
|
|
369
|
+
* for the drag's plane and its world-to-parent delta. Null when the key
|
|
370
|
+
* is not drawn this frame. */
|
|
371
|
+
pathKeyAnchor: ((layerId: string, keyId: string) => PathKeyAnchor | null) | null;
|
|
372
|
+
/** The dot, or the selected dot's handle (with its `part`), the pointer is
|
|
373
|
+
* over. Written by the pointer lane. */
|
|
374
|
+
hoverPathKey: PathKeyRef | PathHandleRef | null;
|
|
375
|
+
/** The dot or handle being dragged, so it keeps its hover ring under the cursor. */
|
|
376
|
+
activePathKey: PathKeyRef | PathHandleRef | null;
|
|
377
|
+
/** The dot last pressed: the one whose Bezier handles show. Stage-local,
|
|
378
|
+
* cleared by the frame pass once that key is no longer drawn. */
|
|
379
|
+
selectedPathKey: PathKeyRef | null;
|
|
195
380
|
/**
|
|
196
|
-
* Did a press in the WORKING pane land on one of the
|
|
197
|
-
*
|
|
381
|
+
* Did a press in the WORKING pane land on one of the transform gizmo's
|
|
382
|
+
* handles, and on which?
|
|
198
383
|
*
|
|
199
384
|
* No pane argument, for `frustumHit`'s reason: the gizmo is drawn in the
|
|
200
385
|
* working pane alone (the camera pane has resize handles, which the working
|
|
201
386
|
* pane deliberately does not — see `grabAt`).
|
|
202
387
|
*
|
|
203
|
-
* The answer carries the
|
|
388
|
+
* The answer carries the handle's ORIGIN AND DIRECTION as a snapshot rather
|
|
204
389
|
* than a live reference: the gizmo re-centres on the selection every frame,
|
|
205
390
|
* and an axis line that moved with the layer being dragged along it would
|
|
206
391
|
* chase its own translation.
|
|
207
392
|
*/
|
|
208
393
|
gizmoHit: ((x: number, y: number) => GizmoGrab | null) | null;
|
|
209
394
|
/**
|
|
210
|
-
* The
|
|
395
|
+
* The handle the pointer is over, or null.
|
|
211
396
|
*
|
|
212
397
|
* WRITTEN BY THE POINTER LANE, READ INSIDE THE FRAME LOOP, which is what
|
|
213
|
-
* keeps a hover off React entirely: `
|
|
214
|
-
* and re-colours a material there, so highlighting costs one uniform write
|
|
398
|
+
* keeps a hover off React entirely: `TransformGizmo` already runs at priority
|
|
399
|
+
* 0 and re-colours a material there, so highlighting costs one uniform write
|
|
215
400
|
* per frame and zero renders. Blender's gizmos highlight under the cursor and
|
|
216
401
|
* ours did not, which is the difference between "is this grabbable" being
|
|
217
402
|
* obvious and being something the author finds out by trying.
|
|
218
403
|
*/
|
|
219
|
-
|
|
404
|
+
hoverHandle: GizmoGrab["handle"] | null;
|
|
405
|
+
/**
|
|
406
|
+
* The handle a drag is currently HELD BY, or null.
|
|
407
|
+
*
|
|
408
|
+
* Its twin above, on the other side of the press. Blender dims the rest of
|
|
409
|
+
* the widget once a transform is running, and the reason is not decoration:
|
|
410
|
+
* the handles are drawn on top of the thing being moved, so a full-strength
|
|
411
|
+
* gizmo is three more lines crossing exactly the geometry the author is
|
|
412
|
+
* trying to judge. Written by the pointer lane at the press and cleared at
|
|
413
|
+
* the release, read by the draw pass.
|
|
414
|
+
*/
|
|
415
|
+
activeHandle: GizmoGrab["handle"] | null;
|
|
416
|
+
/**
|
|
417
|
+
* Which part of the shot camera's gizmo the pointer is over, or null.
|
|
418
|
+
*
|
|
419
|
+
* `hoverArm`'s twin, written and read the same way and for the same reason:
|
|
420
|
+
* the camera BODY and the framed rectangle's border are the two camera grips
|
|
421
|
+
* there are (both pan), and neither of them said anything back until the
|
|
422
|
+
* author pressed.
|
|
423
|
+
*/
|
|
424
|
+
hoverFrustum: "body" | "frame" | null;
|
|
425
|
+
/**
|
|
426
|
+
* Is a component driving the render camera this frame, off the rig?
|
|
427
|
+
*
|
|
428
|
+
* Written by `FrustumGizmo`, which reads the camera after every writer, and
|
|
429
|
+
* read by `TransformGizmo` one frame later: a driven camera has no rig to
|
|
430
|
+
* hang arms on, and dragging the rig would move nothing the picture shows.
|
|
431
|
+
*/
|
|
432
|
+
cameraDriven: boolean;
|
|
433
|
+
/**
|
|
434
|
+
* The driven camera's WORLD: where the component's content is and how big,
|
|
435
|
+
* in world units, or null while the document's rig draws. Written by
|
|
436
|
+
* `FrustumGizmo` (the claim's extent, or the live bounds it measured), read
|
|
437
|
+
* by the working pane's fitter so Home frames the component's world rather
|
|
438
|
+
* than an empty canvas thousands of units away.
|
|
439
|
+
*/
|
|
440
|
+
cameraWorld: { centre: readonly [number, number, number]; extent: number } | null;
|
|
441
|
+
/**
|
|
442
|
+
* What a camera write would do at the playhead (bridge v29), mirrored from
|
|
443
|
+
* the chrome for the frame loops: the gizmo dims when it is not `free`, and
|
|
444
|
+
* the pointer lane refuses the press with the gate's own sentence rather
|
|
445
|
+
* than after the drag. Null when no document is open.
|
|
446
|
+
*/
|
|
447
|
+
cameraGate: CameraGate | null;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** One key on one layer's Position track. */
|
|
451
|
+
export interface PathKeyRef {
|
|
452
|
+
layerId: string;
|
|
453
|
+
keyId: string;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** One of a key's two Bezier handles (schema v40). */
|
|
457
|
+
export interface PathHandleRef extends PathKeyRef {
|
|
458
|
+
part: "in" | "out";
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export interface PathKeyAnchor {
|
|
462
|
+
world: Vector3;
|
|
463
|
+
parent: Matrix4;
|
|
464
|
+
/** The key's frame, in its track's own frames. */
|
|
465
|
+
frame: number;
|
|
466
|
+
/** Where the dot is drawn, parent-local design px (+y down). */
|
|
467
|
+
point: Vec3;
|
|
468
|
+
/** The keys either side of it, for ctrl's snap. */
|
|
469
|
+
neighbours: Vec3[];
|
|
470
|
+
/** Its Bezier handles as the sampler reads them, offsets from `point`.
|
|
471
|
+
* Absent off the bezier arm and on the side no segment uses. */
|
|
472
|
+
spatialIn?: Vec3;
|
|
473
|
+
spatialOut?: Vec3;
|
|
220
474
|
}
|
|
221
475
|
|
|
222
476
|
export function createStageFeed(): StageFeed {
|
|
@@ -224,20 +478,57 @@ export function createStageFeed(): StageFeed {
|
|
|
224
478
|
version: 0,
|
|
225
479
|
sceneEpoch: 0,
|
|
226
480
|
onOverlay: null,
|
|
481
|
+
penLive: false,
|
|
482
|
+
cameraPose: null,
|
|
227
483
|
ids: [],
|
|
228
484
|
quadsCamera: [],
|
|
229
485
|
quadsWorking: [],
|
|
486
|
+
splineGuidesWorking: [],
|
|
230
487
|
locked: [],
|
|
231
488
|
union: null,
|
|
232
489
|
frames: null,
|
|
233
490
|
workingCamera: null,
|
|
491
|
+
prepareWorkingCamera: null,
|
|
234
492
|
pick: null,
|
|
235
493
|
hoverQuad: null,
|
|
494
|
+
hintId: null,
|
|
495
|
+
hintCamera: null,
|
|
496
|
+
hintWorking: null,
|
|
497
|
+
failedIds: [],
|
|
498
|
+
failedLabels: new Map(),
|
|
499
|
+
failureText: null,
|
|
500
|
+
failedCamera: [],
|
|
501
|
+
failedWorking: [],
|
|
502
|
+
maskCamera: [],
|
|
503
|
+
maskWorking: [],
|
|
504
|
+
peerSel: [],
|
|
505
|
+
peersCamera: [],
|
|
506
|
+
peersWorking: [],
|
|
507
|
+
pinLayerId: null,
|
|
508
|
+
pinLayerCamera: null,
|
|
509
|
+
quadForLayer: null,
|
|
236
510
|
pickRect: null,
|
|
237
511
|
grabAt: null,
|
|
238
512
|
rayAt: null,
|
|
513
|
+
paneAt: null,
|
|
514
|
+
worldToPane: null,
|
|
239
515
|
frustumHit: null,
|
|
516
|
+
waypointHit: null,
|
|
517
|
+
hoverWaypoint: null,
|
|
518
|
+
motionPathsCamera: [],
|
|
519
|
+
motionPathsWorking: [],
|
|
520
|
+
pathKeyHit: null,
|
|
521
|
+
pathHandleHit: null,
|
|
522
|
+
pathKeyAnchor: null,
|
|
523
|
+
hoverPathKey: null,
|
|
524
|
+
activePathKey: null,
|
|
525
|
+
selectedPathKey: null,
|
|
240
526
|
gizmoHit: null,
|
|
241
|
-
|
|
527
|
+
hoverHandle: null,
|
|
528
|
+
activeHandle: null,
|
|
529
|
+
hoverFrustum: null,
|
|
530
|
+
cameraDriven: false,
|
|
531
|
+
cameraWorld: null,
|
|
532
|
+
cameraGate: null,
|
|
242
533
|
};
|
|
243
534
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// THE FONT PREVIEW (bridge v50): the font picker's hovered or arrowed-to family
|
|
2
|
+
// drawn on some text layers, without a document write.
|
|
3
|
+
//
|
|
4
|
+
// Two halves. `fontPreviewDoc` derives the document the RUNTIME draws, and only
|
|
5
|
+
// the runtime: every other reader on the stage (picking, the overlays, the
|
|
6
|
+
// inline editor, the auto-width measure the store writes, stills, coverage,
|
|
7
|
+
// health and every export) keeps the real one. `createFontPreviewFaces` loads
|
|
8
|
+
// the preview's files under ONE private family per preview, and adds them to
|
|
9
|
+
// the page's font set only once they have loaded: a face still loading would
|
|
10
|
+
// hold `document.fonts.ready`, which the runtime's own font claim awaits. A
|
|
11
|
+
// face that fails reports nothing; the layers keep the fallback.
|
|
12
|
+
import { browserFontPlatform } from "@dailies-studio/shot";
|
|
13
|
+
import type { FontPlatform } from "@dailies-studio/shot";
|
|
14
|
+
import { FONT_SUBSETS_MAX, quoteFontFamily, unicodeRangeProblem } from "@dailies-studio/shot/doc";
|
|
15
|
+
import type { Doc3D, Layer3D, TextLayer3D } from "@dailies-studio/shot/doc";
|
|
16
|
+
import type { ShotFontPreview, ShotFontPreviewFace } from "../bridgeTypes.js";
|
|
17
|
+
|
|
18
|
+
/** The most files one preview loads: a whole face set (`fontAsset` plus
|
|
19
|
+
* `FONT_SUBSETS_MAX` subsets). */
|
|
20
|
+
export const MAX_FONT_PREVIEW_FACES = FONT_SUBSETS_MAX + 1;
|
|
21
|
+
|
|
22
|
+
const FALLBACKS = new Set(["sans-serif", "serif", "monospace", "cursive"]);
|
|
23
|
+
|
|
24
|
+
/** What the stage holds: the preview as sanitized, and the private family its
|
|
25
|
+
* faces registered under once they landed. Null before that, and for good
|
|
26
|
+
* when no face loads: the layers draw the display family and the fallback. */
|
|
27
|
+
export interface StageFontPreview extends ShotFontPreview {
|
|
28
|
+
face: string | null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A preview the stage can draw, or null for none. A boundary like
|
|
33
|
+
* `sanitizeSketchGuide`: the family becomes a CSS string in `ctx.font`, so it is
|
|
34
|
+
* one line of at most 100 characters; a fallback that is not one of the four
|
|
35
|
+
* generic families is `sans-serif`; a weight range off 1..1000 or backwards is
|
|
36
|
+
* `[1, 1000]`; a face with no url or a range `unicodeRangeProblem` refuses is
|
|
37
|
+
* dropped, and at most `MAX_FONT_PREVIEW_FACES` are kept. No container or no
|
|
38
|
+
* layer id is no preview.
|
|
39
|
+
*/
|
|
40
|
+
export function sanitizeFontPreview(raw: ShotFontPreview | null): ShotFontPreview | null {
|
|
41
|
+
if (raw === null || typeof raw !== "object") return null;
|
|
42
|
+
const { containerId, layerIds, family, fallback, style, weightRange, faces } = raw;
|
|
43
|
+
if (typeof containerId !== "string" || containerId.length === 0 || !Array.isArray(layerIds)) return null;
|
|
44
|
+
const ids = [...new Set((layerIds as unknown[]).filter((id): id is string => typeof id === "string" && id.length > 0))];
|
|
45
|
+
if (ids.length === 0) return null;
|
|
46
|
+
const weight = (n: unknown): n is number => typeof n === "number" && Number.isFinite(n) && n >= 1 && n <= 1000;
|
|
47
|
+
const [min, max] = Array.isArray(weightRange) ? weightRange : [];
|
|
48
|
+
const kept = (Array.isArray(faces) ? faces : []).flatMap((face: Partial<ShotFontPreviewFace> | null): ShotFontPreviewFace[] => {
|
|
49
|
+
if (face === null || typeof face !== "object" || typeof face.url !== "string" || face.url.length === 0) return [];
|
|
50
|
+
if (face.unicodeRange === undefined) return [{ url: face.url }];
|
|
51
|
+
return unicodeRangeProblem(face.unicodeRange) === null ? [{ url: face.url, unicodeRange: face.unicodeRange }] : [];
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
containerId,
|
|
55
|
+
layerIds: ids,
|
|
56
|
+
family: typeof family === "string" ? family.replace(/[\s\p{Cc}]+/gu, " ").trim().slice(0, 100) : "",
|
|
57
|
+
fallback: typeof fallback === "string" && FALLBACKS.has(fallback) ? fallback : "sans-serif",
|
|
58
|
+
style: style === "italic" ? "italic" : "normal",
|
|
59
|
+
weightRange: weight(min) && weight(max) && min <= max ? [min, max] : [1, 1000],
|
|
60
|
+
faces: kept.slice(0, MAX_FONT_PREVIEW_FACES),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The document the runtime draws while `preview` shows. In its container (a
|
|
66
|
+
* scene, else a definition), each listed text layer loses `fontAsset` and
|
|
67
|
+
* `fontSubsets` and draws the preview's private family (once its faces landed),
|
|
68
|
+
* then the display family, then the generic fallback, in the preview's style
|
|
69
|
+
* (upright is the key absent) and at its own weight, on the canvas engine (a
|
|
70
|
+
* glyph layer bakes `fontAsset`, and has none here). Naming the private family
|
|
71
|
+
* only once it landed is what re-rasters exactly these layers then: the style
|
|
72
|
+
* is part of a text raster's key.
|
|
73
|
+
*
|
|
74
|
+
* Every box keeps its stored size and place, auto-width ones included: picking
|
|
75
|
+
* and the overlays read layer frames off the runtime's scene graph, so a box
|
|
76
|
+
* moved here would move them off the real document. Every other object keeps
|
|
77
|
+
* its identity, `assets` included (the runtime's texture cache is keyed on
|
|
78
|
+
* it), and `doc` itself comes back when no listed id is a text layer of that
|
|
79
|
+
* container.
|
|
80
|
+
*/
|
|
81
|
+
export function fontPreviewDoc(doc: Doc3D, preview: StageFontPreview): Doc3D {
|
|
82
|
+
const scene = doc.scenesById[preview.containerId];
|
|
83
|
+
const def = scene === undefined ? doc.components?.[preview.containerId] : undefined;
|
|
84
|
+
const home = scene ?? def;
|
|
85
|
+
if (home === undefined) return doc;
|
|
86
|
+
const fontFamily = [preview.face, preview.family]
|
|
87
|
+
.filter((name): name is string => name !== null && name.length > 0)
|
|
88
|
+
.map(quoteFontFamily)
|
|
89
|
+
.concat(preview.fallback)
|
|
90
|
+
.join(", ");
|
|
91
|
+
let layersById: Record<string, Layer3D> | null = null;
|
|
92
|
+
for (const id of preview.layerIds) {
|
|
93
|
+
const layer = home.layersById[id];
|
|
94
|
+
if (layer?.kind !== "text") continue;
|
|
95
|
+
const { fontAsset: _asset, fontSubsets: _subsets, fontStyle: _slant, ...style } = layer.text.style;
|
|
96
|
+
const { engine: _engine, ...text } = layer.text;
|
|
97
|
+
const shown: TextLayer3D = {
|
|
98
|
+
...layer,
|
|
99
|
+
text: { ...text, style: { ...style, fontFamily, ...(preview.style === "italic" ? { fontStyle: "italic" as const } : {}) } },
|
|
100
|
+
};
|
|
101
|
+
(layersById ??= { ...home.layersById })[id] = shown;
|
|
102
|
+
}
|
|
103
|
+
if (layersById === null) return doc;
|
|
104
|
+
return scene !== undefined
|
|
105
|
+
? { ...doc, scenesById: { ...doc.scenesById, [preview.containerId]: { ...scene, layersById } } }
|
|
106
|
+
: { ...doc, components: { ...doc.components, [preview.containerId]: { ...def!, layersById } } };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
type PreviewFace = ReturnType<FontPlatform["createFace"]>;
|
|
110
|
+
|
|
111
|
+
export interface FontPreviewFaces {
|
|
112
|
+
/**
|
|
113
|
+
* Load `preview`'s faces under a new private family (`dailies-preview-<n>`),
|
|
114
|
+
* deleting the last preview's from the page's font set, or only delete them
|
|
115
|
+
* for null. The same files, style and weight range again keep the faces and
|
|
116
|
+
* family they have. Answers the family when this preview's faces are already
|
|
117
|
+
* in, else null; `onLanded` hears it once they land.
|
|
118
|
+
*/
|
|
119
|
+
show(preview: ShotFontPreview | null): string | null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The preview's faces. Each file loads on its own (`FontFace.load`) and joins
|
|
124
|
+
* the font set once every file has settled; the ones that failed are left out,
|
|
125
|
+
* and when none loads nothing happens at all. `onLanded` never hears a preview
|
|
126
|
+
* that was replaced or cleared meanwhile. `platformOf` is read only when a
|
|
127
|
+
* preview has faces to load (the test seam; a stage without the CSS Font
|
|
128
|
+
* Loading API answers null and draws the fallback).
|
|
129
|
+
*/
|
|
130
|
+
export function createFontPreviewFaces(
|
|
131
|
+
onLanded: (family: string) => void,
|
|
132
|
+
platformOf: () => FontPlatform | null = () => browserFontPlatform(),
|
|
133
|
+
): FontPreviewFaces {
|
|
134
|
+
let made = 0;
|
|
135
|
+
let current: { key: string; family: string; fonts: FontPlatform["fonts"]; added: PreviewFace[]; landed: boolean } | null =
|
|
136
|
+
null;
|
|
137
|
+
return {
|
|
138
|
+
show(preview) {
|
|
139
|
+
const key = preview === null ? "" : JSON.stringify([preview.faces, preview.style, preview.weightRange]);
|
|
140
|
+
if (current !== null && current.key === key) return current.landed ? current.family : null;
|
|
141
|
+
if (current !== null) for (const face of current.added) current.fonts.delete(face);
|
|
142
|
+
current = null;
|
|
143
|
+
if (preview === null || preview.faces.length === 0) return null;
|
|
144
|
+
const platform = platformOf();
|
|
145
|
+
if (platform === null) return null;
|
|
146
|
+
made += 1;
|
|
147
|
+
const entry = { key, family: `dailies-preview-${made}`, fonts: platform.fonts, added: [] as PreviewFace[], landed: false };
|
|
148
|
+
current = entry;
|
|
149
|
+
const descriptors = { weight: `${preview.weightRange[0]} ${preview.weightRange[1]}`, style: preview.style };
|
|
150
|
+
let faces: PreviewFace[];
|
|
151
|
+
let loads: Promise<unknown>[];
|
|
152
|
+
try {
|
|
153
|
+
faces = preview.faces.map((face) =>
|
|
154
|
+
platform.createFace(
|
|
155
|
+
entry.family,
|
|
156
|
+
`url(${JSON.stringify(face.url)})`,
|
|
157
|
+
face.unicodeRange === undefined ? descriptors : { ...descriptors, unicodeRange: face.unicodeRange },
|
|
158
|
+
),
|
|
159
|
+
);
|
|
160
|
+
loads = faces.map((face) => face.load());
|
|
161
|
+
} catch {
|
|
162
|
+
// Reports nothing, like a load that fails: the layers keep the fallback.
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
void Promise.allSettled(loads).then((settled) => {
|
|
166
|
+
if (current !== entry) return;
|
|
167
|
+
entry.added = faces.filter((_, index) => settled[index]!.status === "fulfilled");
|
|
168
|
+
if (entry.added.length === 0) return;
|
|
169
|
+
for (const face of entry.added) entry.fonts.add(face);
|
|
170
|
+
entry.landed = true;
|
|
171
|
+
onLanded(entry.family);
|
|
172
|
+
});
|
|
173
|
+
return null;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|