@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,244 @@
|
|
|
1
|
+
// The ease editor that camera moves and scene transitions share.
|
|
2
|
+
//
|
|
3
|
+
// ── WHY THIS IS NOT `KeyframeEditor` ───────────────────────────────────
|
|
4
|
+
//
|
|
5
|
+
// `@dailies-studio/timeline`'s ease editor is a fine component and its INPUTS
|
|
6
|
+
// are keyframe-shaped: `refs: KeyframeAddr[]` and a `TimelineGesture` whose
|
|
7
|
+
// capture emits `{kind:"setEase", refs}`. A camera move or a transition has no
|
|
8
|
+
// keyframes, so every one of those would be a fabricated address. What DOES
|
|
9
|
+
// transfer is everything pure: `EASE_PRESETS`, `easeSelection`, `SPRING_DEFAULT`,
|
|
10
|
+
// and the pad geometry `padToPx`/`pxToPad`. Those are imported, not re-derived,
|
|
11
|
+
// so the chromes cannot disagree about what "Ease Out" means.
|
|
12
|
+
import { useEffect, useRef } from "react";
|
|
13
|
+
import {
|
|
14
|
+
EASE_GROUP_LABELS,
|
|
15
|
+
EASE_PRESETS,
|
|
16
|
+
SPRING_DEFAULT,
|
|
17
|
+
easeSelection,
|
|
18
|
+
padToPx,
|
|
19
|
+
pxToPad,
|
|
20
|
+
} from "@dailies-studio/timeline";
|
|
21
|
+
import type { PadGeom } from "@dailies-studio/timeline";
|
|
22
|
+
import { Combobox, InspectorRow, NumberField, useLocked } from "@dailies-studio/ui";
|
|
23
|
+
import type { ComboboxOption } from "@dailies-studio/ui";
|
|
24
|
+
import type { Ease, SpringEase } from "@dailies-studio/engine";
|
|
25
|
+
import type { PointerEvent as ReactPointerEvent } from "react";
|
|
26
|
+
import { useStore } from "../../../state/context.js";
|
|
27
|
+
|
|
28
|
+
const PAD_GEOM: PadGeom = { width: 216, height: 132, padY: 30 };
|
|
29
|
+
|
|
30
|
+
// ---- easing ------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The ease row, plus whichever editor the chosen ease needs.
|
|
34
|
+
*
|
|
35
|
+
* Takes an `Ease` and not a subject, because a camera move and a transition both
|
|
36
|
+
* carry one and read it the same way. Two ease editors would be
|
|
37
|
+
* two places for "Ease Out" to mean something slightly different, which is the
|
|
38
|
+
* whole reason `EASE_PRESETS` is imported rather than re-declared.
|
|
39
|
+
*/
|
|
40
|
+
export function EaseControl(props: {
|
|
41
|
+
ease?: Ease;
|
|
42
|
+
/** What the select is called. The subject differs between the two callers and
|
|
43
|
+
* the accessible name has to say which one the author is looking at. */
|
|
44
|
+
ariaLabel?: string;
|
|
45
|
+
onEase(ease: Ease): void;
|
|
46
|
+
onScrub(ease: Ease): void;
|
|
47
|
+
}) {
|
|
48
|
+
const ease = props.ease;
|
|
49
|
+
// `easeSelection` takes a LIST because the shared editor is multi-select. One
|
|
50
|
+
// ease is a list of one, and reusing it keeps "Custom" meaning exactly what
|
|
51
|
+
// it means in the other two chromes.
|
|
52
|
+
const sel = easeSelection(ease === undefined ? [] : [ease]);
|
|
53
|
+
const options: ComboboxOption[] = [
|
|
54
|
+
// Grouped — the flat row cannot survive the full named vocabulary.
|
|
55
|
+
...EASE_PRESETS.map((p) => ({
|
|
56
|
+
value: p.id,
|
|
57
|
+
label: p.label,
|
|
58
|
+
group: EASE_GROUP_LABELS[p.group ?? "basic"],
|
|
59
|
+
})),
|
|
60
|
+
// NOT PRESETS, and not selectable in any useful sense: "custom" is a
|
|
61
|
+
// hand-dragged bezier and "mixed" is no ease at all. They are listed only
|
|
62
|
+
// so the closed picker can NAME what it is showing: a value with no option
|
|
63
|
+
// behind it would read as the raw string. Choosing one is a no-op below,
|
|
64
|
+
// which is what the disabled <option> they replace did.
|
|
65
|
+
...(sel.selectValue === "custom" ? [{ value: "custom", label: "Custom" }] : []),
|
|
66
|
+
...(sel.selectValue === "mixed" ? [{ value: "mixed", label: "Mixed" }] : []),
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
<InspectorRow label="Ease">
|
|
72
|
+
<Combobox
|
|
73
|
+
ariaLabel={props.ariaLabel ?? "Camera move ease"}
|
|
74
|
+
options={options}
|
|
75
|
+
value={sel.selectValue}
|
|
76
|
+
onChange={(next) => {
|
|
77
|
+
const preset = EASE_PRESETS.find((p) => p.id === next);
|
|
78
|
+
if (preset !== undefined) props.onEase(preset.ease);
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
81
|
+
</InspectorRow>
|
|
82
|
+
{sel.ease?.type === "bezier" && <BezierPad handles={sel.ease.handles} onEase={props.onScrub} />}
|
|
83
|
+
{sel.ease?.type === "spring" && <SpringFields spring={sel.ease} onEase={props.onEase} onScrub={props.onScrub} />}
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The bezier handle editor.
|
|
90
|
+
*
|
|
91
|
+
* ONE DRAG IS ONE UNDO ENTRY. Every move emits an ease, and each caller's verb
|
|
92
|
+
* (`setSceneTransition`, `setShotEase`) captures into the open
|
|
93
|
+
* gesture when there is one. So the drag opens an inspector scrub on press and
|
|
94
|
+
* closes it on release: without it each pointermove was its own transaction
|
|
95
|
+
* and one drag flooded the history. A cancel, a lost capture or an unmount
|
|
96
|
+
* mid-drag discards, which restores the pre-drag ease exactly.
|
|
97
|
+
*
|
|
98
|
+
* A viewer's locked panel draws the curve and its handles and takes no press:
|
|
99
|
+
* the handles carry no listeners and `pointer-events: none`, so neither a
|
|
100
|
+
* drag nor the grab cursor offers a change the store would refuse.
|
|
101
|
+
*/
|
|
102
|
+
function BezierPad(props: {
|
|
103
|
+
handles: readonly [number, number, number, number];
|
|
104
|
+
onEase(ease: Ease): void;
|
|
105
|
+
}) {
|
|
106
|
+
const store = useStore();
|
|
107
|
+
const locked = useLocked();
|
|
108
|
+
const svgRef = useRef<SVGSVGElement | null>(null);
|
|
109
|
+
const drag = useRef<{ index: 0 | 1; base: [number, number, number, number] } | null>(null);
|
|
110
|
+
// An unmount mid-drag (the subject changed under the pointer) cancels.
|
|
111
|
+
useEffect(
|
|
112
|
+
() => () => {
|
|
113
|
+
if (drag.current === null) return;
|
|
114
|
+
drag.current = null;
|
|
115
|
+
store.endScrub(false);
|
|
116
|
+
},
|
|
117
|
+
[store],
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const down =
|
|
121
|
+
(index: 0 | 1) =>
|
|
122
|
+
(e: ReactPointerEvent<SVGCircleElement>): void => {
|
|
123
|
+
if (e.button !== 0) return;
|
|
124
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
125
|
+
const h = props.handles;
|
|
126
|
+
drag.current = { index, base: [h[0], h[1], h[2], h[3]] };
|
|
127
|
+
store.beginScrub();
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const move = (e: ReactPointerEvent<SVGCircleElement>): void => {
|
|
131
|
+
const d = drag.current;
|
|
132
|
+
const svg = svgRef.current;
|
|
133
|
+
if (d === null || svg === null) return;
|
|
134
|
+
const rect = svg.getBoundingClientRect();
|
|
135
|
+
const [x, y] = pxToPad(PAD_GEOM, e.clientX - rect.left, e.clientY - rect.top);
|
|
136
|
+
// Rebuilt from the DRAG-START handles, so the untouched one cannot creep as
|
|
137
|
+
// the live value it is being compared against changes underneath.
|
|
138
|
+
const handles: [number, number, number, number] =
|
|
139
|
+
d.index === 0 ? [x, y, d.base[2], d.base[3]] : [d.base[0], d.base[1], x, y];
|
|
140
|
+
props.onEase({ type: "bezier", handles });
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const up = (e: ReactPointerEvent<SVGCircleElement>): void => {
|
|
144
|
+
if (drag.current === null) return;
|
|
145
|
+
drag.current = null;
|
|
146
|
+
store.endScrub(true);
|
|
147
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const h = props.handles;
|
|
151
|
+
const [ax, ay] = padToPx(PAD_GEOM, 0, 0);
|
|
152
|
+
const [bx, by] = padToPx(PAD_GEOM, 1, 1);
|
|
153
|
+
const [x1, y1] = padToPx(PAD_GEOM, h[0], h[1]);
|
|
154
|
+
const [x2, y2] = padToPx(PAD_GEOM, h[2], h[3]);
|
|
155
|
+
const cancel = (): void => {
|
|
156
|
+
if (drag.current === null) return;
|
|
157
|
+
drag.current = null;
|
|
158
|
+
store.endScrub(false);
|
|
159
|
+
};
|
|
160
|
+
const handle = (index: 0 | 1) =>
|
|
161
|
+
locked
|
|
162
|
+
? { className: "insp-pad-handle", r: 4.5, pointerEvents: "none" }
|
|
163
|
+
: {
|
|
164
|
+
className: "insp-pad-handle",
|
|
165
|
+
r: 4.5,
|
|
166
|
+
onPointerDown: down(index),
|
|
167
|
+
onPointerMove: move,
|
|
168
|
+
onPointerUp: up,
|
|
169
|
+
onPointerCancel: cancel,
|
|
170
|
+
// CAPTURE LOSS closes the gesture too, the same pairing `NumberField`'s
|
|
171
|
+
// drag keeps. Without it a lost capture leaves `drag` armed with no
|
|
172
|
+
// pointer down, and the next hover across the handle drags it. After
|
|
173
|
+
// a normal pointerup the ref is already null, so the trailing event
|
|
174
|
+
// is a no-op.
|
|
175
|
+
onLostPointerCapture: cancel,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<svg ref={svgRef} className="insp-pad" width={PAD_GEOM.width} height={PAD_GEOM.height}>
|
|
180
|
+
<rect
|
|
181
|
+
className="insp-pad-box"
|
|
182
|
+
x={0.5}
|
|
183
|
+
y={PAD_GEOM.padY + 0.5}
|
|
184
|
+
width={PAD_GEOM.width - 1}
|
|
185
|
+
height={PAD_GEOM.height - 2 * PAD_GEOM.padY - 1}
|
|
186
|
+
rx={3}
|
|
187
|
+
/>
|
|
188
|
+
<path className="insp-pad-curve" d={`M ${ax} ${ay} C ${x1} ${y1} ${x2} ${y2} ${bx} ${by}`} />
|
|
189
|
+
<line className="insp-pad-arm" x1={ax} y1={ay} x2={x1} y2={y1} />
|
|
190
|
+
<line className="insp-pad-arm" x1={bx} y1={by} x2={x2} y2={y2} />
|
|
191
|
+
<circle {...handle(0)} cx={x1} cy={y1} />
|
|
192
|
+
<circle {...handle(1)} cx={x2} cy={y2} />
|
|
193
|
+
</svg>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const SPRING_FIELDS = {
|
|
198
|
+
stiffness: { label: "Stiffness", min: 1, max: 1000, step: 1 },
|
|
199
|
+
damping: { label: "Damping", min: 0, max: 200, step: 0.5 },
|
|
200
|
+
mass: { label: "Mass", min: 0.05, max: 20, step: 0.05 },
|
|
201
|
+
} as const;
|
|
202
|
+
|
|
203
|
+
/** The spring's rows: Stiffness | Damping, then Mass. The two-box rule: three
|
|
204
|
+
* word labels in one row left each box about 70px at the rail's 264px floor,
|
|
205
|
+
* and "Stiffness" with its value clipped. */
|
|
206
|
+
const SPRING_ROWS: ReadonlyArray<ReadonlyArray<keyof typeof SPRING_FIELDS>> = [["stiffness", "damping"], ["mass"]];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The spring's three numbers. A DRAG is one undo entry that moves the stage
|
|
210
|
+
* under the pointer, the bezier pad's rule: the panel scrub opens on the
|
|
211
|
+
* drag, every move goes through `onScrub`, whose verb (`setShotEase`,
|
|
212
|
+
* `setSceneTransition`) captures into it, and the release closes it.
|
|
213
|
+
*/
|
|
214
|
+
function SpringFields(props: { spring: SpringEase; onEase(ease: Ease): void; onScrub(ease: Ease): void }) {
|
|
215
|
+
const store = useStore();
|
|
216
|
+
const field = (key: keyof typeof SPRING_FIELDS) => {
|
|
217
|
+
const f = SPRING_FIELDS[key];
|
|
218
|
+
const ease = (v: number): Ease => ({ ...SPRING_DEFAULT, ...props.spring, [key]: v });
|
|
219
|
+
return (
|
|
220
|
+
<NumberField
|
|
221
|
+
key={key}
|
|
222
|
+
value={props.spring[key]}
|
|
223
|
+
label={f.label}
|
|
224
|
+
ariaLabel={`Spring ${f.label.toLowerCase()}`}
|
|
225
|
+
min={f.min}
|
|
226
|
+
max={f.max}
|
|
227
|
+
step={f.step}
|
|
228
|
+
onScrubStart={() => store.beginScrub()}
|
|
229
|
+
onScrub={(v) => props.onScrub(ease(v))}
|
|
230
|
+
onScrubEnd={(commit) => store.endScrub(commit)}
|
|
231
|
+
onCommit={(v) => props.onEase(ease(v))}
|
|
232
|
+
/>
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
return (
|
|
236
|
+
<>
|
|
237
|
+
{SPRING_ROWS.map((row) => (
|
|
238
|
+
<InspectorRow key={row.join("|")}>
|
|
239
|
+
{row.length === 1 ? field(row[0]!) : <div className="insp-vec">{row.map(field)}</div>}
|
|
240
|
+
</InspectorRow>
|
|
241
|
+
))}
|
|
242
|
+
</>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// MOTION: one-click entrances, loops and exits, as STAMPS (motionPresets.ts).
|
|
2
|
+
//
|
|
3
|
+
// Picking a preset writes ordinary keyframes on every selected layer and
|
|
4
|
+
// selects them; nothing is stored about the preset. So this section never
|
|
5
|
+
// shows "In: Rise" afterwards, and has no state of its own to keep in step
|
|
6
|
+
// with the document: the diamonds, the dock and Graph mode are the record.
|
|
7
|
+
// Each row is always an offer ("Add an entrance"), never a current value.
|
|
8
|
+
//
|
|
9
|
+
// THE LIST IS WHAT EVERY SELECTED LAYER CAN TAKE (`motionPresetRefusal`), so a
|
|
10
|
+
// Draw on is offered only over a spline and a Count up only over a component
|
|
11
|
+
// with a numeric progress. The stamp asks again at write time with the window,
|
|
12
|
+
// and its refusal is the error line's.
|
|
13
|
+
//
|
|
14
|
+
// Length and Ease apply to the next pick. "Preset's own" is each preset's
|
|
15
|
+
// default; a During loop fills the gap around the playhead whatever its length.
|
|
16
|
+
//
|
|
17
|
+
// The active row PREVIEWS on the stage (bridge v53), the font picker's model:
|
|
18
|
+
// nothing writes until a pick.
|
|
19
|
+
import { useMemo, useState } from "react";
|
|
20
|
+
import { Combobox, InspectorRow, InspectorSection, useLocked } from "@dailies-studio/ui";
|
|
21
|
+
import type { ComboboxOption } from "@dailies-studio/ui";
|
|
22
|
+
import { EASE_GROUP_LABELS, EASE_PRESETS } from "@dailies-studio/timeline";
|
|
23
|
+
import { MOTION_PRESETS, homeOf, motionPresetRefusal } from "@dailies-studio/shot/doc";
|
|
24
|
+
import type { Layer3D, MotionPresetRequest, MotionPresetSlot } from "@dailies-studio/shot/doc";
|
|
25
|
+
import { useShotEditor, useStore } from "../../../state/context.js";
|
|
26
|
+
import { formatDuration } from "../../timeline/model.js";
|
|
27
|
+
|
|
28
|
+
const SLOTS: readonly { slot: MotionPresetSlot; label: string; placeholder: string }[] = [
|
|
29
|
+
{ slot: "in", label: "In", placeholder: "Add an entrance" },
|
|
30
|
+
{ slot: "during", label: "During", placeholder: "Add a loop" },
|
|
31
|
+
{ slot: "out", label: "Out", placeholder: "Add an exit" },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
/** Lengths offered for In and Out, seconds. */
|
|
35
|
+
const LENGTHS_S = [0.2, 0.33, 0.5, 0.75, 1, 1.5, 2] as const;
|
|
36
|
+
const OWN = "";
|
|
37
|
+
|
|
38
|
+
export function PresetsSection() {
|
|
39
|
+
const store = useStore();
|
|
40
|
+
const locked = useLocked();
|
|
41
|
+
const doc = useShotEditor((s) => s.doc);
|
|
42
|
+
const container = useShotEditor((s) => s.editingDef ?? s.sceneId);
|
|
43
|
+
const selection = useShotEditor((s) => s.selection);
|
|
44
|
+
const contracts = useShotEditor((s) => s.contracts);
|
|
45
|
+
const [lengthS, setLengthS] = useState(OWN);
|
|
46
|
+
const [easeId, setEaseId] = useState(OWN);
|
|
47
|
+
|
|
48
|
+
// The STORED layers: `motionPresetRefusal` reads the document's own fields,
|
|
49
|
+
// not the track-resolved values the other sections show.
|
|
50
|
+
const layers = useMemo((): Layer3D[] => {
|
|
51
|
+
if (doc === null || container === null) return [];
|
|
52
|
+
const home = homeOf(doc, container);
|
|
53
|
+
return home === null ? [] : selection.map((id) => home.layersById[id]).filter((l): l is Layer3D => l !== undefined);
|
|
54
|
+
}, [doc, container, selection]);
|
|
55
|
+
|
|
56
|
+
const offered = useMemo(() => {
|
|
57
|
+
const out = new Map<MotionPresetSlot, ComboboxOption[]>();
|
|
58
|
+
if (doc === null || container === null || layers.length === 0) return out;
|
|
59
|
+
for (const preset of MOTION_PRESETS) {
|
|
60
|
+
const fits = layers.every(
|
|
61
|
+
(layer) =>
|
|
62
|
+
motionPresetRefusal(doc, container, layer, preset.id, layer.kind === "instance" ? contracts[layer.instance.component] : undefined) === null,
|
|
63
|
+
);
|
|
64
|
+
if (!fits) continue;
|
|
65
|
+
out.set(preset.slot, [...(out.get(preset.slot) ?? []), { value: preset.id, label: preset.label }]);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}, [doc, container, layers, contracts]);
|
|
69
|
+
|
|
70
|
+
if (doc === null || layers.length === 0) return null;
|
|
71
|
+
const fps = doc.fps.num / doc.fps.den;
|
|
72
|
+
const easeOptions: ComboboxOption[] = [
|
|
73
|
+
{ value: OWN, label: "Preset's own" },
|
|
74
|
+
...EASE_PRESETS.map((p) => ({ value: p.id, label: p.label, group: EASE_GROUP_LABELS[p.group ?? "basic"] })),
|
|
75
|
+
];
|
|
76
|
+
const lengthOptions: ComboboxOption[] = [
|
|
77
|
+
{ value: OWN, label: "Preset's own" },
|
|
78
|
+
...LENGTHS_S.map((s) => ({ value: String(s), label: formatDuration(s) })),
|
|
79
|
+
];
|
|
80
|
+
const request = (preset: string): Omit<MotionPresetRequest, "at"> => {
|
|
81
|
+
const ease = EASE_PRESETS.find((p) => p.id === easeId)?.ease;
|
|
82
|
+
return {
|
|
83
|
+
preset,
|
|
84
|
+
...(lengthS === OWN ? {} : { lengthFrames: Math.max(1, Math.round(Number(lengthS) * fps)) }),
|
|
85
|
+
...(ease === undefined ? {} : { ease }),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const hasText = layers.some((l) => l.kind === "text");
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<InspectorSection
|
|
92
|
+
title="Motion"
|
|
93
|
+
persistKey="shot:presets"
|
|
94
|
+
note="· writes keyframes"
|
|
95
|
+
>
|
|
96
|
+
{SLOTS.map(({ slot, label, placeholder }) => {
|
|
97
|
+
const options = offered.get(slot) ?? [];
|
|
98
|
+
return (
|
|
99
|
+
<InspectorRow key={slot} label={label}>
|
|
100
|
+
<Combobox
|
|
101
|
+
ariaLabel={`${label} preset`}
|
|
102
|
+
options={options}
|
|
103
|
+
value=""
|
|
104
|
+
placeholder={options.length === 0 ? "None fits this selection" : placeholder}
|
|
105
|
+
disabled={options.length === 0}
|
|
106
|
+
onChange={(id) => void store.applyMotionPreset(request(id))}
|
|
107
|
+
onActive={(id) => store.previewMotion(id === null ? null : request(id))}
|
|
108
|
+
/>
|
|
109
|
+
</InspectorRow>
|
|
110
|
+
);
|
|
111
|
+
})}
|
|
112
|
+
<InspectorRow label="Length">
|
|
113
|
+
<Combobox ariaLabel="Preset length" options={lengthOptions} value={lengthS} onChange={setLengthS} />
|
|
114
|
+
</InspectorRow>
|
|
115
|
+
<InspectorRow label="Ease">
|
|
116
|
+
<Combobox ariaLabel="Preset ease" options={easeOptions} value={easeId} onChange={setEaseId} />
|
|
117
|
+
</InspectorRow>
|
|
118
|
+
{hasText ? (
|
|
119
|
+
<InspectorRow label="Letters">
|
|
120
|
+
<div className="insp-buttons">
|
|
121
|
+
<button
|
|
122
|
+
type="button"
|
|
123
|
+
className="btn"
|
|
124
|
+
disabled={locked}
|
|
125
|
+
title="Per-letter and per-word reveals are library components: typewriter-text, word-stream, rise-per-char"
|
|
126
|
+
onClick={() => store.setLibraryBrowserOpen(true, "component")}
|
|
127
|
+
>
|
|
128
|
+
Per-letter effects in the Library
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
</InspectorRow>
|
|
132
|
+
) : null}
|
|
133
|
+
</InspectorSection>
|
|
134
|
+
);
|
|
135
|
+
}
|