dsh-drawai 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/README.md +96 -253
  2. package/lib/client.js +28 -7
  3. package/lib/index.js +474 -97
  4. package/lib/motion/asset-pack.js +109 -50
  5. package/lib/motion/assets.js +291 -291
  6. package/lib/motion/demo-assets-lock.js +10 -0
  7. package/lib/motion/mgstyles/vendor/README.md +28 -0
  8. package/lib/motion/mgstyles/vendor/modules/d3/LICENSE +13 -0
  9. package/lib/motion/mgstyles/vendor/modules/d3/dist/d3.min.js +2 -0
  10. package/lib/motion/mgstyles/vendor/modules/opentype.js/LICENSE +20 -0
  11. package/lib/motion/mgstyles/vendor/modules/opentype.js/dist/opentype.mjs +14460 -0
  12. package/lib/motion/mgstyles/vendor/modules/simplex-noise/LICENSE +21 -0
  13. package/lib/motion/mgstyles/vendor/modules/simplex-noise/dist/esm/simplex-noise.js +466 -0
  14. package/lib/motion/mgstyles/vendor/modules/topojson-client/LICENSE +13 -0
  15. package/lib/motion/mgstyles/vendor/modules/topojson-client/dist/topojson-client.min.js +2 -0
  16. package/lib/motion/preview.js +10 -3
  17. package/lib/motion/render.js +19 -1
  18. package/lib/motion/shotcraft/upstream/SKILL.md +286 -286
  19. package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -54
  20. package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -200
  21. package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -45
  22. package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -20
  23. package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -65
  24. package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -151
  25. package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -129
  26. package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -75
  27. package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -40
  28. package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -11
  29. package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -10
  30. package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -49
  31. package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -210
  32. package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -423
  33. package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -170
  34. package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -157
  35. package/lib/motion/shotcraft/upstream/demos/README.md +120 -120
  36. package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -112
  37. package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -647
  38. package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -316
  39. package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -82
  40. package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -115
  41. package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -243
  42. package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +388 -388
  43. package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -250
  44. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -305
  45. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -246
  46. package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -390
  47. package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -138
  48. package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -542
  49. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -315
  50. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -299
  51. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -173
  52. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -348
  53. package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -366
  54. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -279
  55. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -184
  56. package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -390
  57. package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -155
  58. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -303
  59. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -290
  60. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -278
  61. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -307
  62. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -215
  63. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -299
  64. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -232
  65. package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -290
  66. package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -273
  67. package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -167
  68. package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -536
  69. package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -164
  70. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -175
  71. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -197
  72. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -241
  73. package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -279
  74. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -230
  75. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -345
  76. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -275
  77. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -229
  78. package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -312
  79. package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -222
  80. package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -295
  81. package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -329
  82. package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -315
  83. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -264
  84. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -260
  85. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -263
  86. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -123
  87. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -187
  88. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -175
  89. package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -305
  90. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -350
  91. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -352
  92. package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -218
  93. package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -297
  94. package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -157
  95. package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -218
  96. package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -202
  97. package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -265
  98. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -457
  99. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -446
  100. package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -249
  101. package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -278
  102. package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -332
  103. package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -358
  104. package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -201
  105. package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -200
  106. package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -208
  107. package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -341
  108. package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -389
  109. package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -293
  110. package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -183
  111. package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -245
  112. package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -222
  113. package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -223
  114. package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -217
  115. package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -343
  116. package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -357
  117. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -187
  118. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -333
  119. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -274
  120. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -270
  121. package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -430
  122. package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -252
  123. package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -106
  124. package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -288
  125. package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -362
  126. package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -168
  127. package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -310
  128. package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -261
  129. package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -459
  130. package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -294
  131. package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -161
  132. package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -248
  133. package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -359
  134. package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -227
  135. package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -162
  136. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -248
  137. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -186
  138. package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -355
  139. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -272
  140. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -262
  141. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -217
  142. package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -285
  143. package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -205
  144. package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -178
  145. package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -147
  146. package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -143
  147. package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -134
  148. package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -217
  149. package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -198
  150. package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -221
  151. package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -312
  152. package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -261
  153. package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -121
  154. package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -153
  155. package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -179
  156. package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -140
  157. package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -309
  158. package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -191
  159. package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -292
  160. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -135
  161. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -124
  162. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -255
  163. package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -173
  164. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -225
  165. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -141
  166. package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -137
  167. package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -147
  168. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -409
  169. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -280
  170. package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -271
  171. package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -385
  172. package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -312
  173. package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -303
  174. package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -77
  175. package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -311
  176. package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -307
  177. package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -349
  178. package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -255
  179. package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -244
  180. package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -217
  181. package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -652
  182. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -153
  183. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -238
  184. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -324
  185. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -354
  186. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -101
  187. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -129
  188. package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -297
  189. package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -57
  190. package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -155
  191. package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -175
  192. package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -153
  193. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -146
  194. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -226
  195. package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -1
  196. package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -193
  197. package/lib/motion/shotcraft/upstream/references/final-review.md +121 -121
  198. package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -199
  199. package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -183
  200. package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -257
  201. package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -382
  202. package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -111
  203. package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -50
  204. package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -95
  205. package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -41
  206. package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -52
  207. package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -39
  208. package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -39
  209. package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -57
  210. package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -51
  211. package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -46
  212. package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -52
  213. package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -43
  214. package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -42
  215. package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -48
  216. package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -52
  217. package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -45
  218. package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -46
  219. package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -44
  220. package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -63
  221. package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -54
  222. package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -58
  223. package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -35
  224. package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -53
  225. package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -42
  226. package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -50
  227. package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -46
  228. package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -56
  229. package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -49
  230. package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -50
  231. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -53
  232. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -53
  233. package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -55
  234. package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -52
  235. package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -60
  236. package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -57
  237. package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -51
  238. package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -41
  239. package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -53
  240. package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -60
  241. package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -55
  242. package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -57
  243. package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -47
  244. package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -37
  245. package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -54
  246. package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -36
  247. package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -56
  248. package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -56
  249. package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -40
  250. package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -60
  251. package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -57
  252. package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -73
  253. package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -87
  254. package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -55
  255. package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -50
  256. package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -59
  257. package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -38
  258. package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -38
  259. package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -59
  260. package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -39
  261. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -61
  262. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -52
  263. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -50
  264. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -66
  265. package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -43
  266. package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -38
  267. package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -38
  268. package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -56
  269. package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -44
  270. package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -38
  271. package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -63
  272. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -57
  273. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -63
  274. package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -58
  275. package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -45
  276. package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -55
  277. package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -49
  278. package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -42
  279. package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -42
  280. package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -45
  281. package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -48
  282. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -55
  283. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -43
  284. package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -41
  285. package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -42
  286. package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -59
  287. package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -55
  288. package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -65
  289. package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -42
  290. package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -64
  291. package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -64
  292. package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -54
  293. package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -91
  294. package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -51
  295. package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -66
  296. package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -38
  297. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -66
  298. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -58
  299. package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -61
  300. package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -64
  301. package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -45
  302. package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -41
  303. package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -51
  304. package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -42
  305. package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -63
  306. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -57
  307. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -75
  308. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -59
  309. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -67
  310. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -60
  311. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -66
  312. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -40
  313. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -45
  314. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -62
  315. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -55
  316. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -37
  317. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -55
  318. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -50
  319. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -43
  320. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -55
  321. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -51
  322. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -51
  323. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -56
  324. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -49
  325. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -57
  326. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -36
  327. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -64
  328. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -47
  329. package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -170
  330. package/lib/motion/shotcraft/upstream/references/workbench.md +157 -157
  331. package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -103
  332. package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -44
  333. package/lib/motion/shotcraft/upstream/template/package.json +20 -20
  334. package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -6
  335. package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -17
  336. package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -65
  337. package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -48
  338. package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -24
  339. package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -192
  340. package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -111
  341. package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -150
  342. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -158
  343. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -468
  344. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -552
  345. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -411
  346. package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -200
  347. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -324
  348. package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +388 -388
  349. package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -4
  350. package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -7
  351. package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -68
  352. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -1
  353. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -24
  354. package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -74
  355. package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -91
  356. package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -213
  357. package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -15
  358. package/lib/motion/style-frames.js +47 -12
  359. package/lib/motion-project.js +22 -3
  360. package/lib/motion-render-worker.js +31 -9
  361. package/lib/routing/router.js +12 -1
  362. package/lib/style-kernel.js +16 -6
  363. package/lib/video-trace-pool.js +128 -128
  364. package/package.json +1 -1
  365. package/LICENSE +0 -4175
@@ -1,357 +1,357 @@
1
- // ui-strip-away-outro —— framer-ai 33–36.5s
2
- // 满屏"编辑器"里光标点击高亮 Publish 按钮 → UI 层层错峰蒸发退场
3
- // (每层 fade + 方向性位移 + 蒸发模糊,从外围到中心)→ 黑场只剩按钮 → 按钮淡出交棒字标。
4
- // 质感:编辑器是出版级假 UI(深色图层栏、属性面板真实字段、点阵画布、浏览器预览框里放
5
- // fixture 卡片),发丝线 + 双层软阴影;Publish 用强调色,升格到黑场后带同色光晕;
6
- // 黑场是带色相的深场(中心微光 + 暗角 + 颗粒);字标是 video-shotcraft 标志 + 字标的 lockup,对焦式入场。
7
- // 品牌轮:编辑器即 video-shotcraft 工作台(图层 = 一支发布片的镜头),工具条 logo / 收尾 lockup 用「镜刻」标志。
8
- import React from 'react';
9
- import { AbsoluteFill, useCurrentFrame, interpolate, spring, useVideoConfig, Easing } from 'remotion';
10
- import { G, Card } from '../../_fixtures/Fixtures';
11
- import { EASE, FONT, Grain, Vignette, mix, ramp, hairline, softShadow, innerHighlight } from '../../_fixtures/Polish';
12
- import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
13
-
14
- export const UI_STRIP_AWAY_OUTRO_DURATION = 144; // 字标定版后 hold ≥1s(R1)
15
-
16
- const CLICK = 34; // 点击时刻
17
- // 蒸发层级(点击后延迟,外围先走)
18
- const STRIP = {
19
- sidebar: CLICK + 4,
20
- leftPanel: CLICK + 8,
21
- canvasCards: CLICK + 12,
22
- topbarEnds: CLICK + 16,
23
- canvasBg: CLICK + 20,
24
- toolbarShell: CLICK + 24,
25
- };
26
- const STRIP_DUR = 14;
27
- const BTN_FADE = CLICK + 52;
28
- const LOGO_IN = CLICK + 62;
29
-
30
- const ACCENT = G.accent; // Publish 的品牌高亮色
31
- const INK = '#0b0c10'; // 黑场:带冷色相的近黑
32
- // Publish 按钮几何:工具条右端 → 屏心
33
- const BTN_W = 150;
34
- const BTN_H = 40;
35
- const BTN_FROM = { x: 1920 - 24 - BTN_W / 2, y: 30 };
36
- const BTN_TO = { x: 960, y: 540 };
37
-
38
- // 某层的蒸发进度 → {opacity, transform, filter}:ease-in 加速离场 + 位移 + 渐增模糊(蒸发感)
39
- const strip = (frame: number, start: number, dx: number, dy: number): React.CSSProperties => {
40
- const p = interpolate(frame, [start, start + STRIP_DUR], [0, 1], {
41
- extrapolateLeft: 'clamp',
42
- extrapolateRight: 'clamp',
43
- easing: Easing.in(Easing.quad), // 离场加速
44
- });
45
- return {
46
- opacity: 1 - p,
47
- transform: `translate(${dx * p}px, ${dy * p}px)`,
48
- filter: p > 0.001 ? `blur(${(p * 7).toFixed(2)}px)` : undefined,
49
- };
50
- };
51
-
52
- // —— 小图标(1.5px 线性图标,与 fixture 同语言)——
53
- const Icon: React.FC<{ d: string; size?: number; color?: string }> = ({ d, size = 18, color = G.ink2 }) => (
54
- <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={1.7} strokeLinecap="round" strokeLinejoin="round">
55
- <path d={d} />
56
- </svg>
57
- );
58
- const IC = {
59
- cursor: 'M5 3l13 8-6 1.5L9 19z',
60
- frame: 'M7 3v18M17 3v18M3 7h18M3 17h18',
61
- text: 'M5 6V4h14v2M12 4v16M9 20h6',
62
- pen: 'M12 19l7-7-3-3-7 7-1 4zM14 7l3 3',
63
- image: 'M4 5h16v14H4zM4 16l5-5 4 4 3-3 4 4',
64
- comp: 'M12 3l4 4-4 4-4-4zM12 13l4 4-4 4-4-4z',
65
- layer: 'M4 7h16v10H4z',
66
- textL: 'M6 7V5h12v2M12 5v14',
67
- group: 'M4 6h7v5H4zM13 6h7v5h-7zM4 13h16v5H4z',
68
- };
69
-
70
- const LAYERS: [string, string, number, boolean?][] = [
71
- ['frame', 'Launch film', 0],
72
- ['layer', 'Cold open', 1],
73
- ['group', 'Hero shot', 1],
74
- ['textL', 'Title card', 2],
75
- ['textL', 'Subtitle', 2],
76
- ['group', 'Feature shots', 1, true],
77
- ['layer', 'Shot — Crash zoom', 2],
78
- ['layer', 'Shot — Dolly push', 2],
79
- ['layer', 'Shot — Whip pan', 2],
80
- ['layer', 'Shot — Beat cut', 2],
81
- ['layer', 'Logo sting', 1],
82
- ];
83
-
84
- const Field: React.FC<{ label: string; value: string; w?: number }> = ({ label, value, w }) => (
85
- <div style={{
86
- height: 34, flex: w ? 'none' : 1, width: w, borderRadius: 8, background: G.fill, border: hairline(0.07),
87
- display: 'flex', alignItems: 'center', gap: 8, padding: '0 10px', boxSizing: 'border-box',
88
- fontFamily: FONT.sans, fontSize: 13, fontVariantNumeric: 'tabular-nums',
89
- }}>
90
- <span style={{ color: G.ink3 }}>{label}</span>
91
- <span style={{ color: G.ink1, fontWeight: 500 }}>{value}</span>
92
- </div>
93
- );
94
-
95
- const Section: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (
96
- <div style={{ display: 'flex', flexDirection: 'column', gap: 10, paddingBottom: 18, borderBottom: hairline(0.07) }}>
97
- <div style={{ fontFamily: FONT.sans, fontSize: 12, fontWeight: 600, color: G.ink1, letterSpacing: '0.01em' }}>{title}</div>
98
- {children}
99
- </div>
100
- );
101
-
102
- export const UiStripAwayOutro: React.FC = () => {
103
- const frame = useCurrentFrame();
104
- const { fps } = useVideoConfig();
105
-
106
- // 背景:编辑器底 → 黑场(随 canvasBg 层蒸发压黑)
107
- const bgDark = interpolate(frame, [STRIP.canvasBg, STRIP.canvasBg + STRIP_DUR + 6], [0, 1], {
108
- extrapolateLeft: 'clamp',
109
- extrapolateRight: 'clamp',
110
- easing: Easing.inOut(Easing.quad),
111
- });
112
-
113
- const sidebar = strip(frame, STRIP.sidebar, -140, 0);
114
- const leftPanel = strip(frame, STRIP.leftPanel, -90, 20);
115
- const topLeft = strip(frame, STRIP.topbarEnds, -80, -60);
116
- const topRight = strip(frame, STRIP.topbarEnds, 80, -60);
117
- const toolbarShell = strip(frame, STRIP.toolbarShell, 0, -50);
118
- const canvasFrame = strip(frame, STRIP.canvasBg, 0, 40);
119
-
120
- // 画布卡片错峰蒸发(各错 3f,左右交替散开)
121
- const cardStrip = (i: number) => strip(frame, STRIP.canvasCards + i * 3, i % 2 ? 70 : -70, 50 + i * 10);
122
-
123
- // 按钮:点击脉冲 + 最后淡出
124
- const press = spring({ frame: frame - CLICK, fps, config: { damping: 12, stiffness: 220 } });
125
- const pressScale = frame < CLICK ? 1 : 1 - 0.12 * Math.sin(Math.min(1, press) * Math.PI);
126
- const btnOp = 1 - ramp(frame, BTN_FADE, 12, EASE.exit);
127
- // 蒸发期间按钮从工具条位置滑向屏幕中心,独占黑场
128
- const btnCenter = interpolate(frame, [STRIP.toolbarShell, STRIP.toolbarShell + 18], [0, 1], {
129
- extrapolateLeft: 'clamp',
130
- extrapolateRight: 'clamp',
131
- easing: Easing.inOut(Easing.cubic),
132
- });
133
- const btnX = mix(BTN_FROM.x, BTN_TO.x, btnCenter);
134
- const btnY = mix(BTN_FROM.y, BTN_TO.y, btnCenter);
135
- const btnScale = 1 + 0.5 * btnCenter;
136
- // 迁移最快段的方向性拖影(按每帧位移给模糊,静止为 0)
137
- const dPrev = interpolate(frame - 1, [STRIP.toolbarShell, STRIP.toolbarShell + 18], [0, 1], {
138
- extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.inOut(Easing.cubic),
139
- });
140
- const btnSpeed = Math.hypot(BTN_TO.x - BTN_FROM.x, BTN_TO.y - BTN_FROM.y) * Math.abs(btnCenter - dPrev);
141
- const btnBlur = Math.min(3, btnSpeed * 0.04);
142
- // 按钮淡出时略微放大"化开",把黑场交给字标
143
- const btnRelease = ramp(frame, BTN_FADE, 12, EASE.out);
144
-
145
- // 字标接棒:spring 定版 + 对焦模糊;字标比图形晚 3f(跟随)
146
- const logoP = spring({ frame: frame - LOGO_IN, fps, config: { damping: 14, stiffness: 90 } });
147
- const wordP = spring({ frame: frame - LOGO_IN - 3, fps, config: { damping: 14, stiffness: 90 } });
148
-
149
- // 光标移向按钮:x、y 用不同缓动,走一条手腕带出的弧线;点击时笔尖压下
150
- const curX = interpolate(frame, [4, CLICK - 2], [820, BTN_FROM.x + 18], {
151
- extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.inOut(Easing.quad),
152
- });
153
- const curY = interpolate(frame, [4, CLICK - 2], [640, BTN_FROM.y + 4], {
154
- extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.bezier(0.3, 0, 0.15, 1),
155
- });
156
- const curOp = 1 - ramp(frame, CLICK + 6, 10, EASE.out);
157
- const curPress = frame >= CLICK - 1 && frame < CLICK + 3 ? 0.88 : 1;
158
-
159
- const toolbarBase: React.CSSProperties = {
160
- position: 'absolute', top: 0, height: 60, background: '#fbfbfa', borderBottom: hairline(0.08),
161
- boxSizing: 'border-box', display: 'flex', alignItems: 'center', fontFamily: FONT.sans,
162
- };
163
-
164
- return (
165
- <AbsoluteFill style={{ background: INK, overflow: 'hidden' }}>
166
- {/* 黑场:中心极弱冷光(随压黑亮起) */}
167
- <AbsoluteFill style={{
168
- opacity: bgDark,
169
- background: 'radial-gradient(ellipse 50% 45% at 50% 50%, rgba(120,128,220,0.10) 0%, rgba(120,128,220,0.03) 50%, rgba(0,0,0,0) 75%)',
170
- }} />
171
-
172
- {/* 编辑器底(点阵画布,作为一层可蒸发的背景) */}
173
- <AbsoluteFill style={{
174
- opacity: 1 - bgDark,
175
- backgroundColor: '#ececea',
176
- backgroundImage: 'radial-gradient(rgba(20,22,28,0.10) 1px, transparent 1.2px)',
177
- backgroundSize: '24px 24px',
178
- }} />
179
-
180
- {/* 左侧栏(图层面板) */}
181
- <div style={{
182
- position: 'absolute', left: 0, top: 0, bottom: 0, width: 240, boxSizing: 'border-box', paddingTop: 76,
183
- background: 'linear-gradient(180deg, #1c1d22 0%, #16171b 100%)', boxShadow: 'inset -1px 0 0 rgba(255,255,255,0.06)',
184
- fontFamily: FONT.sans, ...sidebar,
185
- }}>
186
- <div style={{ padding: '0 18px 12px', fontSize: 11, fontWeight: 600, letterSpacing: '0.08em', color: 'rgba(255,255,255,0.36)' }}>LAYERS</div>
187
- {LAYERS.map(([ic, name, depth, sel]) => (
188
- <div key={name} style={{
189
- height: 32, margin: '0 10px', borderRadius: 7, display: 'flex', alignItems: 'center', gap: 9,
190
- paddingLeft: 10 + depth * 16, fontSize: 13, color: sel ? '#fff' : 'rgba(255,255,255,0.62)',
191
- background: sel ? 'rgba(128,136,240,0.22)' : 'transparent',
192
- boxShadow: sel ? 'inset 0 0 0 1px rgba(128,136,240,0.35)' : 'none',
193
- }}>
194
- <Icon d={IC[ic as keyof typeof IC]} size={14} color={sel ? '#c9cdff' : 'rgba(255,255,255,0.42)'} />
195
- {name}
196
- </div>
197
- ))}
198
- </div>
199
-
200
- {/* 右侧属性面板 */}
201
- <div style={{
202
- position: 'absolute', right: 0, top: 60, bottom: 0, width: 300, background: '#fbfbfa', borderLeft: hairline(0.08),
203
- padding: 22, boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 18, ...leftPanel,
204
- }}>
205
- <Section title="Frame">
206
- <div style={{ display: 'flex', gap: 8 }}><Field label="X" value="320" /><Field label="Y" value="130" /></div>
207
- <div style={{ display: 'flex', gap: 8 }}><Field label="W" value="1180" /><Field label="H" value="850" /></div>
208
- </Section>
209
- <Section title="Layout">
210
- <div style={{ display: 'flex', gap: 8 }}><Field label="Gap" value="40" /><Field label="Pad" value="70" /></div>
211
- </Section>
212
- <Section title="Fill">
213
- <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
214
- <div style={{ width: 34, height: 34, borderRadius: 8, background: '#ffffff', border: hairline(0.12), boxSizing: 'border-box' }} />
215
- <Field label="Hex" value="FFFFFF" />
216
- <Field label="" value="100%" w={64} />
217
- </div>
218
- </Section>
219
- <Section title="Effects">
220
- <div style={{ display: 'flex', gap: 8 }}><Field label="Shadow" value="Soft · 16" /></div>
221
- </Section>
222
- </div>
223
-
224
- {/* 顶部工具条左半(logo + 工具) */}
225
- <div style={{ ...toolbarBase, left: 0, width: 760, gap: 6, padding: '0 16px', ...topLeft }}>
226
- <div style={{ marginRight: 14 }}><ShotcraftMark size={34} tone="light" /></div>
227
- {[IC.cursor, IC.frame, IC.text, IC.pen, IC.image, IC.comp].map((d, i) => (
228
- <div key={i} style={{
229
- width: 36, height: 36, borderRadius: 9, display: 'flex', alignItems: 'center', justifyContent: 'center',
230
- background: i === 0 ? G.accentSoft : 'transparent',
231
- }}>
232
- <Icon d={d} size={18} color={i === 0 ? ACCENT : G.ink2} />
233
- </div>
234
- ))}
235
- </div>
236
- {/* 顶部工具条中段(标题) */}
237
- <div style={{ ...toolbarBase, left: 760, right: 400, justifyContent: 'center', gap: 10, ...toolbarShell }}>
238
- <span style={{ fontSize: 14, color: G.ink3 }}>{BRAND.name}</span>
239
- <span style={{ fontSize: 14, color: G.ink3 }}>/</span>
240
- <span style={{ fontSize: 14, color: G.ink1, fontWeight: 600, letterSpacing: '-0.01em' }}>Launch film</span>
241
- <span style={{ fontSize: 11.5, fontWeight: 500, color: G.ink2, padding: '3px 8px', borderRadius: 6, background: G.fill2 }}>Draft</span>
242
- </div>
243
- {/* 顶部工具条右段底板(头像 + Invite;Publish 单独渲染在最上层) */}
244
- <div style={{ ...toolbarBase, right: 0, width: 400, justifyContent: 'flex-end', gap: 12, padding: `0 ${24 + BTN_W + 12}px 0 24px`, ...topRight }}>
245
- <div style={{ display: 'flex' }}>
246
- {['JL', 'MR'].map((n, i) => (
247
- <div key={n} style={{
248
- width: 30, height: 30, borderRadius: 15, marginLeft: i ? -8 : 0, background: i ? '#dfe1e8' : '#e9e6df',
249
- border: '2px solid #fbfbfa', display: 'flex', alignItems: 'center', justifyContent: 'center',
250
- fontSize: 11, fontWeight: 600, color: '#4a4c53',
251
- }}>{n}</div>
252
- ))}
253
- </div>
254
- <div style={{
255
- height: 34, padding: '0 14px', borderRadius: 9, border: hairline(0.13), boxSizing: 'border-box',
256
- display: 'flex', alignItems: 'center', fontSize: 13.5, fontWeight: 500, color: G.ink1, background: '#fff',
257
- boxShadow: softShadow(1),
258
- }}>Invite</div>
259
- </div>
260
-
261
- {/* 画布区:一张浏览器式大卡 + 四张内容卡 */}
262
- <div style={{ position: 'absolute', left: 320, top: 130, width: 1180, height: 850, ...canvasFrame }}>
263
- <div style={{
264
- position: 'absolute', inset: 0, background: G.card, border: hairline(0.09), borderRadius: 18, overflow: 'hidden',
265
- boxShadow: `${innerHighlight(0.9)}, ${softShadow(22)}`,
266
- }}>
267
- <div style={{
268
- height: 46, borderBottom: hairline(0.07), display: 'flex', alignItems: 'center', gap: 8, padding: '0 18px',
269
- background: 'linear-gradient(180deg, #fbfbfa 0%, #f5f5f3 100%)',
270
- }}>
271
- {['#ec6a5e', '#f4bf4f', '#61c554'].map((c) => (
272
- <div key={c} style={{ width: 12, height: 12, borderRadius: 6, background: c, opacity: 0.85 }} />
273
- ))}
274
- <div style={{
275
- marginLeft: 16, height: 26, width: 380, background: G.fill, borderRadius: 8, display: 'flex', alignItems: 'center',
276
- padding: '0 12px', fontFamily: FONT.sans, fontSize: 12.5, color: G.ink2, gap: 6,
277
- }}>
278
- <svg width={11} height={11} viewBox="0 0 24 24" fill="none" stroke={G.ink3} strokeWidth={2.4}><rect x="5" y="11" width="14" height="10" rx="2" /><path d="M8 11V8a4 4 0 0 1 8 0v3" /></svg>
279
- {BRAND.repo}
280
- </div>
281
- </div>
282
- </div>
283
- {[0, 1, 2, 3].map((i) => {
284
- const s = cardStrip(i);
285
- return (
286
- <div key={i} style={{ position: 'absolute', left: 70 + (i % 2) * 560, top: 120 + Math.floor(i / 2) * 340, ...s }}>
287
- <Card w={480} h={280} seed={i + 2} />
288
- </div>
289
- );
290
- })}
291
- </div>
292
-
293
- {/* Publish 按钮(高亮层,最后退场):按中心定位,尺寸按布局放大(字边清晰) */}
294
- <div
295
- style={{
296
- position: 'absolute', left: btnX, top: btnY, width: 0, height: 0, zIndex: 30,
297
- opacity: btnOp, transform: `scale(${pressScale * (1 + 0.06 * btnRelease)})`,
298
- filter: btnBlur > 0.2 ? `blur(${btnBlur.toFixed(2)}px)` : undefined,
299
- }}
300
- >
301
- {/* 黑场上的主角光环:同色柔光盘,随压黑增强 */}
302
- <div style={{
303
- position: 'absolute', left: -260, top: -160, width: 520, height: 320, borderRadius: '50%',
304
- background: 'radial-gradient(ellipse at center, rgba(91,99,211,0.38) 0%, rgba(91,99,211,0.10) 40%, rgba(91,99,211,0) 70%)',
305
- opacity: btnCenter * bgDark,
306
- }} />
307
- <div
308
- style={{
309
- position: 'absolute',
310
- width: BTN_W * btnScale, height: BTN_H * btnScale,
311
- left: -(BTN_W * btnScale) / 2, top: -(BTN_H * btnScale) / 2,
312
- borderRadius: 10 * btnScale,
313
- background: 'linear-gradient(180deg, #6a72e0 0%, #545cd0 100%)',
314
- boxShadow: `inset 0 1px 0 rgba(255,255,255,0.28), inset 0 0 0 1px rgba(255,255,255,0.06), 0 1px 2px rgba(30,34,120,0.35), 0 0 ${30 + 40 * btnCenter}px rgba(110,118,240,${(0.18 + 0.4 * btnCenter * bgDark).toFixed(3)})`,
315
- display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 * btnScale,
316
- fontFamily: FONT.sans, fontWeight: 600, fontSize: 15 * btnScale, letterSpacing: '-0.01em', color: '#ffffff',
317
- }}
318
- >
319
- <svg width={14 * btnScale} height={14 * btnScale} viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth={2.4} strokeLinecap="round" strokeLinejoin="round">
320
- <path d="M12 19V5M5 12l7-7 7 7" />
321
- </svg>
322
- Publish
323
- </div>
324
- </div>
325
-
326
- {/* 字标接棒 */}
327
- {frame >= LOGO_IN && (
328
- <AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center' }}>
329
- <div style={{ display: 'flex', alignItems: 'center', gap: 30, transform: `scale(${0.86 + 0.14 * logoP})` }}>
330
- <div style={{ opacity: Math.min(1, logoP * 1.4), filter: logoP < 0.995 ? `blur(${((1 - logoP) * 9).toFixed(2)}px)` : undefined }}>
331
- <ShotcraftMark size={132} tone="dark" />
332
- </div>
333
- <div style={{
334
- opacity: Math.min(1, wordP * 1.4), transform: `translateX(${((1 - wordP) * -16).toFixed(2)}px)`,
335
- filter: wordP < 0.995 ? `blur(${((1 - wordP) * 9).toFixed(2)}px)` : undefined,
336
- fontFamily: BRAND.font, fontWeight: 700, fontSize: 68, lineHeight: 1, letterSpacing: '0.03em', color: BRAND.paper, paddingBottom: 4, whiteSpace: 'nowrap',
337
- }}>
338
- {BRAND.name}
339
- </div>
340
- </div>
341
- </AbsoluteFill>
342
- )}
343
-
344
- {/* 光标 */}
345
- <svg width={30} height={38} viewBox="0 0 14 18" style={{
346
- position: 'absolute', left: curX, top: curY, opacity: curOp, zIndex: 40,
347
- transform: `scale(${curPress})`, transformOrigin: '2px 2px', filter: 'drop-shadow(0 3px 5px rgba(16,18,24,0.3))',
348
- }}>
349
- <path d="M1 1 L1 15 L4.6 11.6 L7.2 17 L9.4 16 L6.9 10.7 L12 10.7 Z" fill="#111216" stroke="#ffffff" strokeWidth={1.1} strokeLinejoin="round" />
350
- </svg>
351
-
352
- {/* 暗角 + 颗粒:随压黑加深(亮场时几乎不压) */}
353
- <Vignette strength={0.12 + 0.45 * bgDark} inner={0.42} color="#000000" />
354
- <Grain opacity={0.05 + 0.03 * bgDark} blend="soft-light" />
355
- </AbsoluteFill>
356
- );
357
- };
1
+ // ui-strip-away-outro —— framer-ai 33–36.5s
2
+ // 满屏"编辑器"里光标点击高亮 Publish 按钮 → UI 层层错峰蒸发退场
3
+ // (每层 fade + 方向性位移 + 蒸发模糊,从外围到中心)→ 黑场只剩按钮 → 按钮淡出交棒字标。
4
+ // 质感:编辑器是出版级假 UI(深色图层栏、属性面板真实字段、点阵画布、浏览器预览框里放
5
+ // fixture 卡片),发丝线 + 双层软阴影;Publish 用强调色,升格到黑场后带同色光晕;
6
+ // 黑场是带色相的深场(中心微光 + 暗角 + 颗粒);字标是 video-shotcraft 标志 + 字标的 lockup,对焦式入场。
7
+ // 品牌轮:编辑器即 video-shotcraft 工作台(图层 = 一支发布片的镜头),工具条 logo / 收尾 lockup 用「镜刻」标志。
8
+ import React from 'react';
9
+ import { AbsoluteFill, useCurrentFrame, interpolate, spring, useVideoConfig, Easing } from 'remotion';
10
+ import { G, Card } from '../../_fixtures/Fixtures';
11
+ import { EASE, FONT, Grain, Vignette, mix, ramp, hairline, softShadow, innerHighlight } from '../../_fixtures/Polish';
12
+ import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
13
+
14
+ export const UI_STRIP_AWAY_OUTRO_DURATION = 144; // 字标定版后 hold ≥1s(R1)
15
+
16
+ const CLICK = 34; // 点击时刻
17
+ // 蒸发层级(点击后延迟,外围先走)
18
+ const STRIP = {
19
+ sidebar: CLICK + 4,
20
+ leftPanel: CLICK + 8,
21
+ canvasCards: CLICK + 12,
22
+ topbarEnds: CLICK + 16,
23
+ canvasBg: CLICK + 20,
24
+ toolbarShell: CLICK + 24,
25
+ };
26
+ const STRIP_DUR = 14;
27
+ const BTN_FADE = CLICK + 52;
28
+ const LOGO_IN = CLICK + 62;
29
+
30
+ const ACCENT = G.accent; // Publish 的品牌高亮色
31
+ const INK = '#0b0c10'; // 黑场:带冷色相的近黑
32
+ // Publish 按钮几何:工具条右端 → 屏心
33
+ const BTN_W = 150;
34
+ const BTN_H = 40;
35
+ const BTN_FROM = { x: 1920 - 24 - BTN_W / 2, y: 30 };
36
+ const BTN_TO = { x: 960, y: 540 };
37
+
38
+ // 某层的蒸发进度 → {opacity, transform, filter}:ease-in 加速离场 + 位移 + 渐增模糊(蒸发感)
39
+ const strip = (frame: number, start: number, dx: number, dy: number): React.CSSProperties => {
40
+ const p = interpolate(frame, [start, start + STRIP_DUR], [0, 1], {
41
+ extrapolateLeft: 'clamp',
42
+ extrapolateRight: 'clamp',
43
+ easing: Easing.in(Easing.quad), // 离场加速
44
+ });
45
+ return {
46
+ opacity: 1 - p,
47
+ transform: `translate(${dx * p}px, ${dy * p}px)`,
48
+ filter: p > 0.001 ? `blur(${(p * 7).toFixed(2)}px)` : undefined,
49
+ };
50
+ };
51
+
52
+ // —— 小图标(1.5px 线性图标,与 fixture 同语言)——
53
+ const Icon: React.FC<{ d: string; size?: number; color?: string }> = ({ d, size = 18, color = G.ink2 }) => (
54
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={1.7} strokeLinecap="round" strokeLinejoin="round">
55
+ <path d={d} />
56
+ </svg>
57
+ );
58
+ const IC = {
59
+ cursor: 'M5 3l13 8-6 1.5L9 19z',
60
+ frame: 'M7 3v18M17 3v18M3 7h18M3 17h18',
61
+ text: 'M5 6V4h14v2M12 4v16M9 20h6',
62
+ pen: 'M12 19l7-7-3-3-7 7-1 4zM14 7l3 3',
63
+ image: 'M4 5h16v14H4zM4 16l5-5 4 4 3-3 4 4',
64
+ comp: 'M12 3l4 4-4 4-4-4zM12 13l4 4-4 4-4-4z',
65
+ layer: 'M4 7h16v10H4z',
66
+ textL: 'M6 7V5h12v2M12 5v14',
67
+ group: 'M4 6h7v5H4zM13 6h7v5h-7zM4 13h16v5H4z',
68
+ };
69
+
70
+ const LAYERS: [string, string, number, boolean?][] = [
71
+ ['frame', 'Launch film', 0],
72
+ ['layer', 'Cold open', 1],
73
+ ['group', 'Hero shot', 1],
74
+ ['textL', 'Title card', 2],
75
+ ['textL', 'Subtitle', 2],
76
+ ['group', 'Feature shots', 1, true],
77
+ ['layer', 'Shot — Crash zoom', 2],
78
+ ['layer', 'Shot — Dolly push', 2],
79
+ ['layer', 'Shot — Whip pan', 2],
80
+ ['layer', 'Shot — Beat cut', 2],
81
+ ['layer', 'Logo sting', 1],
82
+ ];
83
+
84
+ const Field: React.FC<{ label: string; value: string; w?: number }> = ({ label, value, w }) => (
85
+ <div style={{
86
+ height: 34, flex: w ? 'none' : 1, width: w, borderRadius: 8, background: G.fill, border: hairline(0.07),
87
+ display: 'flex', alignItems: 'center', gap: 8, padding: '0 10px', boxSizing: 'border-box',
88
+ fontFamily: FONT.sans, fontSize: 13, fontVariantNumeric: 'tabular-nums',
89
+ }}>
90
+ <span style={{ color: G.ink3 }}>{label}</span>
91
+ <span style={{ color: G.ink1, fontWeight: 500 }}>{value}</span>
92
+ </div>
93
+ );
94
+
95
+ const Section: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (
96
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 10, paddingBottom: 18, borderBottom: hairline(0.07) }}>
97
+ <div style={{ fontFamily: FONT.sans, fontSize: 12, fontWeight: 600, color: G.ink1, letterSpacing: '0.01em' }}>{title}</div>
98
+ {children}
99
+ </div>
100
+ );
101
+
102
+ export const UiStripAwayOutro: React.FC = () => {
103
+ const frame = useCurrentFrame();
104
+ const { fps } = useVideoConfig();
105
+
106
+ // 背景:编辑器底 → 黑场(随 canvasBg 层蒸发压黑)
107
+ const bgDark = interpolate(frame, [STRIP.canvasBg, STRIP.canvasBg + STRIP_DUR + 6], [0, 1], {
108
+ extrapolateLeft: 'clamp',
109
+ extrapolateRight: 'clamp',
110
+ easing: Easing.inOut(Easing.quad),
111
+ });
112
+
113
+ const sidebar = strip(frame, STRIP.sidebar, -140, 0);
114
+ const leftPanel = strip(frame, STRIP.leftPanel, -90, 20);
115
+ const topLeft = strip(frame, STRIP.topbarEnds, -80, -60);
116
+ const topRight = strip(frame, STRIP.topbarEnds, 80, -60);
117
+ const toolbarShell = strip(frame, STRIP.toolbarShell, 0, -50);
118
+ const canvasFrame = strip(frame, STRIP.canvasBg, 0, 40);
119
+
120
+ // 画布卡片错峰蒸发(各错 3f,左右交替散开)
121
+ const cardStrip = (i: number) => strip(frame, STRIP.canvasCards + i * 3, i % 2 ? 70 : -70, 50 + i * 10);
122
+
123
+ // 按钮:点击脉冲 + 最后淡出
124
+ const press = spring({ frame: frame - CLICK, fps, config: { damping: 12, stiffness: 220 } });
125
+ const pressScale = frame < CLICK ? 1 : 1 - 0.12 * Math.sin(Math.min(1, press) * Math.PI);
126
+ const btnOp = 1 - ramp(frame, BTN_FADE, 12, EASE.exit);
127
+ // 蒸发期间按钮从工具条位置滑向屏幕中心,独占黑场
128
+ const btnCenter = interpolate(frame, [STRIP.toolbarShell, STRIP.toolbarShell + 18], [0, 1], {
129
+ extrapolateLeft: 'clamp',
130
+ extrapolateRight: 'clamp',
131
+ easing: Easing.inOut(Easing.cubic),
132
+ });
133
+ const btnX = mix(BTN_FROM.x, BTN_TO.x, btnCenter);
134
+ const btnY = mix(BTN_FROM.y, BTN_TO.y, btnCenter);
135
+ const btnScale = 1 + 0.5 * btnCenter;
136
+ // 迁移最快段的方向性拖影(按每帧位移给模糊,静止为 0)
137
+ const dPrev = interpolate(frame - 1, [STRIP.toolbarShell, STRIP.toolbarShell + 18], [0, 1], {
138
+ extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.inOut(Easing.cubic),
139
+ });
140
+ const btnSpeed = Math.hypot(BTN_TO.x - BTN_FROM.x, BTN_TO.y - BTN_FROM.y) * Math.abs(btnCenter - dPrev);
141
+ const btnBlur = Math.min(3, btnSpeed * 0.04);
142
+ // 按钮淡出时略微放大"化开",把黑场交给字标
143
+ const btnRelease = ramp(frame, BTN_FADE, 12, EASE.out);
144
+
145
+ // 字标接棒:spring 定版 + 对焦模糊;字标比图形晚 3f(跟随)
146
+ const logoP = spring({ frame: frame - LOGO_IN, fps, config: { damping: 14, stiffness: 90 } });
147
+ const wordP = spring({ frame: frame - LOGO_IN - 3, fps, config: { damping: 14, stiffness: 90 } });
148
+
149
+ // 光标移向按钮:x、y 用不同缓动,走一条手腕带出的弧线;点击时笔尖压下
150
+ const curX = interpolate(frame, [4, CLICK - 2], [820, BTN_FROM.x + 18], {
151
+ extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.inOut(Easing.quad),
152
+ });
153
+ const curY = interpolate(frame, [4, CLICK - 2], [640, BTN_FROM.y + 4], {
154
+ extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.bezier(0.3, 0, 0.15, 1),
155
+ });
156
+ const curOp = 1 - ramp(frame, CLICK + 6, 10, EASE.out);
157
+ const curPress = frame >= CLICK - 1 && frame < CLICK + 3 ? 0.88 : 1;
158
+
159
+ const toolbarBase: React.CSSProperties = {
160
+ position: 'absolute', top: 0, height: 60, background: '#fbfbfa', borderBottom: hairline(0.08),
161
+ boxSizing: 'border-box', display: 'flex', alignItems: 'center', fontFamily: FONT.sans,
162
+ };
163
+
164
+ return (
165
+ <AbsoluteFill style={{ background: INK, overflow: 'hidden' }}>
166
+ {/* 黑场:中心极弱冷光(随压黑亮起) */}
167
+ <AbsoluteFill style={{
168
+ opacity: bgDark,
169
+ background: 'radial-gradient(ellipse 50% 45% at 50% 50%, rgba(120,128,220,0.10) 0%, rgba(120,128,220,0.03) 50%, rgba(0,0,0,0) 75%)',
170
+ }} />
171
+
172
+ {/* 编辑器底(点阵画布,作为一层可蒸发的背景) */}
173
+ <AbsoluteFill style={{
174
+ opacity: 1 - bgDark,
175
+ backgroundColor: '#ececea',
176
+ backgroundImage: 'radial-gradient(rgba(20,22,28,0.10) 1px, transparent 1.2px)',
177
+ backgroundSize: '24px 24px',
178
+ }} />
179
+
180
+ {/* 左侧栏(图层面板) */}
181
+ <div style={{
182
+ position: 'absolute', left: 0, top: 0, bottom: 0, width: 240, boxSizing: 'border-box', paddingTop: 76,
183
+ background: 'linear-gradient(180deg, #1c1d22 0%, #16171b 100%)', boxShadow: 'inset -1px 0 0 rgba(255,255,255,0.06)',
184
+ fontFamily: FONT.sans, ...sidebar,
185
+ }}>
186
+ <div style={{ padding: '0 18px 12px', fontSize: 11, fontWeight: 600, letterSpacing: '0.08em', color: 'rgba(255,255,255,0.36)' }}>LAYERS</div>
187
+ {LAYERS.map(([ic, name, depth, sel]) => (
188
+ <div key={name} style={{
189
+ height: 32, margin: '0 10px', borderRadius: 7, display: 'flex', alignItems: 'center', gap: 9,
190
+ paddingLeft: 10 + depth * 16, fontSize: 13, color: sel ? '#fff' : 'rgba(255,255,255,0.62)',
191
+ background: sel ? 'rgba(128,136,240,0.22)' : 'transparent',
192
+ boxShadow: sel ? 'inset 0 0 0 1px rgba(128,136,240,0.35)' : 'none',
193
+ }}>
194
+ <Icon d={IC[ic as keyof typeof IC]} size={14} color={sel ? '#c9cdff' : 'rgba(255,255,255,0.42)'} />
195
+ {name}
196
+ </div>
197
+ ))}
198
+ </div>
199
+
200
+ {/* 右侧属性面板 */}
201
+ <div style={{
202
+ position: 'absolute', right: 0, top: 60, bottom: 0, width: 300, background: '#fbfbfa', borderLeft: hairline(0.08),
203
+ padding: 22, boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 18, ...leftPanel,
204
+ }}>
205
+ <Section title="Frame">
206
+ <div style={{ display: 'flex', gap: 8 }}><Field label="X" value="320" /><Field label="Y" value="130" /></div>
207
+ <div style={{ display: 'flex', gap: 8 }}><Field label="W" value="1180" /><Field label="H" value="850" /></div>
208
+ </Section>
209
+ <Section title="Layout">
210
+ <div style={{ display: 'flex', gap: 8 }}><Field label="Gap" value="40" /><Field label="Pad" value="70" /></div>
211
+ </Section>
212
+ <Section title="Fill">
213
+ <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
214
+ <div style={{ width: 34, height: 34, borderRadius: 8, background: '#ffffff', border: hairline(0.12), boxSizing: 'border-box' }} />
215
+ <Field label="Hex" value="FFFFFF" />
216
+ <Field label="" value="100%" w={64} />
217
+ </div>
218
+ </Section>
219
+ <Section title="Effects">
220
+ <div style={{ display: 'flex', gap: 8 }}><Field label="Shadow" value="Soft · 16" /></div>
221
+ </Section>
222
+ </div>
223
+
224
+ {/* 顶部工具条左半(logo + 工具) */}
225
+ <div style={{ ...toolbarBase, left: 0, width: 760, gap: 6, padding: '0 16px', ...topLeft }}>
226
+ <div style={{ marginRight: 14 }}><ShotcraftMark size={34} tone="light" /></div>
227
+ {[IC.cursor, IC.frame, IC.text, IC.pen, IC.image, IC.comp].map((d, i) => (
228
+ <div key={i} style={{
229
+ width: 36, height: 36, borderRadius: 9, display: 'flex', alignItems: 'center', justifyContent: 'center',
230
+ background: i === 0 ? G.accentSoft : 'transparent',
231
+ }}>
232
+ <Icon d={d} size={18} color={i === 0 ? ACCENT : G.ink2} />
233
+ </div>
234
+ ))}
235
+ </div>
236
+ {/* 顶部工具条中段(标题) */}
237
+ <div style={{ ...toolbarBase, left: 760, right: 400, justifyContent: 'center', gap: 10, ...toolbarShell }}>
238
+ <span style={{ fontSize: 14, color: G.ink3 }}>{BRAND.name}</span>
239
+ <span style={{ fontSize: 14, color: G.ink3 }}>/</span>
240
+ <span style={{ fontSize: 14, color: G.ink1, fontWeight: 600, letterSpacing: '-0.01em' }}>Launch film</span>
241
+ <span style={{ fontSize: 11.5, fontWeight: 500, color: G.ink2, padding: '3px 8px', borderRadius: 6, background: G.fill2 }}>Draft</span>
242
+ </div>
243
+ {/* 顶部工具条右段底板(头像 + Invite;Publish 单独渲染在最上层) */}
244
+ <div style={{ ...toolbarBase, right: 0, width: 400, justifyContent: 'flex-end', gap: 12, padding: `0 ${24 + BTN_W + 12}px 0 24px`, ...topRight }}>
245
+ <div style={{ display: 'flex' }}>
246
+ {['JL', 'MR'].map((n, i) => (
247
+ <div key={n} style={{
248
+ width: 30, height: 30, borderRadius: 15, marginLeft: i ? -8 : 0, background: i ? '#dfe1e8' : '#e9e6df',
249
+ border: '2px solid #fbfbfa', display: 'flex', alignItems: 'center', justifyContent: 'center',
250
+ fontSize: 11, fontWeight: 600, color: '#4a4c53',
251
+ }}>{n}</div>
252
+ ))}
253
+ </div>
254
+ <div style={{
255
+ height: 34, padding: '0 14px', borderRadius: 9, border: hairline(0.13), boxSizing: 'border-box',
256
+ display: 'flex', alignItems: 'center', fontSize: 13.5, fontWeight: 500, color: G.ink1, background: '#fff',
257
+ boxShadow: softShadow(1),
258
+ }}>Invite</div>
259
+ </div>
260
+
261
+ {/* 画布区:一张浏览器式大卡 + 四张内容卡 */}
262
+ <div style={{ position: 'absolute', left: 320, top: 130, width: 1180, height: 850, ...canvasFrame }}>
263
+ <div style={{
264
+ position: 'absolute', inset: 0, background: G.card, border: hairline(0.09), borderRadius: 18, overflow: 'hidden',
265
+ boxShadow: `${innerHighlight(0.9)}, ${softShadow(22)}`,
266
+ }}>
267
+ <div style={{
268
+ height: 46, borderBottom: hairline(0.07), display: 'flex', alignItems: 'center', gap: 8, padding: '0 18px',
269
+ background: 'linear-gradient(180deg, #fbfbfa 0%, #f5f5f3 100%)',
270
+ }}>
271
+ {['#ec6a5e', '#f4bf4f', '#61c554'].map((c) => (
272
+ <div key={c} style={{ width: 12, height: 12, borderRadius: 6, background: c, opacity: 0.85 }} />
273
+ ))}
274
+ <div style={{
275
+ marginLeft: 16, height: 26, width: 380, background: G.fill, borderRadius: 8, display: 'flex', alignItems: 'center',
276
+ padding: '0 12px', fontFamily: FONT.sans, fontSize: 12.5, color: G.ink2, gap: 6,
277
+ }}>
278
+ <svg width={11} height={11} viewBox="0 0 24 24" fill="none" stroke={G.ink3} strokeWidth={2.4}><rect x="5" y="11" width="14" height="10" rx="2" /><path d="M8 11V8a4 4 0 0 1 8 0v3" /></svg>
279
+ {BRAND.repo}
280
+ </div>
281
+ </div>
282
+ </div>
283
+ {[0, 1, 2, 3].map((i) => {
284
+ const s = cardStrip(i);
285
+ return (
286
+ <div key={i} style={{ position: 'absolute', left: 70 + (i % 2) * 560, top: 120 + Math.floor(i / 2) * 340, ...s }}>
287
+ <Card w={480} h={280} seed={i + 2} />
288
+ </div>
289
+ );
290
+ })}
291
+ </div>
292
+
293
+ {/* Publish 按钮(高亮层,最后退场):按中心定位,尺寸按布局放大(字边清晰) */}
294
+ <div
295
+ style={{
296
+ position: 'absolute', left: btnX, top: btnY, width: 0, height: 0, zIndex: 30,
297
+ opacity: btnOp, transform: `scale(${pressScale * (1 + 0.06 * btnRelease)})`,
298
+ filter: btnBlur > 0.2 ? `blur(${btnBlur.toFixed(2)}px)` : undefined,
299
+ }}
300
+ >
301
+ {/* 黑场上的主角光环:同色柔光盘,随压黑增强 */}
302
+ <div style={{
303
+ position: 'absolute', left: -260, top: -160, width: 520, height: 320, borderRadius: '50%',
304
+ background: 'radial-gradient(ellipse at center, rgba(91,99,211,0.38) 0%, rgba(91,99,211,0.10) 40%, rgba(91,99,211,0) 70%)',
305
+ opacity: btnCenter * bgDark,
306
+ }} />
307
+ <div
308
+ style={{
309
+ position: 'absolute',
310
+ width: BTN_W * btnScale, height: BTN_H * btnScale,
311
+ left: -(BTN_W * btnScale) / 2, top: -(BTN_H * btnScale) / 2,
312
+ borderRadius: 10 * btnScale,
313
+ background: 'linear-gradient(180deg, #6a72e0 0%, #545cd0 100%)',
314
+ boxShadow: `inset 0 1px 0 rgba(255,255,255,0.28), inset 0 0 0 1px rgba(255,255,255,0.06), 0 1px 2px rgba(30,34,120,0.35), 0 0 ${30 + 40 * btnCenter}px rgba(110,118,240,${(0.18 + 0.4 * btnCenter * bgDark).toFixed(3)})`,
315
+ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 * btnScale,
316
+ fontFamily: FONT.sans, fontWeight: 600, fontSize: 15 * btnScale, letterSpacing: '-0.01em', color: '#ffffff',
317
+ }}
318
+ >
319
+ <svg width={14 * btnScale} height={14 * btnScale} viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth={2.4} strokeLinecap="round" strokeLinejoin="round">
320
+ <path d="M12 19V5M5 12l7-7 7 7" />
321
+ </svg>
322
+ Publish
323
+ </div>
324
+ </div>
325
+
326
+ {/* 字标接棒 */}
327
+ {frame >= LOGO_IN && (
328
+ <AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center' }}>
329
+ <div style={{ display: 'flex', alignItems: 'center', gap: 30, transform: `scale(${0.86 + 0.14 * logoP})` }}>
330
+ <div style={{ opacity: Math.min(1, logoP * 1.4), filter: logoP < 0.995 ? `blur(${((1 - logoP) * 9).toFixed(2)}px)` : undefined }}>
331
+ <ShotcraftMark size={132} tone="dark" />
332
+ </div>
333
+ <div style={{
334
+ opacity: Math.min(1, wordP * 1.4), transform: `translateX(${((1 - wordP) * -16).toFixed(2)}px)`,
335
+ filter: wordP < 0.995 ? `blur(${((1 - wordP) * 9).toFixed(2)}px)` : undefined,
336
+ fontFamily: BRAND.font, fontWeight: 700, fontSize: 68, lineHeight: 1, letterSpacing: '0.03em', color: BRAND.paper, paddingBottom: 4, whiteSpace: 'nowrap',
337
+ }}>
338
+ {BRAND.name}
339
+ </div>
340
+ </div>
341
+ </AbsoluteFill>
342
+ )}
343
+
344
+ {/* 光标 */}
345
+ <svg width={30} height={38} viewBox="0 0 14 18" style={{
346
+ position: 'absolute', left: curX, top: curY, opacity: curOp, zIndex: 40,
347
+ transform: `scale(${curPress})`, transformOrigin: '2px 2px', filter: 'drop-shadow(0 3px 5px rgba(16,18,24,0.3))',
348
+ }}>
349
+ <path d="M1 1 L1 15 L4.6 11.6 L7.2 17 L9.4 16 L6.9 10.7 L12 10.7 Z" fill="#111216" stroke="#ffffff" strokeWidth={1.1} strokeLinejoin="round" />
350
+ </svg>
351
+
352
+ {/* 暗角 + 颗粒:随压黑加深(亮场时几乎不压) */}
353
+ <Vignette strength={0.12 + 0.45 * bgDark} inner={0.42} color="#000000" />
354
+ <Grain opacity={0.05 + 0.03 * bgDark} blend="soft-light" />
355
+ </AbsoluteFill>
356
+ );
357
+ };