dsh-drawai 0.4.2 → 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 (366) hide show
  1. package/README.md +4 -3
  2. package/lib/index.js +7777 -7719
  3. package/lib/motion/asset-pack.js +394 -394
  4. package/lib/motion/assets.js +291 -291
  5. package/lib/motion/demo-assets-lock.js +10 -10
  6. package/lib/motion/mgstyles/vendor/README.md +28 -28
  7. package/lib/motion/mgstyles/vendor/modules/d3/LICENSE +13 -13
  8. package/lib/motion/mgstyles/vendor/modules/d3/dist/d3.min.js +2 -2
  9. package/lib/motion/mgstyles/vendor/modules/opentype.js/LICENSE +20 -20
  10. package/lib/motion/mgstyles/vendor/modules/opentype.js/dist/opentype.mjs +14460 -14460
  11. package/lib/motion/mgstyles/vendor/modules/simplex-noise/LICENSE +21 -21
  12. package/lib/motion/mgstyles/vendor/modules/simplex-noise/dist/esm/simplex-noise.js +465 -465
  13. package/lib/motion/mgstyles/vendor/modules/topojson-client/LICENSE +13 -13
  14. package/lib/motion/mgstyles/vendor/modules/topojson-client/dist/topojson-client.min.js +2 -2
  15. package/lib/motion/render.js +179 -179
  16. package/lib/motion/shotcraft/upstream/SKILL.md +286 -286
  17. package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -54
  18. package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -200
  19. package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -45
  20. package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -20
  21. package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -65
  22. package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -151
  23. package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -129
  24. package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -75
  25. package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -40
  26. package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -11
  27. package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -10
  28. package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -49
  29. package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -210
  30. package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -423
  31. package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -170
  32. package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -157
  33. package/lib/motion/shotcraft/upstream/demos/README.md +120 -120
  34. package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -112
  35. package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -647
  36. package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -316
  37. package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -82
  38. package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -115
  39. package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -243
  40. package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +388 -388
  41. package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -250
  42. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -305
  43. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -246
  44. package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -390
  45. package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -138
  46. package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -542
  47. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -315
  48. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -299
  49. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -173
  50. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -348
  51. package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -366
  52. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -279
  53. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -184
  54. package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -390
  55. package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -155
  56. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -303
  57. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -290
  58. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -278
  59. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -307
  60. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -215
  61. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -299
  62. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -232
  63. package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -290
  64. package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -273
  65. package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -167
  66. package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -536
  67. package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -164
  68. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -175
  69. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -197
  70. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -241
  71. package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -279
  72. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -230
  73. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -345
  74. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -275
  75. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -229
  76. package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -312
  77. package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -222
  78. package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -295
  79. package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -329
  80. package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -315
  81. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -264
  82. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -260
  83. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -263
  84. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -123
  85. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -187
  86. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -175
  87. package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -305
  88. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -350
  89. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -352
  90. package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -218
  91. package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -297
  92. package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -157
  93. package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -218
  94. package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -202
  95. package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -265
  96. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -457
  97. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -446
  98. package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -249
  99. package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -278
  100. package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -332
  101. package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -358
  102. package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -201
  103. package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -200
  104. package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -208
  105. package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -341
  106. package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -389
  107. package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -293
  108. package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -183
  109. package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -245
  110. package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -222
  111. package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -223
  112. package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -217
  113. package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -343
  114. package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -357
  115. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -187
  116. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -333
  117. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -274
  118. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -270
  119. package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -430
  120. package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -252
  121. package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -106
  122. package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -288
  123. package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -362
  124. package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -168
  125. package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -310
  126. package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -261
  127. package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -459
  128. package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -294
  129. package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -161
  130. package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -248
  131. package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -359
  132. package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -227
  133. package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -162
  134. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -248
  135. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -186
  136. package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -355
  137. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -272
  138. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -262
  139. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -217
  140. package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -285
  141. package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -205
  142. package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -178
  143. package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -147
  144. package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -143
  145. package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -134
  146. package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -217
  147. package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -198
  148. package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -221
  149. package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -312
  150. package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -261
  151. package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -121
  152. package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -153
  153. package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -179
  154. package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -140
  155. package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -309
  156. package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -191
  157. package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -292
  158. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -135
  159. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -124
  160. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -255
  161. package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -173
  162. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -225
  163. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -141
  164. package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -137
  165. package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -147
  166. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -409
  167. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -280
  168. package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -271
  169. package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -385
  170. package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -312
  171. package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -303
  172. package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -77
  173. package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -311
  174. package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -307
  175. package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -349
  176. package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -255
  177. package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -244
  178. package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -217
  179. package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -652
  180. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -153
  181. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -238
  182. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -324
  183. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -354
  184. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -101
  185. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -129
  186. package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -297
  187. package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -57
  188. package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -155
  189. package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -175
  190. package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -153
  191. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -146
  192. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -226
  193. package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -1
  194. package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -193
  195. package/lib/motion/shotcraft/upstream/references/final-review.md +121 -121
  196. package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -199
  197. package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -183
  198. package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -257
  199. package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -382
  200. package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -111
  201. package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -50
  202. package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -95
  203. package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -41
  204. package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -52
  205. package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -39
  206. package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -39
  207. package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -57
  208. package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -51
  209. package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -46
  210. package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -52
  211. package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -43
  212. package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -42
  213. package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -48
  214. package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -52
  215. package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -45
  216. package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -46
  217. package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -44
  218. package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -63
  219. package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -54
  220. package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -58
  221. package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -35
  222. package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -53
  223. package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -42
  224. package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -50
  225. package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -46
  226. package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -56
  227. package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -49
  228. package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -50
  229. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -53
  230. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -53
  231. package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -55
  232. package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -52
  233. package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -60
  234. package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -57
  235. package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -51
  236. package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -41
  237. package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -53
  238. package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -60
  239. package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -55
  240. package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -57
  241. package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -47
  242. package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -37
  243. package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -54
  244. package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -36
  245. package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -56
  246. package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -56
  247. package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -40
  248. package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -60
  249. package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -57
  250. package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -73
  251. package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -87
  252. package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -55
  253. package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -50
  254. package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -59
  255. package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -38
  256. package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -38
  257. package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -59
  258. package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -39
  259. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -61
  260. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -52
  261. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -50
  262. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -66
  263. package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -43
  264. package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -38
  265. package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -38
  266. package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -56
  267. package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -44
  268. package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -38
  269. package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -63
  270. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -57
  271. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -63
  272. package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -58
  273. package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -45
  274. package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -55
  275. package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -49
  276. package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -42
  277. package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -42
  278. package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -45
  279. package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -48
  280. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -55
  281. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -43
  282. package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -41
  283. package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -42
  284. package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -59
  285. package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -55
  286. package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -65
  287. package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -42
  288. package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -64
  289. package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -64
  290. package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -54
  291. package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -91
  292. package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -51
  293. package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -66
  294. package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -38
  295. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -66
  296. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -58
  297. package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -61
  298. package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -64
  299. package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -45
  300. package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -41
  301. package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -51
  302. package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -42
  303. package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -63
  304. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -57
  305. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -75
  306. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -59
  307. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -67
  308. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -60
  309. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -66
  310. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -40
  311. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -45
  312. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -62
  313. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -55
  314. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -37
  315. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -55
  316. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -50
  317. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -43
  318. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -55
  319. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -51
  320. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -51
  321. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -56
  322. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -49
  323. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -57
  324. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -36
  325. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -64
  326. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -47
  327. package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -170
  328. package/lib/motion/shotcraft/upstream/references/workbench.md +157 -157
  329. package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -103
  330. package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -44
  331. package/lib/motion/shotcraft/upstream/template/package.json +20 -20
  332. package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -6
  333. package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -17
  334. package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -65
  335. package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -48
  336. package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -24
  337. package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -192
  338. package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -111
  339. package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -150
  340. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -158
  341. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -468
  342. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -552
  343. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -411
  344. package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -200
  345. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -324
  346. package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +388 -388
  347. package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -4
  348. package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -7
  349. package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -68
  350. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -1
  351. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -24
  352. package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -74
  353. package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -91
  354. package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -213
  355. package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -15
  356. package/lib/motion/style-frames.js +306 -306
  357. package/lib/motion/sync.js +214 -214
  358. package/lib/motion-project.js +105 -105
  359. package/lib/motion-render-worker.js +174 -174
  360. package/lib/routing/router.js +222 -222
  361. package/lib/routing/vendor/README.md +96 -96
  362. package/lib/routing/vendor/libavoid-routing.js +753 -753
  363. package/lib/routing/vendor/libavoid.min.js +59 -59
  364. package/lib/video-trace-pool.js +128 -128
  365. package/package.json +1 -1
  366. package/LICENSE +0 -4175
@@ -1,350 +1,350 @@
1
- // diagram-cascade-build —— miro-promo 104–116s
2
- // prompt 打字 → 结构图逐层级联生成(根 → 2 子 → 4 孙),连线先于节点生长,成树后整棵呼吸一拍。
3
- //
4
- // 第二轮重设计(极光暗场 · AI 画布"一句话长出一棵树"):
5
- // - look = aurora(深紫夜 · 紫粉光)。主角是"生长"本身:每条连线都带一颗发光的彗星头领跑,
6
- // 线头到达子端口的那一帧子节点才从端口处"被拉出来"(缩放原点 = 节点顶边中点)——线牵节点,因果可见。
7
- // - 生成源头清楚:prompt 条(video-shotcraft 的 AI 命令条,36px 大字)提交后描边变成流动的紫粉渐变(生成中),
8
- // 从 prompt 条底部先滴下一条线接到根节点——树是从这句话里长出来的;生成完毕描边落定、右侧状态变成"7 tables"。
9
- // - 节点做成为镜头设计的 ER 表卡:34px 表名 + 两行 mono 字段(PK/FK 小签),根节点用渐变描边当主角;
10
- // 其余是带色相的深紫玻璃面板 + 发丝线 + 顶部内高光 + 两层软阴影。
11
- // - 相机:开场推近在 prompt 条上(1.3× 居中,读字),提交后随树生长 smooth 拉远到 1.0 揭示整体结构(crane-back),
12
- // 全程平滑无速度突变;成树后以树心为原点呼吸 1→1.03→1,背后极光同步亮一档。
13
- //
14
- // 时间表(30fps,共 180f):
15
- // 0–10 舞台 + prompt 条落下(空条 + 光标闪)
16
- // 8–44 打字 "Map the data model for Shotcraft"(每字 1–2f 不均匀,像真人敲)
17
- // 46–50 敲完:描边转紫确认;48f 按下提交键(scale 0.9 → 回弹)
18
- // 50–136 生成中:描边流光;50f 起相机 1.3→1.0 拉远(smooth,72f),prompt 条从画面中心升到顶部
19
- // 54 prompt 底部滴线 → 62f 根节点从端口拉出(spring damping 14)
20
- // 82/104 第 1 / 2 层:线先行 10f(16f ease-out + 彗星头),同层兄弟错峰 5f
21
- // ~128 末节点落定 → 状态 "7 tables · 6 links"、描边流光收束
22
- // 138–166 整棵呼吸一拍 + 极光亮一档
23
- // 166–180 落定 hold:完整海报
24
- import React from 'react';
25
- import { AbsoluteFill, useCurrentFrame } from 'remotion';
26
- import { EASE, FONT, mix, ramp, softShadow } from '../../_fixtures/Polish';
27
- import { Dust, LOOKS, Stage, alpha, springAt, type } from '../../_fixtures/Look';
28
-
29
- export const DIAGRAM_CASCADE_BUILD_DURATION = 180;
30
-
31
- const L = LOOKS.aurora;
32
- const A1 = L.accent; // 紫
33
- const A2 = L.accent2; // 粉(点缀:渐变另一端)
34
-
35
- const PROMPT = 'Map the data model for Shotcraft'; // 与原句同节奏:提交帧仍是 50f
36
- const TYPE_START = 8;
37
- // 每个字符的敲击间隔(帧):确定性"人手节奏"——词间空格多停半拍
38
- const charGap = (i: number) => (PROMPT[i] === ' ' ? 1.7 : 0.95 + 0.25 * Math.abs(Math.sin(i * 2.17)));
39
- const CHAR_T: number[] = [];
40
- {
41
- let t = TYPE_START;
42
- for (let i = 0; i < PROMPT.length; i++) {
43
- t += charGap(i);
44
- CHAR_T.push(t);
45
- }
46
- }
47
- const TYPE_END = CHAR_T[CHAR_T.length - 1];
48
- const SUBMIT = Math.round(TYPE_END) + 4;
49
-
50
- // ── 树布局(画布坐标,节点中心)──
51
- const NODE_W = 344;
52
- const NODE_H = 158;
53
- type Field = [string, string, '' | 'PK' | 'FK'];
54
- type Node = { id: number; x: number; y: number; level: number; parent: number; name: string; fields: Field[] };
55
- const NODES: Node[] = [
56
- // video-shotcraft 自己的数据模型:成片工程 → 分镜 / 渲染任务 → 镜头、配方卡、输出、预设
57
- { id: 0, x: 960, y: 372, level: 0, parent: -1, name: 'Project', fields: [['id', 'uuid', 'PK'], ['title', 'text', '']] },
58
- { id: 1, x: 540, y: 608, level: 1, parent: 0, name: 'Storyboard', fields: [['id', 'uuid', 'PK'], ['proj_id', 'uuid', 'FK']] },
59
- { id: 2, x: 1380, y: 608, level: 1, parent: 0, name: 'RenderJob', fields: [['id', 'uuid', 'PK'], ['proj_id', 'uuid', 'FK']] },
60
- { id: 3, x: 320, y: 852, level: 2, parent: 1, name: 'Shot', fields: [['board_id', 'uuid', 'FK'], ['frames', 'int', '']] },
61
- { id: 4, x: 760, y: 852, level: 2, parent: 1, name: 'Recipe', fields: [['shot_id', 'uuid', 'FK'], ['move', 'enum', '']] },
62
- { id: 5, x: 1160, y: 852, level: 2, parent: 2, name: 'Output', fields: [['job_id', 'uuid', 'FK'], ['codec', 'text', '']] },
63
- { id: 6, x: 1600, y: 852, level: 2, parent: 2, name: 'Preset', fields: [['id', 'uuid', 'PK'], ['fps', 'int', '']] },
64
- ];
65
- const PROMPT_Y = 96; // prompt 条顶
66
- const PROMPT_H = 100;
67
- const ROOT_DRIP = SUBMIT + 6; // 滴线起笔
68
- const CASCADE_START = SUBMIT + 14; // 根节点出现
69
- const LEVEL_GAP = 22;
70
- const SIBLING_STAGGER = 5;
71
- const LEAD = 10; // 线比子节点早到
72
- const EDGE_DUR = 16;
73
-
74
- const nodeStart = (n: Node) => {
75
- if (n.level === 0) return CASCADE_START;
76
- const siblingIdx = NODES.filter((m) => m.level === n.level && m.id < n.id).length;
77
- return CASCADE_START + n.level * LEVEL_GAP + siblingIdx * SIBLING_STAGGER;
78
- };
79
- const LAST = nodeStart(NODES[NODES.length - 1]);
80
- const DONE = LAST + 12;
81
- const BREATHE = DONE + 10;
82
-
83
- // ── 圆角折线(父底端口 → 下探 → 横移 → 下探到子顶端口),用 SVG 圆弧,长度可精确计算 ──
84
- const R = 22;
85
- const edgeGeom = (p: Node, c: Node) => {
86
- const x1 = p.x, y1 = p.y + NODE_H / 2 + 8, x2 = c.x, y2 = c.y - NODE_H / 2 - 8;
87
- const my = (y1 + y2) / 2;
88
- const dir = Math.sign(x2 - x1);
89
- const r = Math.min(R, Math.abs(x2 - x1) / 2);
90
- const sweep1 = dir > 0 ? 0 : 1;
91
- const sweep2 = dir > 0 ? 1 : 0;
92
- const d = `M ${x1} ${y1} L ${x1} ${my - r} A ${r} ${r} 0 0 ${sweep1} ${x1 + dir * r} ${my} L ${x2 - dir * r} ${my} A ${r} ${r} 0 0 ${sweep2} ${x2} ${my + r} L ${x2} ${y2}`;
93
- const s1 = my - r - y1, a = (Math.PI * r) / 2, h = Math.abs(x2 - x1) - 2 * r, s3 = y2 - my - r;
94
- const len = s1 + a + h + a + s3;
95
- // 沿路径弧长 u(px)取点:给彗星头定位
96
- const at = (u: number) => {
97
- if (u <= s1) return { x: x1, y: y1 + u };
98
- u -= s1;
99
- if (u <= a) { const th = u / r; return { x: x1 + dir * r * (1 - Math.cos(th)), y: my - r + r * Math.sin(th) }; }
100
- u -= a;
101
- if (u <= h) return { x: x1 + dir * (r + u), y: my };
102
- u -= h;
103
- if (u <= a) { const th = u / r; return { x: x2 - dir * r + dir * r * Math.sin(th), y: my + r - r * Math.cos(th) }; }
104
- u -= a;
105
- return { x: x2, y: my + r + Math.min(u, s3) };
106
- };
107
- return { d, len, at };
108
- };
109
-
110
- // ── 小图标 ──
111
- const SparkIcon: React.FC<{ c: string; size?: number }> = ({ c, size = 34 }) => (
112
- <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
113
- <path d="M12 2.5l2.1 6.4 6.4 2.1-6.4 2.1L12 19.5l-2.1-6.4L3.5 11l6.4-2.1z" fill={c} />
114
- <path d="M19 15.5l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8z" fill={c} opacity={0.6} />
115
- </svg>
116
- );
117
- const TableIcon: React.FC<{ c: string }> = ({ c }) => (
118
- <svg width={26} height={26} viewBox="0 0 18 18" fill="none">
119
- <rect x={2} y={3} width={14} height={12} rx={2.5} stroke={c} strokeWidth={1.5} />
120
- <path d="M2 7.5h14M7 7.5V15" stroke={c} strokeWidth={1.5} />
121
- </svg>
122
- );
123
-
124
- // ── ER 表卡 ──
125
- const EntityCard: React.FC<{ n: Node; t: number }> = ({ n, t }) => {
126
- const root = n.level === 0;
127
- const head = ramp(t, 3, 8, EASE.out);
128
- const row = (i: number) => ramp(t, 7 + i * 3, 9, EASE.out);
129
- return (
130
- <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column' }}>
131
- <div style={{
132
- height: 66, display: 'flex', alignItems: 'center', gap: 14, padding: '0 24px',
133
- borderBottom: `1px solid ${alpha('#ffffff', root ? 0.12 : 0.07)}`,
134
- opacity: head, transform: `translateY(${((1 - head) * 6).toFixed(2)}px)`,
135
- }}>
136
- <TableIcon c={root ? A1 : L.ink3} />
137
- <span style={{ ...type(34, 650), color: L.ink }}>{n.name}</span>
138
- </div>
139
- <div style={{ padding: '14px 24px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
140
- {n.fields.map(([k, ty, key], i) => (
141
- <div key={k} style={{
142
- display: 'flex', alignItems: 'center', gap: 10, height: 26, ...type(22, 500, { mono: true }),
143
- opacity: row(i), transform: `translateX(${((1 - row(i)) * -8).toFixed(2)}px)`,
144
- }}>
145
- <span style={{ color: L.ink2 }}>{k}</span>
146
- {key && (
147
- <span style={{
148
- ...type(15, 700, { caps: true }), padding: '3px 7px', borderRadius: 6,
149
- color: key === 'PK' ? A1 : A2, background: alpha(key === 'PK' ? A1 : A2, 0.14),
150
- }}>{key}</span>
151
- )}
152
- <span style={{ marginLeft: 'auto', color: L.ink3 }}>{ty}</span>
153
- </div>
154
- ))}
155
- </div>
156
- </div>
157
- );
158
- };
159
-
160
- export const DiagramCascadeBuild: React.FC = () => {
161
- const frame = useCurrentFrame();
162
-
163
- // ── prompt ──
164
- let typed = 0;
165
- while (typed < PROMPT.length && CHAR_T[typed] <= frame) typed++;
166
- const caretOn = frame < SUBMIT && (typed < PROMPT.length || Math.floor((frame - TYPE_END) / 7) % 2 === 0);
167
- const confirm = ramp(frame, TYPE_END, 6, EASE.out);
168
- const press = frame < SUBMIT ? 0 : frame < SUBMIT + 3 ? ramp(frame, SUBMIT, 3, EASE.out) : 1 - ramp(frame, SUBMIT + 3, 10, EASE.out);
169
- const promptIn = ramp(frame, 0, 14, EASE.snappy);
170
- const generating = ramp(frame, SUBMIT, 8, EASE.out) * (1 - ramp(frame, DONE, 12, EASE.out));
171
- const doneIn = ramp(frame, DONE, 14, EASE.snappy);
172
- const flow = Math.max(0, frame - SUBMIT) * 0.012; // 描边流光相位
173
-
174
- // ── 相机:推近 prompt → 提交后拉远揭示全树 ──
175
- const pull = ramp(frame, SUBMIT + 2, 72, EASE.smooth);
176
- const cam = mix(1.3, 1, pull);
177
- const camY = mix(340, 0, pull); // 推近时把 prompt 条拉到画面正中
178
-
179
- // ── 成树呼吸 ──
180
- const br = ramp(frame, BREATHE, 14, EASE.smooth) - ramp(frame, BREATHE + 14, 14, EASE.smooth);
181
- const breathe = 1 + 0.03 * br;
182
- const auroraUp = ramp(frame, BREATHE - 6, 24, EASE.out);
183
-
184
- const drip = ramp(frame, ROOT_DRIP, 8, EASE.out);
185
- const root = NODES[0];
186
- const dripY1 = PROMPT_Y + PROMPT_H + 4;
187
- const dripY2 = root.y - NODE_H / 2 - 8;
188
-
189
- return (
190
- <AbsoluteFill style={{ background: L.bg[1], overflow: 'hidden', fontFamily: FONT.sans }}>
191
- <Stage look={L} keyLight={{ x: 0.5, y: 0.05 }} fill={{ x: 0.82, y: 0.95 }} breathe={0.5}>
192
- {/* 树后的极光:随生成逐渐亮起,成树时再亮一档 */}
193
- <div style={{
194
- position: 'absolute', left: 260, right: 260, top: 380, height: 640,
195
- background: `radial-gradient(ellipse 50% 50% at 35% 55%, ${alpha(A1, 0.1 + 0.12 * auroraUp)} 0%, transparent 70%), radial-gradient(ellipse 45% 45% at 70% 60%, ${alpha(A2, 0.05 + 0.08 * auroraUp)} 0%, transparent 70%)`,
196
- opacity: ramp(frame, SUBMIT, 60, EASE.out),
197
- }} />
198
- {/* 画布点阵 */}
199
- <AbsoluteFill style={{
200
- backgroundImage: `radial-gradient(${alpha(L.ink, 0.12)} 1.4px, transparent 1.7px)`,
201
- backgroundSize: '40px 40px', backgroundPosition: '0 16px',
202
- WebkitMaskImage: 'radial-gradient(ellipse 60% 62% at 50% 58%, #000 25%, transparent 100%)',
203
- maskImage: 'radial-gradient(ellipse 60% 62% at 50% 58%, #000 25%, transparent 100%)',
204
- }} />
205
- <Dust look={L} count={22} seed={5} drift={0.18} opacity={0.35} />
206
- </Stage>
207
-
208
- <AbsoluteFill style={{ transform: `translateY(${camY.toFixed(2)}px) scale(${cam.toFixed(4)})`, transformOrigin: '50% 14%' }}>
209
- {/* ── prompt 条:渐变描边(生成中流动)+ 内面板 ── */}
210
- <div style={{
211
- position: 'absolute', left: 960 - 560, top: PROMPT_Y, width: 1120, height: PROMPT_H, borderRadius: 50,
212
- padding: 2, boxSizing: 'border-box',
213
- background: alpha(A1, 0.14 + 0.4 * confirm),
214
- boxShadow: `0 0 ${(30 + 40 * generating).toFixed(1)}px ${alpha(A1, 0.1 + 0.25 * generating)}, ${softShadow(24, { color: L.shadow, strength: 2.4 })}`,
215
- opacity: promptIn, transform: `translateY(${((1 - promptIn) * -20).toFixed(2)}px)`,
216
- }}>
217
- {/* 生成中:流动的紫粉渐变描边;完成后留一道静止的渐变边 */}
218
- <div style={{
219
- position: 'absolute', inset: 0, borderRadius: 50,
220
- background: `linear-gradient(90deg, ${A1}, ${A2}, ${A1}, ${A2}, ${A1})`, backgroundSize: '300% 100%',
221
- backgroundPosition: `${(-flow * 100).toFixed(2)}% 0`, opacity: Math.max(generating, 0.55 * doneIn),
222
- }} />
223
- <div style={{
224
- position: 'relative', width: '100%', height: '100%', borderRadius: 48, boxSizing: 'border-box',
225
- background: `linear-gradient(180deg, ${L.surface2}, ${L.surface})`,
226
- boxShadow: `inset 0 1px 0 ${alpha('#ffffff', 0.08)}`,
227
- display: 'flex', alignItems: 'center', padding: '0 16px 0 30px',
228
- }}>
229
- <div style={{ marginRight: 20, flexShrink: 0, display: 'grid', placeItems: 'center', filter: `drop-shadow(0 0 ${8 + 10 * generating}px ${alpha(A1, 0.6)})` }}>
230
- <SparkIcon c={A1} />
231
- </div>
232
- <span style={{ ...type(36, 520), color: L.ink, whiteSpace: 'nowrap' }}>
233
- {PROMPT.slice(0, typed)}
234
- <span style={{
235
- display: 'inline-block', width: 3, height: 40, marginLeft: 4, verticalAlign: -7, borderRadius: 2,
236
- background: A1, opacity: caretOn ? 1 : 0,
237
- }} />
238
- </span>
239
- {/* 右侧:提交键 → 生成中 → 完成状态 */}
240
- <div style={{ marginLeft: 'auto', position: 'relative', height: 68, display: 'flex', alignItems: 'center' }}>
241
- <div style={{
242
- position: 'absolute', right: 0, top: 0, whiteSpace: 'nowrap', height: 68, display: 'flex', alignItems: 'center', gap: 12,
243
- opacity: doneIn, transform: `translateY(${((1 - doneIn) * 12).toFixed(2)}px)`,
244
- ...type(28, 560), color: L.ink2, paddingRight: 14,
245
- }}>
246
- <svg width={28} height={28} viewBox="0 0 24 24" fill="none">
247
- <circle cx={12} cy={12} r={10} fill={alpha(A1, 0.18)} />
248
- <path d="M7.5 12.3l3 3 6-6.3" stroke={A1} strokeWidth={2.2} strokeLinecap="round" strokeLinejoin="round" />
249
- </svg>
250
- 7 tables · 6 links
251
- </div>
252
- <div style={{
253
- width: 68, height: 68, borderRadius: 34, display: 'grid', placeItems: 'center',
254
- background: confirm > 0 ? `linear-gradient(135deg, ${A1}, ${A2})` : alpha('#ffffff', 0.06),
255
- opacity: (0.4 + 0.6 * confirm) * (1 - doneIn),
256
- transform: `scale(${(1 - 0.1 * press) * (1 - 0.3 * doneIn)})`,
257
- boxShadow: confirm > 0.5 ? `0 6px 20px -6px ${alpha(A2, 0.7)}` : 'none',
258
- }}>
259
- <svg width={30} height={30} viewBox="0 0 24 24" fill="none">
260
- <path d="M12 19V5M6 11l6-6 6 6" stroke={confirm > 0.5 ? L.onAccent : L.ink3} strokeWidth={2.6} strokeLinecap="round" strokeLinejoin="round" />
261
- </svg>
262
- </div>
263
- </div>
264
- </div>
265
- </div>
266
-
267
- {/* ── 树(呼吸以树心为原点) ── */}
268
- <div style={{ position: 'absolute', inset: 0, transform: `scale(${breathe.toFixed(4)})`, transformOrigin: '960px 620px' }}>
269
- <svg width={1920} height={1080} style={{ position: 'absolute', inset: 0, overflow: 'visible' }}>
270
- <defs>
271
- <linearGradient id="dcbEdge" x1="0" y1="300" x2="0" y2="800" gradientUnits="userSpaceOnUse">
272
- <stop offset="0" stopColor={A1} stopOpacity={0.85} />
273
- <stop offset="1" stopColor={A2} stopOpacity={0.7} />
274
- </linearGradient>
275
- <radialGradient id="dcbHead">
276
- <stop offset="0" stopColor="#ffffff" stopOpacity={1} />
277
- <stop offset="0.35" stopColor={A2} stopOpacity={0.9} />
278
- <stop offset="1" stopColor={A1} stopOpacity={0} />
279
- </radialGradient>
280
- </defs>
281
- {/* prompt → 根的滴线 */}
282
- {drip > 0 && (
283
- <g>
284
- <line x1={960} y1={dripY1} x2={960} y2={mix(dripY1, dripY2, drip)} stroke="url(#dcbEdge)" strokeWidth={2.5} strokeLinecap="round" strokeDasharray="2 7" />
285
- {drip < 1 && <circle cx={960} cy={mix(dripY1, dripY2, drip)} r={16} fill="url(#dcbHead)" />}
286
- </g>
287
- )}
288
- {NODES.filter((n) => n.parent >= 0).map((n) => {
289
- const g = edgeGeom(NODES[n.parent], n);
290
- const start = nodeStart(n) - LEAD;
291
- const grow = ramp(frame, start, EDGE_DUR, EASE.out);
292
- if (grow <= 0) return null;
293
- const tip = g.at(grow * g.len);
294
- const headOp = 1 - ramp(frame, start + EDGE_DUR - 4, 8, EASE.out);
295
- const port = ramp(frame, start + EDGE_DUR - 6, 10, EASE.overshoot);
296
- return (
297
- <g key={n.id}>
298
- {/* 柔光底线 + 实线 */}
299
- <path d={g.d} stroke={A1} strokeOpacity={0.18} strokeWidth={9} fill="none" strokeLinecap="round"
300
- strokeDasharray={`${g.len} ${g.len}`} strokeDashoffset={g.len * (1 - grow)} />
301
- <path d={g.d} stroke="url(#dcbEdge)" strokeWidth={2.5} fill="none" strokeLinecap="round"
302
- strokeDasharray={`${g.len} ${g.len}`} strokeDashoffset={g.len * (1 - grow)} />
303
- {headOp > 0 && <circle cx={tip.x} cy={tip.y} r={18} fill="url(#dcbHead)" opacity={headOp} />}
304
- <circle cx={n.x} cy={n.y - NODE_H / 2 - 8} r={6 * port} fill={L.bg[1]} stroke={A2} strokeWidth={2.5} />
305
- </g>
306
- );
307
- })}
308
- {/* 父端口:第一条出线起笔时出现 */}
309
- {NODES.filter((n) => n.level < 2).map((n) => {
310
- const firstChild = NODES.find((c) => c.parent === n.id)!;
311
- const port = ramp(frame, nodeStart(firstChild) - LEAD - 4, 8, EASE.overshoot);
312
- return <circle key={`p${n.id}`} cx={n.x} cy={n.y + NODE_H / 2 + 8} r={6 * port} fill={L.bg[1]} stroke={A1} strokeWidth={2.5} />;
313
- })}
314
- {/* 根的顶端口(接滴线) */}
315
- <circle cx={960} cy={dripY2} r={6 * ramp(frame, ROOT_DRIP + 4, 8, EASE.overshoot)} fill={L.bg[1]} stroke={A1} strokeWidth={2.5} />
316
- </svg>
317
-
318
- {NODES.map((n) => {
319
- const start = nodeStart(n);
320
- if (frame < start) return null;
321
- const pop = springAt(frame, start, { damping: 14, stiffness: 190 });
322
- const op = ramp(frame, start, 5, EASE.linear);
323
- const lift = (1 - Math.min(1, pop)) * 22; // 弹出时离地更高,落定阴影收紧
324
- const isRoot = n.level === 0;
325
- return (
326
- <div key={n.id} style={{
327
- position: 'absolute', left: n.x - NODE_W / 2, top: n.y - NODE_H / 2, width: NODE_W, height: NODE_H,
328
- borderRadius: 22, padding: isRoot ? 2 : 0, boxSizing: 'border-box',
329
- background: isRoot ? `linear-gradient(135deg, ${A1}, ${A2})` : undefined,
330
- boxShadow: `${softShadow(10 + lift, { color: L.shadow, strength: 2.6 })}${isRoot ? `, 0 0 50px ${alpha(A1, 0.25 + 0.2 * br)}` : ''}`,
331
- opacity: op,
332
- // 从顶端口"拉出":缩放原点 = 顶边中点
333
- transform: `translateY(${((1 - pop) * -18).toFixed(2)}px) scale(${(0.7 + 0.3 * pop).toFixed(4)})`, transformOrigin: '50% 0%',
334
- }}>
335
- <div style={{
336
- position: 'relative', width: '100%', height: '100%', borderRadius: isRoot ? 20 : 22, overflow: 'hidden', boxSizing: 'border-box',
337
- background: isRoot ? `linear-gradient(180deg, #2a2045, ${L.surface})` : `linear-gradient(180deg, ${alpha('#2a2340', 0.92)}, ${alpha(L.surface, 0.94)})`,
338
- border: isRoot ? undefined : `1px solid ${alpha('#ffffff', 0.09)}`,
339
- boxShadow: `inset 0 1px 0 ${alpha('#ffffff', isRoot ? 0.14 : 0.08)}`,
340
- }}>
341
- <EntityCard n={n} t={frame - start} />
342
- </div>
343
- </div>
344
- );
345
- })}
346
- </div>
347
- </AbsoluteFill>
348
- </AbsoluteFill>
349
- );
350
- };
1
+ // diagram-cascade-build —— miro-promo 104–116s
2
+ // prompt 打字 → 结构图逐层级联生成(根 → 2 子 → 4 孙),连线先于节点生长,成树后整棵呼吸一拍。
3
+ //
4
+ // 第二轮重设计(极光暗场 · AI 画布"一句话长出一棵树"):
5
+ // - look = aurora(深紫夜 · 紫粉光)。主角是"生长"本身:每条连线都带一颗发光的彗星头领跑,
6
+ // 线头到达子端口的那一帧子节点才从端口处"被拉出来"(缩放原点 = 节点顶边中点)——线牵节点,因果可见。
7
+ // - 生成源头清楚:prompt 条(video-shotcraft 的 AI 命令条,36px 大字)提交后描边变成流动的紫粉渐变(生成中),
8
+ // 从 prompt 条底部先滴下一条线接到根节点——树是从这句话里长出来的;生成完毕描边落定、右侧状态变成"7 tables"。
9
+ // - 节点做成为镜头设计的 ER 表卡:34px 表名 + 两行 mono 字段(PK/FK 小签),根节点用渐变描边当主角;
10
+ // 其余是带色相的深紫玻璃面板 + 发丝线 + 顶部内高光 + 两层软阴影。
11
+ // - 相机:开场推近在 prompt 条上(1.3× 居中,读字),提交后随树生长 smooth 拉远到 1.0 揭示整体结构(crane-back),
12
+ // 全程平滑无速度突变;成树后以树心为原点呼吸 1→1.03→1,背后极光同步亮一档。
13
+ //
14
+ // 时间表(30fps,共 180f):
15
+ // 0–10 舞台 + prompt 条落下(空条 + 光标闪)
16
+ // 8–44 打字 "Map the data model for Shotcraft"(每字 1–2f 不均匀,像真人敲)
17
+ // 46–50 敲完:描边转紫确认;48f 按下提交键(scale 0.9 → 回弹)
18
+ // 50–136 生成中:描边流光;50f 起相机 1.3→1.0 拉远(smooth,72f),prompt 条从画面中心升到顶部
19
+ // 54 prompt 底部滴线 → 62f 根节点从端口拉出(spring damping 14)
20
+ // 82/104 第 1 / 2 层:线先行 10f(16f ease-out + 彗星头),同层兄弟错峰 5f
21
+ // ~128 末节点落定 → 状态 "7 tables · 6 links"、描边流光收束
22
+ // 138–166 整棵呼吸一拍 + 极光亮一档
23
+ // 166–180 落定 hold:完整海报
24
+ import React from 'react';
25
+ import { AbsoluteFill, useCurrentFrame } from 'remotion';
26
+ import { EASE, FONT, mix, ramp, softShadow } from '../../_fixtures/Polish';
27
+ import { Dust, LOOKS, Stage, alpha, springAt, type } from '../../_fixtures/Look';
28
+
29
+ export const DIAGRAM_CASCADE_BUILD_DURATION = 180;
30
+
31
+ const L = LOOKS.aurora;
32
+ const A1 = L.accent; // 紫
33
+ const A2 = L.accent2; // 粉(点缀:渐变另一端)
34
+
35
+ const PROMPT = 'Map the data model for Shotcraft'; // 与原句同节奏:提交帧仍是 50f
36
+ const TYPE_START = 8;
37
+ // 每个字符的敲击间隔(帧):确定性"人手节奏"——词间空格多停半拍
38
+ const charGap = (i: number) => (PROMPT[i] === ' ' ? 1.7 : 0.95 + 0.25 * Math.abs(Math.sin(i * 2.17)));
39
+ const CHAR_T: number[] = [];
40
+ {
41
+ let t = TYPE_START;
42
+ for (let i = 0; i < PROMPT.length; i++) {
43
+ t += charGap(i);
44
+ CHAR_T.push(t);
45
+ }
46
+ }
47
+ const TYPE_END = CHAR_T[CHAR_T.length - 1];
48
+ const SUBMIT = Math.round(TYPE_END) + 4;
49
+
50
+ // ── 树布局(画布坐标,节点中心)──
51
+ const NODE_W = 344;
52
+ const NODE_H = 158;
53
+ type Field = [string, string, '' | 'PK' | 'FK'];
54
+ type Node = { id: number; x: number; y: number; level: number; parent: number; name: string; fields: Field[] };
55
+ const NODES: Node[] = [
56
+ // video-shotcraft 自己的数据模型:成片工程 → 分镜 / 渲染任务 → 镜头、配方卡、输出、预设
57
+ { id: 0, x: 960, y: 372, level: 0, parent: -1, name: 'Project', fields: [['id', 'uuid', 'PK'], ['title', 'text', '']] },
58
+ { id: 1, x: 540, y: 608, level: 1, parent: 0, name: 'Storyboard', fields: [['id', 'uuid', 'PK'], ['proj_id', 'uuid', 'FK']] },
59
+ { id: 2, x: 1380, y: 608, level: 1, parent: 0, name: 'RenderJob', fields: [['id', 'uuid', 'PK'], ['proj_id', 'uuid', 'FK']] },
60
+ { id: 3, x: 320, y: 852, level: 2, parent: 1, name: 'Shot', fields: [['board_id', 'uuid', 'FK'], ['frames', 'int', '']] },
61
+ { id: 4, x: 760, y: 852, level: 2, parent: 1, name: 'Recipe', fields: [['shot_id', 'uuid', 'FK'], ['move', 'enum', '']] },
62
+ { id: 5, x: 1160, y: 852, level: 2, parent: 2, name: 'Output', fields: [['job_id', 'uuid', 'FK'], ['codec', 'text', '']] },
63
+ { id: 6, x: 1600, y: 852, level: 2, parent: 2, name: 'Preset', fields: [['id', 'uuid', 'PK'], ['fps', 'int', '']] },
64
+ ];
65
+ const PROMPT_Y = 96; // prompt 条顶
66
+ const PROMPT_H = 100;
67
+ const ROOT_DRIP = SUBMIT + 6; // 滴线起笔
68
+ const CASCADE_START = SUBMIT + 14; // 根节点出现
69
+ const LEVEL_GAP = 22;
70
+ const SIBLING_STAGGER = 5;
71
+ const LEAD = 10; // 线比子节点早到
72
+ const EDGE_DUR = 16;
73
+
74
+ const nodeStart = (n: Node) => {
75
+ if (n.level === 0) return CASCADE_START;
76
+ const siblingIdx = NODES.filter((m) => m.level === n.level && m.id < n.id).length;
77
+ return CASCADE_START + n.level * LEVEL_GAP + siblingIdx * SIBLING_STAGGER;
78
+ };
79
+ const LAST = nodeStart(NODES[NODES.length - 1]);
80
+ const DONE = LAST + 12;
81
+ const BREATHE = DONE + 10;
82
+
83
+ // ── 圆角折线(父底端口 → 下探 → 横移 → 下探到子顶端口),用 SVG 圆弧,长度可精确计算 ──
84
+ const R = 22;
85
+ const edgeGeom = (p: Node, c: Node) => {
86
+ const x1 = p.x, y1 = p.y + NODE_H / 2 + 8, x2 = c.x, y2 = c.y - NODE_H / 2 - 8;
87
+ const my = (y1 + y2) / 2;
88
+ const dir = Math.sign(x2 - x1);
89
+ const r = Math.min(R, Math.abs(x2 - x1) / 2);
90
+ const sweep1 = dir > 0 ? 0 : 1;
91
+ const sweep2 = dir > 0 ? 1 : 0;
92
+ const d = `M ${x1} ${y1} L ${x1} ${my - r} A ${r} ${r} 0 0 ${sweep1} ${x1 + dir * r} ${my} L ${x2 - dir * r} ${my} A ${r} ${r} 0 0 ${sweep2} ${x2} ${my + r} L ${x2} ${y2}`;
93
+ const s1 = my - r - y1, a = (Math.PI * r) / 2, h = Math.abs(x2 - x1) - 2 * r, s3 = y2 - my - r;
94
+ const len = s1 + a + h + a + s3;
95
+ // 沿路径弧长 u(px)取点:给彗星头定位
96
+ const at = (u: number) => {
97
+ if (u <= s1) return { x: x1, y: y1 + u };
98
+ u -= s1;
99
+ if (u <= a) { const th = u / r; return { x: x1 + dir * r * (1 - Math.cos(th)), y: my - r + r * Math.sin(th) }; }
100
+ u -= a;
101
+ if (u <= h) return { x: x1 + dir * (r + u), y: my };
102
+ u -= h;
103
+ if (u <= a) { const th = u / r; return { x: x2 - dir * r + dir * r * Math.sin(th), y: my + r - r * Math.cos(th) }; }
104
+ u -= a;
105
+ return { x: x2, y: my + r + Math.min(u, s3) };
106
+ };
107
+ return { d, len, at };
108
+ };
109
+
110
+ // ── 小图标 ──
111
+ const SparkIcon: React.FC<{ c: string; size?: number }> = ({ c, size = 34 }) => (
112
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
113
+ <path d="M12 2.5l2.1 6.4 6.4 2.1-6.4 2.1L12 19.5l-2.1-6.4L3.5 11l6.4-2.1z" fill={c} />
114
+ <path d="M19 15.5l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8z" fill={c} opacity={0.6} />
115
+ </svg>
116
+ );
117
+ const TableIcon: React.FC<{ c: string }> = ({ c }) => (
118
+ <svg width={26} height={26} viewBox="0 0 18 18" fill="none">
119
+ <rect x={2} y={3} width={14} height={12} rx={2.5} stroke={c} strokeWidth={1.5} />
120
+ <path d="M2 7.5h14M7 7.5V15" stroke={c} strokeWidth={1.5} />
121
+ </svg>
122
+ );
123
+
124
+ // ── ER 表卡 ──
125
+ const EntityCard: React.FC<{ n: Node; t: number }> = ({ n, t }) => {
126
+ const root = n.level === 0;
127
+ const head = ramp(t, 3, 8, EASE.out);
128
+ const row = (i: number) => ramp(t, 7 + i * 3, 9, EASE.out);
129
+ return (
130
+ <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column' }}>
131
+ <div style={{
132
+ height: 66, display: 'flex', alignItems: 'center', gap: 14, padding: '0 24px',
133
+ borderBottom: `1px solid ${alpha('#ffffff', root ? 0.12 : 0.07)}`,
134
+ opacity: head, transform: `translateY(${((1 - head) * 6).toFixed(2)}px)`,
135
+ }}>
136
+ <TableIcon c={root ? A1 : L.ink3} />
137
+ <span style={{ ...type(34, 650), color: L.ink }}>{n.name}</span>
138
+ </div>
139
+ <div style={{ padding: '14px 24px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
140
+ {n.fields.map(([k, ty, key], i) => (
141
+ <div key={k} style={{
142
+ display: 'flex', alignItems: 'center', gap: 10, height: 26, ...type(22, 500, { mono: true }),
143
+ opacity: row(i), transform: `translateX(${((1 - row(i)) * -8).toFixed(2)}px)`,
144
+ }}>
145
+ <span style={{ color: L.ink2 }}>{k}</span>
146
+ {key && (
147
+ <span style={{
148
+ ...type(15, 700, { caps: true }), padding: '3px 7px', borderRadius: 6,
149
+ color: key === 'PK' ? A1 : A2, background: alpha(key === 'PK' ? A1 : A2, 0.14),
150
+ }}>{key}</span>
151
+ )}
152
+ <span style={{ marginLeft: 'auto', color: L.ink3 }}>{ty}</span>
153
+ </div>
154
+ ))}
155
+ </div>
156
+ </div>
157
+ );
158
+ };
159
+
160
+ export const DiagramCascadeBuild: React.FC = () => {
161
+ const frame = useCurrentFrame();
162
+
163
+ // ── prompt ──
164
+ let typed = 0;
165
+ while (typed < PROMPT.length && CHAR_T[typed] <= frame) typed++;
166
+ const caretOn = frame < SUBMIT && (typed < PROMPT.length || Math.floor((frame - TYPE_END) / 7) % 2 === 0);
167
+ const confirm = ramp(frame, TYPE_END, 6, EASE.out);
168
+ const press = frame < SUBMIT ? 0 : frame < SUBMIT + 3 ? ramp(frame, SUBMIT, 3, EASE.out) : 1 - ramp(frame, SUBMIT + 3, 10, EASE.out);
169
+ const promptIn = ramp(frame, 0, 14, EASE.snappy);
170
+ const generating = ramp(frame, SUBMIT, 8, EASE.out) * (1 - ramp(frame, DONE, 12, EASE.out));
171
+ const doneIn = ramp(frame, DONE, 14, EASE.snappy);
172
+ const flow = Math.max(0, frame - SUBMIT) * 0.012; // 描边流光相位
173
+
174
+ // ── 相机:推近 prompt → 提交后拉远揭示全树 ──
175
+ const pull = ramp(frame, SUBMIT + 2, 72, EASE.smooth);
176
+ const cam = mix(1.3, 1, pull);
177
+ const camY = mix(340, 0, pull); // 推近时把 prompt 条拉到画面正中
178
+
179
+ // ── 成树呼吸 ──
180
+ const br = ramp(frame, BREATHE, 14, EASE.smooth) - ramp(frame, BREATHE + 14, 14, EASE.smooth);
181
+ const breathe = 1 + 0.03 * br;
182
+ const auroraUp = ramp(frame, BREATHE - 6, 24, EASE.out);
183
+
184
+ const drip = ramp(frame, ROOT_DRIP, 8, EASE.out);
185
+ const root = NODES[0];
186
+ const dripY1 = PROMPT_Y + PROMPT_H + 4;
187
+ const dripY2 = root.y - NODE_H / 2 - 8;
188
+
189
+ return (
190
+ <AbsoluteFill style={{ background: L.bg[1], overflow: 'hidden', fontFamily: FONT.sans }}>
191
+ <Stage look={L} keyLight={{ x: 0.5, y: 0.05 }} fill={{ x: 0.82, y: 0.95 }} breathe={0.5}>
192
+ {/* 树后的极光:随生成逐渐亮起,成树时再亮一档 */}
193
+ <div style={{
194
+ position: 'absolute', left: 260, right: 260, top: 380, height: 640,
195
+ background: `radial-gradient(ellipse 50% 50% at 35% 55%, ${alpha(A1, 0.1 + 0.12 * auroraUp)} 0%, transparent 70%), radial-gradient(ellipse 45% 45% at 70% 60%, ${alpha(A2, 0.05 + 0.08 * auroraUp)} 0%, transparent 70%)`,
196
+ opacity: ramp(frame, SUBMIT, 60, EASE.out),
197
+ }} />
198
+ {/* 画布点阵 */}
199
+ <AbsoluteFill style={{
200
+ backgroundImage: `radial-gradient(${alpha(L.ink, 0.12)} 1.4px, transparent 1.7px)`,
201
+ backgroundSize: '40px 40px', backgroundPosition: '0 16px',
202
+ WebkitMaskImage: 'radial-gradient(ellipse 60% 62% at 50% 58%, #000 25%, transparent 100%)',
203
+ maskImage: 'radial-gradient(ellipse 60% 62% at 50% 58%, #000 25%, transparent 100%)',
204
+ }} />
205
+ <Dust look={L} count={22} seed={5} drift={0.18} opacity={0.35} />
206
+ </Stage>
207
+
208
+ <AbsoluteFill style={{ transform: `translateY(${camY.toFixed(2)}px) scale(${cam.toFixed(4)})`, transformOrigin: '50% 14%' }}>
209
+ {/* ── prompt 条:渐变描边(生成中流动)+ 内面板 ── */}
210
+ <div style={{
211
+ position: 'absolute', left: 960 - 560, top: PROMPT_Y, width: 1120, height: PROMPT_H, borderRadius: 50,
212
+ padding: 2, boxSizing: 'border-box',
213
+ background: alpha(A1, 0.14 + 0.4 * confirm),
214
+ boxShadow: `0 0 ${(30 + 40 * generating).toFixed(1)}px ${alpha(A1, 0.1 + 0.25 * generating)}, ${softShadow(24, { color: L.shadow, strength: 2.4 })}`,
215
+ opacity: promptIn, transform: `translateY(${((1 - promptIn) * -20).toFixed(2)}px)`,
216
+ }}>
217
+ {/* 生成中:流动的紫粉渐变描边;完成后留一道静止的渐变边 */}
218
+ <div style={{
219
+ position: 'absolute', inset: 0, borderRadius: 50,
220
+ background: `linear-gradient(90deg, ${A1}, ${A2}, ${A1}, ${A2}, ${A1})`, backgroundSize: '300% 100%',
221
+ backgroundPosition: `${(-flow * 100).toFixed(2)}% 0`, opacity: Math.max(generating, 0.55 * doneIn),
222
+ }} />
223
+ <div style={{
224
+ position: 'relative', width: '100%', height: '100%', borderRadius: 48, boxSizing: 'border-box',
225
+ background: `linear-gradient(180deg, ${L.surface2}, ${L.surface})`,
226
+ boxShadow: `inset 0 1px 0 ${alpha('#ffffff', 0.08)}`,
227
+ display: 'flex', alignItems: 'center', padding: '0 16px 0 30px',
228
+ }}>
229
+ <div style={{ marginRight: 20, flexShrink: 0, display: 'grid', placeItems: 'center', filter: `drop-shadow(0 0 ${8 + 10 * generating}px ${alpha(A1, 0.6)})` }}>
230
+ <SparkIcon c={A1} />
231
+ </div>
232
+ <span style={{ ...type(36, 520), color: L.ink, whiteSpace: 'nowrap' }}>
233
+ {PROMPT.slice(0, typed)}
234
+ <span style={{
235
+ display: 'inline-block', width: 3, height: 40, marginLeft: 4, verticalAlign: -7, borderRadius: 2,
236
+ background: A1, opacity: caretOn ? 1 : 0,
237
+ }} />
238
+ </span>
239
+ {/* 右侧:提交键 → 生成中 → 完成状态 */}
240
+ <div style={{ marginLeft: 'auto', position: 'relative', height: 68, display: 'flex', alignItems: 'center' }}>
241
+ <div style={{
242
+ position: 'absolute', right: 0, top: 0, whiteSpace: 'nowrap', height: 68, display: 'flex', alignItems: 'center', gap: 12,
243
+ opacity: doneIn, transform: `translateY(${((1 - doneIn) * 12).toFixed(2)}px)`,
244
+ ...type(28, 560), color: L.ink2, paddingRight: 14,
245
+ }}>
246
+ <svg width={28} height={28} viewBox="0 0 24 24" fill="none">
247
+ <circle cx={12} cy={12} r={10} fill={alpha(A1, 0.18)} />
248
+ <path d="M7.5 12.3l3 3 6-6.3" stroke={A1} strokeWidth={2.2} strokeLinecap="round" strokeLinejoin="round" />
249
+ </svg>
250
+ 7 tables · 6 links
251
+ </div>
252
+ <div style={{
253
+ width: 68, height: 68, borderRadius: 34, display: 'grid', placeItems: 'center',
254
+ background: confirm > 0 ? `linear-gradient(135deg, ${A1}, ${A2})` : alpha('#ffffff', 0.06),
255
+ opacity: (0.4 + 0.6 * confirm) * (1 - doneIn),
256
+ transform: `scale(${(1 - 0.1 * press) * (1 - 0.3 * doneIn)})`,
257
+ boxShadow: confirm > 0.5 ? `0 6px 20px -6px ${alpha(A2, 0.7)}` : 'none',
258
+ }}>
259
+ <svg width={30} height={30} viewBox="0 0 24 24" fill="none">
260
+ <path d="M12 19V5M6 11l6-6 6 6" stroke={confirm > 0.5 ? L.onAccent : L.ink3} strokeWidth={2.6} strokeLinecap="round" strokeLinejoin="round" />
261
+ </svg>
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </div>
266
+
267
+ {/* ── 树(呼吸以树心为原点) ── */}
268
+ <div style={{ position: 'absolute', inset: 0, transform: `scale(${breathe.toFixed(4)})`, transformOrigin: '960px 620px' }}>
269
+ <svg width={1920} height={1080} style={{ position: 'absolute', inset: 0, overflow: 'visible' }}>
270
+ <defs>
271
+ <linearGradient id="dcbEdge" x1="0" y1="300" x2="0" y2="800" gradientUnits="userSpaceOnUse">
272
+ <stop offset="0" stopColor={A1} stopOpacity={0.85} />
273
+ <stop offset="1" stopColor={A2} stopOpacity={0.7} />
274
+ </linearGradient>
275
+ <radialGradient id="dcbHead">
276
+ <stop offset="0" stopColor="#ffffff" stopOpacity={1} />
277
+ <stop offset="0.35" stopColor={A2} stopOpacity={0.9} />
278
+ <stop offset="1" stopColor={A1} stopOpacity={0} />
279
+ </radialGradient>
280
+ </defs>
281
+ {/* prompt → 根的滴线 */}
282
+ {drip > 0 && (
283
+ <g>
284
+ <line x1={960} y1={dripY1} x2={960} y2={mix(dripY1, dripY2, drip)} stroke="url(#dcbEdge)" strokeWidth={2.5} strokeLinecap="round" strokeDasharray="2 7" />
285
+ {drip < 1 && <circle cx={960} cy={mix(dripY1, dripY2, drip)} r={16} fill="url(#dcbHead)" />}
286
+ </g>
287
+ )}
288
+ {NODES.filter((n) => n.parent >= 0).map((n) => {
289
+ const g = edgeGeom(NODES[n.parent], n);
290
+ const start = nodeStart(n) - LEAD;
291
+ const grow = ramp(frame, start, EDGE_DUR, EASE.out);
292
+ if (grow <= 0) return null;
293
+ const tip = g.at(grow * g.len);
294
+ const headOp = 1 - ramp(frame, start + EDGE_DUR - 4, 8, EASE.out);
295
+ const port = ramp(frame, start + EDGE_DUR - 6, 10, EASE.overshoot);
296
+ return (
297
+ <g key={n.id}>
298
+ {/* 柔光底线 + 实线 */}
299
+ <path d={g.d} stroke={A1} strokeOpacity={0.18} strokeWidth={9} fill="none" strokeLinecap="round"
300
+ strokeDasharray={`${g.len} ${g.len}`} strokeDashoffset={g.len * (1 - grow)} />
301
+ <path d={g.d} stroke="url(#dcbEdge)" strokeWidth={2.5} fill="none" strokeLinecap="round"
302
+ strokeDasharray={`${g.len} ${g.len}`} strokeDashoffset={g.len * (1 - grow)} />
303
+ {headOp > 0 && <circle cx={tip.x} cy={tip.y} r={18} fill="url(#dcbHead)" opacity={headOp} />}
304
+ <circle cx={n.x} cy={n.y - NODE_H / 2 - 8} r={6 * port} fill={L.bg[1]} stroke={A2} strokeWidth={2.5} />
305
+ </g>
306
+ );
307
+ })}
308
+ {/* 父端口:第一条出线起笔时出现 */}
309
+ {NODES.filter((n) => n.level < 2).map((n) => {
310
+ const firstChild = NODES.find((c) => c.parent === n.id)!;
311
+ const port = ramp(frame, nodeStart(firstChild) - LEAD - 4, 8, EASE.overshoot);
312
+ return <circle key={`p${n.id}`} cx={n.x} cy={n.y + NODE_H / 2 + 8} r={6 * port} fill={L.bg[1]} stroke={A1} strokeWidth={2.5} />;
313
+ })}
314
+ {/* 根的顶端口(接滴线) */}
315
+ <circle cx={960} cy={dripY2} r={6 * ramp(frame, ROOT_DRIP + 4, 8, EASE.overshoot)} fill={L.bg[1]} stroke={A1} strokeWidth={2.5} />
316
+ </svg>
317
+
318
+ {NODES.map((n) => {
319
+ const start = nodeStart(n);
320
+ if (frame < start) return null;
321
+ const pop = springAt(frame, start, { damping: 14, stiffness: 190 });
322
+ const op = ramp(frame, start, 5, EASE.linear);
323
+ const lift = (1 - Math.min(1, pop)) * 22; // 弹出时离地更高,落定阴影收紧
324
+ const isRoot = n.level === 0;
325
+ return (
326
+ <div key={n.id} style={{
327
+ position: 'absolute', left: n.x - NODE_W / 2, top: n.y - NODE_H / 2, width: NODE_W, height: NODE_H,
328
+ borderRadius: 22, padding: isRoot ? 2 : 0, boxSizing: 'border-box',
329
+ background: isRoot ? `linear-gradient(135deg, ${A1}, ${A2})` : undefined,
330
+ boxShadow: `${softShadow(10 + lift, { color: L.shadow, strength: 2.6 })}${isRoot ? `, 0 0 50px ${alpha(A1, 0.25 + 0.2 * br)}` : ''}`,
331
+ opacity: op,
332
+ // 从顶端口"拉出":缩放原点 = 顶边中点
333
+ transform: `translateY(${((1 - pop) * -18).toFixed(2)}px) scale(${(0.7 + 0.3 * pop).toFixed(4)})`, transformOrigin: '50% 0%',
334
+ }}>
335
+ <div style={{
336
+ position: 'relative', width: '100%', height: '100%', borderRadius: isRoot ? 20 : 22, overflow: 'hidden', boxSizing: 'border-box',
337
+ background: isRoot ? `linear-gradient(180deg, #2a2045, ${L.surface})` : `linear-gradient(180deg, ${alpha('#2a2340', 0.92)}, ${alpha(L.surface, 0.94)})`,
338
+ border: isRoot ? undefined : `1px solid ${alpha('#ffffff', 0.09)}`,
339
+ boxShadow: `inset 0 1px 0 ${alpha('#ffffff', isRoot ? 0.14 : 0.08)}`,
340
+ }}>
341
+ <EntityCard n={n} t={frame - start} />
342
+ </div>
343
+ </div>
344
+ );
345
+ })}
346
+ </div>
347
+ </AbsoluteFill>
348
+ </AbsoluteFill>
349
+ );
350
+ };