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,358 +1,358 @@
1
- /**
2
- * DatavizLandscapeOpen — 暗场支流线束地景开场
3
- * 配方卡: references/shots/opening/dataviz-landscape-open.md
4
- *
5
- * 第二轮重设计(石墨 · 荧光黄绿 · 真透视地景):
6
- * - look = lime。不再是平面 SVG 横移:整片线束画在一张真透视的地平面上(针孔投影,相机高 220、焦距 1100),
7
- * 一条荧光黄绿主干从镜头脚下蜿蜒奔向画面右 1/3 处的消失点(汇点),11 条灰绿支流从两侧画外切向汇入。
8
- * 景深 / 视差 / 雾全部由投影深度算出来:近处线条又宽又虚(按深度分进模糊层)、中景锐利、远处变细隐入地平线。
9
- * - 相机低空沿河道前飞 + 横向缓移(dolly + truck),整段 bezier 减速:开场即在飞、收尾缓停接字标,不急刹。
10
- * - 中景支流上钉 6 枚 video-shotcraft 镜头标签(立杆图钉 + 等宽镜头号胶囊 + 运镜名),随透视逐渐变大、向两侧散开;
11
- * 隐喻:每条支流是一个镜头,汇成主干这一支成片;
12
- * 生长完成后沿线有亮脉冲低速流向汇点(数据在流)。
13
- * - 收尾:消失点亮起一团黄绿光(交棒亮部),天空里落一行大标题「Every shot, / one film.」(眉题 video-shotcraft 字标小写),
14
- * 结尾帧是完整的海报。
15
- *
16
- * 时间表(30fps,共 180f):
17
- * 0–10 从深场浮出(地平线光带首帧就在)
18
- * 0–36 主干由近及远 draw-on(out-cubic),笔尖光点
19
- * 8–70 支流错峰生长(每条 4–6f,近处先),笔尖光点
20
- * 44–104 标签非均匀错峰立起(图钉过冲 → 立杆 → 胶囊去模糊),104f 后不再新增
21
- * 60–180 流动脉冲;相机全程前飞,140f 后明显减速
22
- * 104–140 标题:眉题 + 两行逐词升起;汇点光 120f 起升亮
23
- * 140–180 hold:相机缓停、脉冲流动,海报落定
24
- */
25
- import React from 'react';
26
- import {AbsoluteFill, useCurrentFrame} from 'remotion';
27
- import {EASE, FONT, bezier, mix, ramp} from '../../_fixtures/Polish';
28
- import {Dust, LOOKS, Stage, TextReveal, alpha, type} from '../../_fixtures/Look';
29
- import {BRAND} from '../../_fixtures/Brand';
30
-
31
- const DUR = 180; // 6s @30fps
32
- export const DATAVIZ_LANDSCAPE_OPEN_DURATION = DUR;
33
-
34
- const L = LOOKS.lime;
35
- const HY = 420; // 地平线(屏幕 y)
36
- const F = 1100; // 焦距
37
- const CAM_H = 220; // 相机离地高度
38
- const SLOPE = 0.29; // 主干总体走向(dX/dZ)→ 消失点 x = 960 + F*SLOPE ≈ 1279(右 1/3)
39
- const VPX = 960 + F * SLOPE;
40
-
41
- // ───────────── 相机 ─────────────
42
- const camPath = bezier(0.3, 0.3, 0.55, 1); // 匀速起步、尾段减速缓停
43
- const CAM_DIST = 950;
44
- const camAt = (frame: number) => {
45
- const t = Math.min(1, Math.max(0, frame / (DUR - 1)));
46
- const z = CAM_DIST * camPath(t);
47
- const lat = mix(-140, 110, EASE.smooth(t)); // 横向缓移:近远景相对错动 = 视差
48
- return {z, x: SLOPE * z + lat};
49
- };
50
-
51
- type P3 = {x: number; z: number};
52
- const project = (p: P3, cam: {x: number; z: number}) => {
53
- const zr = p.z - cam.z;
54
- return {sx: 960 + (F * (p.x - cam.x)) / zr, sy: HY + (F * CAM_H) / zr, zr};
55
- };
56
-
57
- // ───────────── 世界几何(地平面 X/Z)─────────────
58
- const trunkX = (z: number) => SLOPE * z - 160 + 150 * Math.sin(z / 950);
59
- const trunkDX = (z: number) => SLOPE + (150 / 950) * Math.cos(z / 950);
60
-
61
- // 主干:-300 → 14000,近密远疏采样
62
- const TRUNK: P3[] = Array.from({length: 261}, (_, i) => {
63
- const z = -300 + Math.pow(i / 260, 1.7) * 14300;
64
- return {x: trunkX(z), z};
65
- });
66
-
67
- // 三次贝塞尔按弧长等距重采样
68
- const bez = (a: P3, b: P3, c: P3, d: P3, t: number): P3 => {
69
- const u = 1 - t;
70
- return {
71
- x: u * u * u * a.x + 3 * u * u * t * b.x + 3 * u * t * t * c.x + t * t * t * d.x,
72
- z: u * u * u * a.z + 3 * u * u * t * b.z + 3 * u * t * t * c.z + t * t * t * d.z,
73
- };
74
- };
75
- const resample = (at: (t: number) => P3, n: number) => {
76
- const raw = Array.from({length: 241}, (_, i) => at(i / 240));
77
- const cum = [0];
78
- for (let i = 1; i < raw.length; i++) cum.push(cum[i - 1] + Math.hypot(raw[i].x - raw[i - 1].x, raw[i].z - raw[i - 1].z));
79
- const total = cum[cum.length - 1];
80
- const out: P3[] = [];
81
- let j = 1;
82
- for (let k = 0; k <= n; k++) {
83
- const target = (k / n) * total;
84
- while (j < raw.length - 1 && cum[j] < target) j++;
85
- const f = (target - cum[j - 1]) / Math.max(1e-6, cum[j] - cum[j - 1]);
86
- out.push({x: mix(raw[j - 1].x, raw[j].x, f), z: mix(raw[j - 1].z, raw[j].z, f)});
87
- }
88
- return out;
89
- };
90
-
91
- // 支流:起点在两侧画外,切向汇入主干(汇入点切线 = 主干切线)
92
- type TribSpec = {side: number; z0: number; off: number; zm: number; lm: number; grow: number; w: number};
93
- const TRIB_SPECS: TribSpec[] = [
94
- {side: -1, z0: -260, off: 700, zm: 1500, lm: 520, grow: 8, w: 5},
95
- {side: 1, z0: -120, off: 900, zm: 2100, lm: 640, grow: 11, w: 5},
96
- {side: -1, z0: 500, off: 1500, zm: 2700, lm: 760, grow: 16, w: 4.4},
97
- {side: 1, z0: 800, off: 1800, zm: 3300, lm: 820, grow: 20, w: 4.4},
98
- {side: -1, z0: 1400, off: 2300, zm: 3900, lm: 900, grow: 25, w: 4.2},
99
- {side: 1, z0: 1700, off: 2500, zm: 4600, lm: 980, grow: 29, w: 4.2},
100
- {side: -1, z0: 2500, off: 2900, zm: 5300, lm: 1050, grow: 34, w: 4.2},
101
- {side: 1, z0: 3100, off: 3200, zm: 6100, lm: 1150, grow: 38, w: 4.2},
102
- {side: -1, z0: 4100, off: 3600, zm: 7100, lm: 1250, grow: 43, w: 4.2},
103
- {side: 1, z0: 5000, off: 3900, zm: 8200, lm: 1350, grow: 47, w: 4.2},
104
- {side: 1, z0: -420, off: 260, zm: 980, lm: 380, grow: 4, w: 6}, // 贴着镜头右下方掠过的近景支流(大虚焦)
105
- ];
106
- const TRIBS = TRIB_SPECS.map((s) => {
107
- const end: P3 = {x: trunkX(s.zm), z: s.zm};
108
- const dx = trunkDX(s.zm);
109
- const dl = Math.hypot(dx, 1);
110
- const p2: P3 = {x: end.x - (dx / dl) * s.lm, z: end.z - (1 / dl) * s.lm};
111
- const p0: P3 = {x: trunkX(s.z0) + s.side * s.off, z: s.z0};
112
- const p1: P3 = {x: p0.x + (end.x - p0.x) * 0.12, z: p0.z + (end.z - p0.z) * 0.5};
113
- return {...s, pts: resample((t) => bez(p0, p1, p2, end, t), 90)};
114
- });
115
-
116
- // ───────────── 线段渲染:按深度分层(近虚 / 中实 / 远雾)─────────────
117
- const smooth01 = (a: number, b: number, x: number) => {
118
- const t = Math.min(1, Math.max(0, (x - a) / (b - a)));
119
- return t * t * (3 - 2 * t);
120
- };
121
- type Seg = {x1: number; y1: number; x2: number; y2: number; w: number; o: number; c: string};
122
-
123
- const emitLine = (
124
- pts: P3[], g: number, cam: {x: number; z: number}, opts: {w: number; color: string; base: number; ramp?: boolean; pulse: (u: number) => number},
125
- sharp: Seg[], near: Seg[],
126
- ) => {
127
- const n = pts.length - 1;
128
- const reach = g * n;
129
- const kMax = Math.min(n, Math.ceil(reach));
130
- for (let k = 0; k < kMax; k++) {
131
- const a = pts[k];
132
- const b0 = pts[k + 1];
133
- const f = Math.min(1, reach - k);
134
- const b = f < 1 ? {x: mix(a.x, b0.x, f), z: mix(a.z, b0.z, f)} : b0;
135
- if (a.z - cam.z < 70 || b.z - cam.z < 70) continue;
136
- const pa = project(a, cam);
137
- const pb = project(b, cam);
138
- if ((pa.sx < -200 && pb.sx < -200) || (pa.sx > 2120 && pb.sx > 2120) || (pa.sy > 1300 && pb.sy > 1300)) continue;
139
- const zr = (pa.zr + pb.zr) / 2;
140
- const u = (k + 0.5 * f) / n;
141
- const fog = 1 - smooth01(2600, 11000, zr); // 远处雾化
142
- const lift = opts.ramp ? 0.3 + 0.7 * Math.pow(u, 0.8) : 1; // 支流:源头淡、汇入处亮
143
- // 脉冲只在中远景显形:近处一段线在屏幕上很长,逐段明暗会读成台阶
144
- const pv = opts.pulse(u);
145
- const o = opts.base * fog * lift * mix(1, pv, smooth01(500, 1400, zr));
146
- if (o < 0.01) continue;
147
- const w = Math.max(0.9, Math.min(46, (opts.w * F) / zr));
148
- const nearW = 1 - smooth01(420, 1050, zr); // 近景权重 → 进模糊层
149
- const seg = {x1: pa.sx, y1: pa.sy, x2: pb.sx, y2: pb.sy, w, c: opts.color};
150
- if (nearW < 0.98) sharp.push({...seg, o: o * (1 - nearW)});
151
- if (nearW > 0.02) near.push({...seg, w: w * 1.3, o: o * nearW * 0.7});
152
- }
153
- // 笔尖
154
- if (g > 0 && g < 1) {
155
- const k = Math.min(n - 1, Math.floor(reach));
156
- const f = reach - k;
157
- const tip = {x: mix(pts[k].x, pts[k + 1].x, f), z: mix(pts[k].z, pts[k + 1].z, f)};
158
- if (tip.z - cam.z > 70) return project(tip, cam);
159
- }
160
- return null;
161
- };
162
-
163
- // ───────────── 标签(中景,video-shotcraft 的镜头号 + 运镜名;字数与原 issue 标签相当,投影位置不变)─────────────
164
- // 位置按投影逐帧核过:起止两端都错开(不叠、不压汇点、不出画),近处一枚随前飞明显变大
165
- type LabelSpec = {trib: number; u: number; id: string; note: string; appear: number};
166
- const LABELS: LabelSpec[] = [
167
- {trib: 2, u: 0.6, id: 'SHOT-01', note: 'dolly in', appear: 44},
168
- {trib: 1, u: 0.75, id: 'SHOT-02', note: 'crash zoom', appear: 53},
169
- {trib: 3, u: 0.6, id: 'SHOT-03', note: 'whip pan', appear: 62},
170
- {trib: 6, u: 0.3, id: 'SHOT-04', note: 'beat cut', appear: 73},
171
- {trib: 7, u: 0.45, id: 'SHOT-05', note: 'tilt up', appear: 84},
172
- {trib: 8, u: 0.45, id: 'SHOT-06', note: 'lockup', appear: 96},
173
- ];
174
- const LABEL_PTS = LABELS.map((l) => {
175
- const pts = TRIBS[l.trib].pts;
176
- return {p: pts[Math.round(l.u * (pts.length - 1))]};
177
- });
178
-
179
- const Label: React.FC<{spec: LabelSpec; at: P3; frame: number; cam: {x: number; z: number}}> = ({spec, at, frame, cam}) => {
180
- const pr = project(at, cam);
181
- if (pr.zr < 200) return null;
182
- const k = Math.min(1.7, Math.max(0.7, 1500 / pr.zr)); // 透视缩放(近大远小),钳住可读区间
183
- const fog = 1 - smooth01(3600, 8000, pr.zr);
184
- const pin = ramp(frame, spec.appear, 10, EASE.overshoot);
185
- const pinOp = ramp(frame, spec.appear, 4, EASE.out);
186
- const stem = ramp(frame, spec.appear + 2, 12, EASE.snappy);
187
- const tag = ramp(frame, spec.appear + 6, 14, EASE.snappy);
188
- // 立杆世界高度远低于相机高度 → 标签落在地平线以下、按深度上下错开(杆高≈相机高时所有标签都投影到地平线上挤成一排)
189
- const stemH = 44 * k;
190
- const fs = 25 * k;
191
- return (
192
- <div style={{position: 'absolute', left: 0, top: 0, opacity: fog}}>
193
- {/* 图钉(落在线上) */}
194
- <div style={{
195
- position: 'absolute', left: pr.sx - 6 * k, top: pr.sy - 6 * k, width: 12 * k, height: 12 * k, borderRadius: 2.5 * k,
196
- background: L.accent, opacity: pinOp, transform: `scale(${pin})`,
197
- boxShadow: `0 0 0 ${3 * k}px ${alpha(L.bg[2], 0.9)}, 0 0 ${18 * k}px ${alpha(L.accent, 0.7)}`,
198
- }} />
199
- {/* 立杆 */}
200
- <div style={{
201
- position: 'absolute', left: pr.sx - 0.75, top: pr.sy - 8 * k - stemH * stem, width: 1.5, height: stemH * stem,
202
- background: `linear-gradient(0deg, ${alpha(L.accent, 0.7)}, ${alpha(L.ink, 0.25)})`,
203
- }} />
204
- {/* ID 胶囊 */}
205
- <div style={{
206
- position: 'absolute', left: pr.sx - 2 * k, top: pr.sy - 8 * k - stemH - 46 * k + (1 - tag) * 14 * k,
207
- height: 46 * k, padding: `0 ${14 * k}px 0 ${12 * k}px`, borderRadius: 10 * k, boxSizing: 'border-box',
208
- display: 'flex', alignItems: 'center', gap: 10 * k, whiteSpace: 'nowrap',
209
- background: alpha('#141711', 0.82), border: `1px solid ${alpha(L.ink, 0.12)}`,
210
- boxShadow: `inset 0 1px 0 ${alpha('#ffffff', 0.06)}, 0 ${10 * k}px ${28 * k}px ${alpha('#000000', 0.5)}`,
211
- opacity: tag, filter: tag < 0.98 ? `blur(${((1 - tag) * 6).toFixed(2)}px)` : undefined,
212
- }}>
213
- <div style={{width: 7 * k, height: 7 * k, borderRadius: 4 * k, background: L.accent}} />
214
- <span style={{fontFamily: FONT.mono, fontSize: fs, fontWeight: 600, color: L.ink, letterSpacing: '0.02em'}}>{spec.id}</span>
215
- <span style={{fontFamily: FONT.sans, fontSize: fs * 0.82, fontWeight: 500, color: L.ink3}}>{spec.note}</span>
216
- </div>
217
- </div>
218
- );
219
- };
220
-
221
- // ───────────── 组件 ─────────────
222
- export const DatavizLandscapeOpen: React.FC = () => {
223
- const frame = useCurrentFrame();
224
- const cam = camAt(frame);
225
- const fadeUp = ramp(frame, 0, 12, EASE.out);
226
-
227
- const sharp: Seg[] = [];
228
- const near: Seg[] = [];
229
- const tips: {sx: number; sy: number; zr: number; trunk: boolean}[] = [];
230
-
231
- // 流动脉冲:生长完后沿线流向汇点的亮脉冲(窄峰,低速)
232
- const flowIn = (end: number) => ramp(frame, end, 24, EASE.smooth);
233
- const pulseFn = (end: number, n: number, speed: number, seed: number) => {
234
- const on = flowIn(end);
235
- return (u: number) => {
236
- const ph = u * n - frame * speed + seed;
237
- const c = Math.cos(ph * Math.PI * 2);
238
- return 0.7 + on * 0.55 * Math.pow(Math.max(0, c), 4);
239
- };
240
- };
241
-
242
- const trunkG = ramp(frame, 0, 36, EASE.out);
243
- TRIBS.forEach((t, i) => {
244
- const g = ramp(frame, t.grow, 34, EASE.out);
245
- const tip = emitLine(t.pts, g, cam, {w: t.w, color: L.ink2, base: 0.62, ramp: true, pulse: pulseFn(t.grow + 34, 2.2, 0.018, i * 0.37)}, sharp, near);
246
- if (tip) tips.push({...tip, trunk: false});
247
- });
248
- const tTip = emitLine(TRUNK, trunkG, cam, {w: 11, color: L.accent, base: 0.95, pulse: pulseFn(36, 4, 0.022, 0)}, sharp, near);
249
- if (tTip) tips.push({...tTip, trunk: true});
250
- const trunkSegs = sharp.filter((s) => s.c === L.accent);
251
-
252
- // 地面点阵:与世界锁定的网格,前飞时从远处涌来
253
- const dots: {x: number; y: number; r: number; o: number}[] = [];
254
- const STEP = 420;
255
- const zStart = Math.ceil((cam.z + 300) / STEP) * STEP;
256
- for (let z = zStart; z < cam.z + 9000; z += STEP) {
257
- for (let x = Math.floor((cam.x - 5200) / STEP) * STEP; x < cam.x + 5200; x += STEP) {
258
- const pr = project({x, z}, cam);
259
- if (pr.sx < -20 || pr.sx > 1940 || pr.sy > 1100) continue;
260
- const o = 0.28 * (1 - smooth01(2000, 9000, pr.zr)) * smooth01(300, 900, pr.zr);
261
- if (o < 0.01) continue;
262
- dots.push({x: pr.sx, y: pr.sy, r: Math.max(0.8, Math.min(3.2, 2400 / pr.zr)), o});
263
- }
264
- }
265
-
266
- const handoff = ramp(frame, 118, 50, EASE.swift);
267
- const lineRender = (s: Seg, i: number) => (
268
- <line key={i} x1={s.x1} y1={s.y1} x2={s.x2} y2={s.y2} stroke={s.c} strokeWidth={s.w} strokeOpacity={s.o} strokeLinecap="butt" />
269
- );
270
-
271
- return (
272
- <AbsoluteFill style={{background: L.bg[2], overflow: 'hidden'}}>
273
- <AbsoluteFill style={{opacity: 0.35 + 0.65 * fadeUp}}>
274
- <Stage look={L} keyLight={{x: VPX / 1920, y: HY / 1080}} fill={{x: 0.12, y: 0.95}} horizon={HY / 1080} intensity={0.55} grain={0.1} vignette={0.6}>
275
- {/* 天空里的极淡浮尘 */}
276
- <div style={{position: 'absolute', left: 0, right: 0, top: 0, height: HY, overflow: 'hidden'}}>
277
- <Dust look={L} count={26} seed={7} drift={0.12} opacity={0.35} color={L.ink2} />
278
- </div>
279
- {/* 地面:地平线以下略亮一档的冷灰绿,向近处压暗 */}
280
- <div style={{
281
- position: 'absolute', left: 0, right: 0, top: HY, bottom: 0,
282
- background: `linear-gradient(180deg, ${alpha('#2a3122', 0.55)} 0%, ${alpha('#141811', 0.3)} 30%, ${alpha('#050604', 0)} 100%)`,
283
- }} />
284
- {/* 地平线发丝线 */}
285
- <div style={{
286
- position: 'absolute', left: 0, right: 0, top: HY - 0.5, height: 1,
287
- background: `linear-gradient(90deg, ${alpha(L.ink, 0)} 0%, ${alpha(L.ink, 0.16)} 40%, ${alpha(L.accent, 0.35)} 66%, ${alpha(L.ink, 0.12)} 85%, ${alpha(L.ink, 0)} 100%)`,
288
- }} />
289
- </Stage>
290
-
291
- <svg width={1920} height={1080} style={{position: 'absolute', inset: 0}}>
292
- <defs>
293
- <filter id="dv-near" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="11" /></filter>
294
- <filter id="dv-glow" x="-10%" y="-10%" width="120%" height="120%"><feGaussianBlur stdDeviation="7" /></filter>
295
- <radialGradient id="dv-tip">
296
- <stop offset="0" stopColor="#ffffff" stopOpacity={0.9} />
297
- <stop offset="0.3" stopColor={L.accent} stopOpacity={0.35} />
298
- <stop offset="1" stopColor={L.accent} stopOpacity={0} />
299
- </radialGradient>
300
- </defs>
301
- {dots.map((d, i) => <circle key={i} cx={d.x} cy={d.y} r={d.r} fill={L.ink2} fillOpacity={d.o} />)}
302
- {/* 主干泛光(只给主角) */}
303
- <g filter="url(#dv-glow)" opacity={0.75}>
304
- {trunkSegs.map((s, i) => <line key={i} x1={s.x1} y1={s.y1} x2={s.x2} y2={s.y2} stroke={L.accent} strokeWidth={s.w * 3} strokeOpacity={s.o * 0.45} strokeLinecap="butt" />)}
305
- </g>
306
- {sharp.map(lineRender)}
307
- {tips.map((t, i) => {
308
- const r = Math.max(3, Math.min(18, (t.trunk ? 7000 : 4200) / t.zr));
309
- return (
310
- <g key={i}>
311
- <circle cx={t.sx} cy={t.sy} r={r * 5} fill="url(#dv-tip)" />
312
- <circle cx={t.sx} cy={t.sy} r={r * 0.6} fill="#ffffff" />
313
- </g>
314
- );
315
- })}
316
- </svg>
317
-
318
- {/* 汇点交棒亮部:消失点一团黄绿光,收尾升亮 */}
319
- <div style={{
320
- position: 'absolute', left: VPX - 520, top: HY - 260, width: 1040, height: 520, pointerEvents: 'none',
321
- background: `radial-gradient(50% 50% at 50% 50%, ${alpha('#f4ffd6', 0.55)} 0%, ${alpha(L.accent, 0.22)} 22%, ${alpha(L.accent, 0)} 70%)`,
322
- opacity: 0.25 + 0.75 * handoff, mixBlendMode: 'screen',
323
- }} />
324
- <div style={{
325
- position: 'absolute', left: VPX - 4, top: HY - 4, width: 8, height: 8, borderRadius: 4, background: '#f6ffe0',
326
- boxShadow: `0 0 18px 6px ${alpha(L.accent, 0.6)}`, opacity: 0.4 + 0.6 * handoff,
327
- }} />
328
-
329
- {/* 远的先画、近的后画:近处胶囊正确遮住远处图钉 */}
330
- {LABELS.map((l, i) => ({l, p: LABEL_PTS[i].p}))
331
- .sort((a, b) => b.p.z - a.p.z)
332
- .map(({l, p}) => (frame >= l.appear ? <Label key={l.id} spec={l} at={p} frame={frame} cam={cam} /> : null))}
333
-
334
- {/* 近景大虚焦层(在标签之上:前景掠过) */}
335
- <svg width={1920} height={1080} style={{position: 'absolute', inset: 0}}>
336
- <g filter="url(#dv-near)">{near.map(lineRender)}</g>
337
- </svg>
338
- </AbsoluteFill>
339
-
340
- {/* 标题:天空左上,收尾落字 */}
341
- <div style={{position: 'absolute', left: 120, top: 128}}>
342
- {/* 眉题:品牌名按字标规范全小写(不走大写科技字标) */}
343
- <div style={{
344
- fontFamily: FONT.mono, fontSize: 28, fontWeight: 600, color: L.accent, letterSpacing: '0.12em',
345
- opacity: ramp(frame, 104, 14, EASE.out), transform: `translateY(${(1 - ramp(frame, 104, 18, EASE.snappy)) * 12}px)`,
346
- }}>
347
- {BRAND.name} · shot recipes
348
- </div>
349
- <div style={{...type(108, 650), color: L.ink, marginTop: 26}}>
350
- <TextReveal text="Every shot," by="word" variant="rise" start={110} each={20} gap={5} />
351
- </div>
352
- <div style={{...type(108, 650), color: L.accent, marginTop: 4}}>
353
- <TextReveal text="one film." by="word" variant="rise" start={121} each={20} gap={5} />
354
- </div>
355
- </div>
356
- </AbsoluteFill>
357
- );
358
- };
1
+ /**
2
+ * DatavizLandscapeOpen — 暗场支流线束地景开场
3
+ * 配方卡: references/shots/opening/dataviz-landscape-open.md
4
+ *
5
+ * 第二轮重设计(石墨 · 荧光黄绿 · 真透视地景):
6
+ * - look = lime。不再是平面 SVG 横移:整片线束画在一张真透视的地平面上(针孔投影,相机高 220、焦距 1100),
7
+ * 一条荧光黄绿主干从镜头脚下蜿蜒奔向画面右 1/3 处的消失点(汇点),11 条灰绿支流从两侧画外切向汇入。
8
+ * 景深 / 视差 / 雾全部由投影深度算出来:近处线条又宽又虚(按深度分进模糊层)、中景锐利、远处变细隐入地平线。
9
+ * - 相机低空沿河道前飞 + 横向缓移(dolly + truck),整段 bezier 减速:开场即在飞、收尾缓停接字标,不急刹。
10
+ * - 中景支流上钉 6 枚 video-shotcraft 镜头标签(立杆图钉 + 等宽镜头号胶囊 + 运镜名),随透视逐渐变大、向两侧散开;
11
+ * 隐喻:每条支流是一个镜头,汇成主干这一支成片;
12
+ * 生长完成后沿线有亮脉冲低速流向汇点(数据在流)。
13
+ * - 收尾:消失点亮起一团黄绿光(交棒亮部),天空里落一行大标题「Every shot, / one film.」(眉题 video-shotcraft 字标小写),
14
+ * 结尾帧是完整的海报。
15
+ *
16
+ * 时间表(30fps,共 180f):
17
+ * 0–10 从深场浮出(地平线光带首帧就在)
18
+ * 0–36 主干由近及远 draw-on(out-cubic),笔尖光点
19
+ * 8–70 支流错峰生长(每条 4–6f,近处先),笔尖光点
20
+ * 44–104 标签非均匀错峰立起(图钉过冲 → 立杆 → 胶囊去模糊),104f 后不再新增
21
+ * 60–180 流动脉冲;相机全程前飞,140f 后明显减速
22
+ * 104–140 标题:眉题 + 两行逐词升起;汇点光 120f 起升亮
23
+ * 140–180 hold:相机缓停、脉冲流动,海报落定
24
+ */
25
+ import React from 'react';
26
+ import {AbsoluteFill, useCurrentFrame} from 'remotion';
27
+ import {EASE, FONT, bezier, mix, ramp} from '../../_fixtures/Polish';
28
+ import {Dust, LOOKS, Stage, TextReveal, alpha, type} from '../../_fixtures/Look';
29
+ import {BRAND} from '../../_fixtures/Brand';
30
+
31
+ const DUR = 180; // 6s @30fps
32
+ export const DATAVIZ_LANDSCAPE_OPEN_DURATION = DUR;
33
+
34
+ const L = LOOKS.lime;
35
+ const HY = 420; // 地平线(屏幕 y)
36
+ const F = 1100; // 焦距
37
+ const CAM_H = 220; // 相机离地高度
38
+ const SLOPE = 0.29; // 主干总体走向(dX/dZ)→ 消失点 x = 960 + F*SLOPE ≈ 1279(右 1/3)
39
+ const VPX = 960 + F * SLOPE;
40
+
41
+ // ───────────── 相机 ─────────────
42
+ const camPath = bezier(0.3, 0.3, 0.55, 1); // 匀速起步、尾段减速缓停
43
+ const CAM_DIST = 950;
44
+ const camAt = (frame: number) => {
45
+ const t = Math.min(1, Math.max(0, frame / (DUR - 1)));
46
+ const z = CAM_DIST * camPath(t);
47
+ const lat = mix(-140, 110, EASE.smooth(t)); // 横向缓移:近远景相对错动 = 视差
48
+ return {z, x: SLOPE * z + lat};
49
+ };
50
+
51
+ type P3 = {x: number; z: number};
52
+ const project = (p: P3, cam: {x: number; z: number}) => {
53
+ const zr = p.z - cam.z;
54
+ return {sx: 960 + (F * (p.x - cam.x)) / zr, sy: HY + (F * CAM_H) / zr, zr};
55
+ };
56
+
57
+ // ───────────── 世界几何(地平面 X/Z)─────────────
58
+ const trunkX = (z: number) => SLOPE * z - 160 + 150 * Math.sin(z / 950);
59
+ const trunkDX = (z: number) => SLOPE + (150 / 950) * Math.cos(z / 950);
60
+
61
+ // 主干:-300 → 14000,近密远疏采样
62
+ const TRUNK: P3[] = Array.from({length: 261}, (_, i) => {
63
+ const z = -300 + Math.pow(i / 260, 1.7) * 14300;
64
+ return {x: trunkX(z), z};
65
+ });
66
+
67
+ // 三次贝塞尔按弧长等距重采样
68
+ const bez = (a: P3, b: P3, c: P3, d: P3, t: number): P3 => {
69
+ const u = 1 - t;
70
+ return {
71
+ x: u * u * u * a.x + 3 * u * u * t * b.x + 3 * u * t * t * c.x + t * t * t * d.x,
72
+ z: u * u * u * a.z + 3 * u * u * t * b.z + 3 * u * t * t * c.z + t * t * t * d.z,
73
+ };
74
+ };
75
+ const resample = (at: (t: number) => P3, n: number) => {
76
+ const raw = Array.from({length: 241}, (_, i) => at(i / 240));
77
+ const cum = [0];
78
+ for (let i = 1; i < raw.length; i++) cum.push(cum[i - 1] + Math.hypot(raw[i].x - raw[i - 1].x, raw[i].z - raw[i - 1].z));
79
+ const total = cum[cum.length - 1];
80
+ const out: P3[] = [];
81
+ let j = 1;
82
+ for (let k = 0; k <= n; k++) {
83
+ const target = (k / n) * total;
84
+ while (j < raw.length - 1 && cum[j] < target) j++;
85
+ const f = (target - cum[j - 1]) / Math.max(1e-6, cum[j] - cum[j - 1]);
86
+ out.push({x: mix(raw[j - 1].x, raw[j].x, f), z: mix(raw[j - 1].z, raw[j].z, f)});
87
+ }
88
+ return out;
89
+ };
90
+
91
+ // 支流:起点在两侧画外,切向汇入主干(汇入点切线 = 主干切线)
92
+ type TribSpec = {side: number; z0: number; off: number; zm: number; lm: number; grow: number; w: number};
93
+ const TRIB_SPECS: TribSpec[] = [
94
+ {side: -1, z0: -260, off: 700, zm: 1500, lm: 520, grow: 8, w: 5},
95
+ {side: 1, z0: -120, off: 900, zm: 2100, lm: 640, grow: 11, w: 5},
96
+ {side: -1, z0: 500, off: 1500, zm: 2700, lm: 760, grow: 16, w: 4.4},
97
+ {side: 1, z0: 800, off: 1800, zm: 3300, lm: 820, grow: 20, w: 4.4},
98
+ {side: -1, z0: 1400, off: 2300, zm: 3900, lm: 900, grow: 25, w: 4.2},
99
+ {side: 1, z0: 1700, off: 2500, zm: 4600, lm: 980, grow: 29, w: 4.2},
100
+ {side: -1, z0: 2500, off: 2900, zm: 5300, lm: 1050, grow: 34, w: 4.2},
101
+ {side: 1, z0: 3100, off: 3200, zm: 6100, lm: 1150, grow: 38, w: 4.2},
102
+ {side: -1, z0: 4100, off: 3600, zm: 7100, lm: 1250, grow: 43, w: 4.2},
103
+ {side: 1, z0: 5000, off: 3900, zm: 8200, lm: 1350, grow: 47, w: 4.2},
104
+ {side: 1, z0: -420, off: 260, zm: 980, lm: 380, grow: 4, w: 6}, // 贴着镜头右下方掠过的近景支流(大虚焦)
105
+ ];
106
+ const TRIBS = TRIB_SPECS.map((s) => {
107
+ const end: P3 = {x: trunkX(s.zm), z: s.zm};
108
+ const dx = trunkDX(s.zm);
109
+ const dl = Math.hypot(dx, 1);
110
+ const p2: P3 = {x: end.x - (dx / dl) * s.lm, z: end.z - (1 / dl) * s.lm};
111
+ const p0: P3 = {x: trunkX(s.z0) + s.side * s.off, z: s.z0};
112
+ const p1: P3 = {x: p0.x + (end.x - p0.x) * 0.12, z: p0.z + (end.z - p0.z) * 0.5};
113
+ return {...s, pts: resample((t) => bez(p0, p1, p2, end, t), 90)};
114
+ });
115
+
116
+ // ───────────── 线段渲染:按深度分层(近虚 / 中实 / 远雾)─────────────
117
+ const smooth01 = (a: number, b: number, x: number) => {
118
+ const t = Math.min(1, Math.max(0, (x - a) / (b - a)));
119
+ return t * t * (3 - 2 * t);
120
+ };
121
+ type Seg = {x1: number; y1: number; x2: number; y2: number; w: number; o: number; c: string};
122
+
123
+ const emitLine = (
124
+ pts: P3[], g: number, cam: {x: number; z: number}, opts: {w: number; color: string; base: number; ramp?: boolean; pulse: (u: number) => number},
125
+ sharp: Seg[], near: Seg[],
126
+ ) => {
127
+ const n = pts.length - 1;
128
+ const reach = g * n;
129
+ const kMax = Math.min(n, Math.ceil(reach));
130
+ for (let k = 0; k < kMax; k++) {
131
+ const a = pts[k];
132
+ const b0 = pts[k + 1];
133
+ const f = Math.min(1, reach - k);
134
+ const b = f < 1 ? {x: mix(a.x, b0.x, f), z: mix(a.z, b0.z, f)} : b0;
135
+ if (a.z - cam.z < 70 || b.z - cam.z < 70) continue;
136
+ const pa = project(a, cam);
137
+ const pb = project(b, cam);
138
+ if ((pa.sx < -200 && pb.sx < -200) || (pa.sx > 2120 && pb.sx > 2120) || (pa.sy > 1300 && pb.sy > 1300)) continue;
139
+ const zr = (pa.zr + pb.zr) / 2;
140
+ const u = (k + 0.5 * f) / n;
141
+ const fog = 1 - smooth01(2600, 11000, zr); // 远处雾化
142
+ const lift = opts.ramp ? 0.3 + 0.7 * Math.pow(u, 0.8) : 1; // 支流:源头淡、汇入处亮
143
+ // 脉冲只在中远景显形:近处一段线在屏幕上很长,逐段明暗会读成台阶
144
+ const pv = opts.pulse(u);
145
+ const o = opts.base * fog * lift * mix(1, pv, smooth01(500, 1400, zr));
146
+ if (o < 0.01) continue;
147
+ const w = Math.max(0.9, Math.min(46, (opts.w * F) / zr));
148
+ const nearW = 1 - smooth01(420, 1050, zr); // 近景权重 → 进模糊层
149
+ const seg = {x1: pa.sx, y1: pa.sy, x2: pb.sx, y2: pb.sy, w, c: opts.color};
150
+ if (nearW < 0.98) sharp.push({...seg, o: o * (1 - nearW)});
151
+ if (nearW > 0.02) near.push({...seg, w: w * 1.3, o: o * nearW * 0.7});
152
+ }
153
+ // 笔尖
154
+ if (g > 0 && g < 1) {
155
+ const k = Math.min(n - 1, Math.floor(reach));
156
+ const f = reach - k;
157
+ const tip = {x: mix(pts[k].x, pts[k + 1].x, f), z: mix(pts[k].z, pts[k + 1].z, f)};
158
+ if (tip.z - cam.z > 70) return project(tip, cam);
159
+ }
160
+ return null;
161
+ };
162
+
163
+ // ───────────── 标签(中景,video-shotcraft 的镜头号 + 运镜名;字数与原 issue 标签相当,投影位置不变)─────────────
164
+ // 位置按投影逐帧核过:起止两端都错开(不叠、不压汇点、不出画),近处一枚随前飞明显变大
165
+ type LabelSpec = {trib: number; u: number; id: string; note: string; appear: number};
166
+ const LABELS: LabelSpec[] = [
167
+ {trib: 2, u: 0.6, id: 'SHOT-01', note: 'dolly in', appear: 44},
168
+ {trib: 1, u: 0.75, id: 'SHOT-02', note: 'crash zoom', appear: 53},
169
+ {trib: 3, u: 0.6, id: 'SHOT-03', note: 'whip pan', appear: 62},
170
+ {trib: 6, u: 0.3, id: 'SHOT-04', note: 'beat cut', appear: 73},
171
+ {trib: 7, u: 0.45, id: 'SHOT-05', note: 'tilt up', appear: 84},
172
+ {trib: 8, u: 0.45, id: 'SHOT-06', note: 'lockup', appear: 96},
173
+ ];
174
+ const LABEL_PTS = LABELS.map((l) => {
175
+ const pts = TRIBS[l.trib].pts;
176
+ return {p: pts[Math.round(l.u * (pts.length - 1))]};
177
+ });
178
+
179
+ const Label: React.FC<{spec: LabelSpec; at: P3; frame: number; cam: {x: number; z: number}}> = ({spec, at, frame, cam}) => {
180
+ const pr = project(at, cam);
181
+ if (pr.zr < 200) return null;
182
+ const k = Math.min(1.7, Math.max(0.7, 1500 / pr.zr)); // 透视缩放(近大远小),钳住可读区间
183
+ const fog = 1 - smooth01(3600, 8000, pr.zr);
184
+ const pin = ramp(frame, spec.appear, 10, EASE.overshoot);
185
+ const pinOp = ramp(frame, spec.appear, 4, EASE.out);
186
+ const stem = ramp(frame, spec.appear + 2, 12, EASE.snappy);
187
+ const tag = ramp(frame, spec.appear + 6, 14, EASE.snappy);
188
+ // 立杆世界高度远低于相机高度 → 标签落在地平线以下、按深度上下错开(杆高≈相机高时所有标签都投影到地平线上挤成一排)
189
+ const stemH = 44 * k;
190
+ const fs = 25 * k;
191
+ return (
192
+ <div style={{position: 'absolute', left: 0, top: 0, opacity: fog}}>
193
+ {/* 图钉(落在线上) */}
194
+ <div style={{
195
+ position: 'absolute', left: pr.sx - 6 * k, top: pr.sy - 6 * k, width: 12 * k, height: 12 * k, borderRadius: 2.5 * k,
196
+ background: L.accent, opacity: pinOp, transform: `scale(${pin})`,
197
+ boxShadow: `0 0 0 ${3 * k}px ${alpha(L.bg[2], 0.9)}, 0 0 ${18 * k}px ${alpha(L.accent, 0.7)}`,
198
+ }} />
199
+ {/* 立杆 */}
200
+ <div style={{
201
+ position: 'absolute', left: pr.sx - 0.75, top: pr.sy - 8 * k - stemH * stem, width: 1.5, height: stemH * stem,
202
+ background: `linear-gradient(0deg, ${alpha(L.accent, 0.7)}, ${alpha(L.ink, 0.25)})`,
203
+ }} />
204
+ {/* ID 胶囊 */}
205
+ <div style={{
206
+ position: 'absolute', left: pr.sx - 2 * k, top: pr.sy - 8 * k - stemH - 46 * k + (1 - tag) * 14 * k,
207
+ height: 46 * k, padding: `0 ${14 * k}px 0 ${12 * k}px`, borderRadius: 10 * k, boxSizing: 'border-box',
208
+ display: 'flex', alignItems: 'center', gap: 10 * k, whiteSpace: 'nowrap',
209
+ background: alpha('#141711', 0.82), border: `1px solid ${alpha(L.ink, 0.12)}`,
210
+ boxShadow: `inset 0 1px 0 ${alpha('#ffffff', 0.06)}, 0 ${10 * k}px ${28 * k}px ${alpha('#000000', 0.5)}`,
211
+ opacity: tag, filter: tag < 0.98 ? `blur(${((1 - tag) * 6).toFixed(2)}px)` : undefined,
212
+ }}>
213
+ <div style={{width: 7 * k, height: 7 * k, borderRadius: 4 * k, background: L.accent}} />
214
+ <span style={{fontFamily: FONT.mono, fontSize: fs, fontWeight: 600, color: L.ink, letterSpacing: '0.02em'}}>{spec.id}</span>
215
+ <span style={{fontFamily: FONT.sans, fontSize: fs * 0.82, fontWeight: 500, color: L.ink3}}>{spec.note}</span>
216
+ </div>
217
+ </div>
218
+ );
219
+ };
220
+
221
+ // ───────────── 组件 ─────────────
222
+ export const DatavizLandscapeOpen: React.FC = () => {
223
+ const frame = useCurrentFrame();
224
+ const cam = camAt(frame);
225
+ const fadeUp = ramp(frame, 0, 12, EASE.out);
226
+
227
+ const sharp: Seg[] = [];
228
+ const near: Seg[] = [];
229
+ const tips: {sx: number; sy: number; zr: number; trunk: boolean}[] = [];
230
+
231
+ // 流动脉冲:生长完后沿线流向汇点的亮脉冲(窄峰,低速)
232
+ const flowIn = (end: number) => ramp(frame, end, 24, EASE.smooth);
233
+ const pulseFn = (end: number, n: number, speed: number, seed: number) => {
234
+ const on = flowIn(end);
235
+ return (u: number) => {
236
+ const ph = u * n - frame * speed + seed;
237
+ const c = Math.cos(ph * Math.PI * 2);
238
+ return 0.7 + on * 0.55 * Math.pow(Math.max(0, c), 4);
239
+ };
240
+ };
241
+
242
+ const trunkG = ramp(frame, 0, 36, EASE.out);
243
+ TRIBS.forEach((t, i) => {
244
+ const g = ramp(frame, t.grow, 34, EASE.out);
245
+ const tip = emitLine(t.pts, g, cam, {w: t.w, color: L.ink2, base: 0.62, ramp: true, pulse: pulseFn(t.grow + 34, 2.2, 0.018, i * 0.37)}, sharp, near);
246
+ if (tip) tips.push({...tip, trunk: false});
247
+ });
248
+ const tTip = emitLine(TRUNK, trunkG, cam, {w: 11, color: L.accent, base: 0.95, pulse: pulseFn(36, 4, 0.022, 0)}, sharp, near);
249
+ if (tTip) tips.push({...tTip, trunk: true});
250
+ const trunkSegs = sharp.filter((s) => s.c === L.accent);
251
+
252
+ // 地面点阵:与世界锁定的网格,前飞时从远处涌来
253
+ const dots: {x: number; y: number; r: number; o: number}[] = [];
254
+ const STEP = 420;
255
+ const zStart = Math.ceil((cam.z + 300) / STEP) * STEP;
256
+ for (let z = zStart; z < cam.z + 9000; z += STEP) {
257
+ for (let x = Math.floor((cam.x - 5200) / STEP) * STEP; x < cam.x + 5200; x += STEP) {
258
+ const pr = project({x, z}, cam);
259
+ if (pr.sx < -20 || pr.sx > 1940 || pr.sy > 1100) continue;
260
+ const o = 0.28 * (1 - smooth01(2000, 9000, pr.zr)) * smooth01(300, 900, pr.zr);
261
+ if (o < 0.01) continue;
262
+ dots.push({x: pr.sx, y: pr.sy, r: Math.max(0.8, Math.min(3.2, 2400 / pr.zr)), o});
263
+ }
264
+ }
265
+
266
+ const handoff = ramp(frame, 118, 50, EASE.swift);
267
+ const lineRender = (s: Seg, i: number) => (
268
+ <line key={i} x1={s.x1} y1={s.y1} x2={s.x2} y2={s.y2} stroke={s.c} strokeWidth={s.w} strokeOpacity={s.o} strokeLinecap="butt" />
269
+ );
270
+
271
+ return (
272
+ <AbsoluteFill style={{background: L.bg[2], overflow: 'hidden'}}>
273
+ <AbsoluteFill style={{opacity: 0.35 + 0.65 * fadeUp}}>
274
+ <Stage look={L} keyLight={{x: VPX / 1920, y: HY / 1080}} fill={{x: 0.12, y: 0.95}} horizon={HY / 1080} intensity={0.55} grain={0.1} vignette={0.6}>
275
+ {/* 天空里的极淡浮尘 */}
276
+ <div style={{position: 'absolute', left: 0, right: 0, top: 0, height: HY, overflow: 'hidden'}}>
277
+ <Dust look={L} count={26} seed={7} drift={0.12} opacity={0.35} color={L.ink2} />
278
+ </div>
279
+ {/* 地面:地平线以下略亮一档的冷灰绿,向近处压暗 */}
280
+ <div style={{
281
+ position: 'absolute', left: 0, right: 0, top: HY, bottom: 0,
282
+ background: `linear-gradient(180deg, ${alpha('#2a3122', 0.55)} 0%, ${alpha('#141811', 0.3)} 30%, ${alpha('#050604', 0)} 100%)`,
283
+ }} />
284
+ {/* 地平线发丝线 */}
285
+ <div style={{
286
+ position: 'absolute', left: 0, right: 0, top: HY - 0.5, height: 1,
287
+ background: `linear-gradient(90deg, ${alpha(L.ink, 0)} 0%, ${alpha(L.ink, 0.16)} 40%, ${alpha(L.accent, 0.35)} 66%, ${alpha(L.ink, 0.12)} 85%, ${alpha(L.ink, 0)} 100%)`,
288
+ }} />
289
+ </Stage>
290
+
291
+ <svg width={1920} height={1080} style={{position: 'absolute', inset: 0}}>
292
+ <defs>
293
+ <filter id="dv-near" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="11" /></filter>
294
+ <filter id="dv-glow" x="-10%" y="-10%" width="120%" height="120%"><feGaussianBlur stdDeviation="7" /></filter>
295
+ <radialGradient id="dv-tip">
296
+ <stop offset="0" stopColor="#ffffff" stopOpacity={0.9} />
297
+ <stop offset="0.3" stopColor={L.accent} stopOpacity={0.35} />
298
+ <stop offset="1" stopColor={L.accent} stopOpacity={0} />
299
+ </radialGradient>
300
+ </defs>
301
+ {dots.map((d, i) => <circle key={i} cx={d.x} cy={d.y} r={d.r} fill={L.ink2} fillOpacity={d.o} />)}
302
+ {/* 主干泛光(只给主角) */}
303
+ <g filter="url(#dv-glow)" opacity={0.75}>
304
+ {trunkSegs.map((s, i) => <line key={i} x1={s.x1} y1={s.y1} x2={s.x2} y2={s.y2} stroke={L.accent} strokeWidth={s.w * 3} strokeOpacity={s.o * 0.45} strokeLinecap="butt" />)}
305
+ </g>
306
+ {sharp.map(lineRender)}
307
+ {tips.map((t, i) => {
308
+ const r = Math.max(3, Math.min(18, (t.trunk ? 7000 : 4200) / t.zr));
309
+ return (
310
+ <g key={i}>
311
+ <circle cx={t.sx} cy={t.sy} r={r * 5} fill="url(#dv-tip)" />
312
+ <circle cx={t.sx} cy={t.sy} r={r * 0.6} fill="#ffffff" />
313
+ </g>
314
+ );
315
+ })}
316
+ </svg>
317
+
318
+ {/* 汇点交棒亮部:消失点一团黄绿光,收尾升亮 */}
319
+ <div style={{
320
+ position: 'absolute', left: VPX - 520, top: HY - 260, width: 1040, height: 520, pointerEvents: 'none',
321
+ background: `radial-gradient(50% 50% at 50% 50%, ${alpha('#f4ffd6', 0.55)} 0%, ${alpha(L.accent, 0.22)} 22%, ${alpha(L.accent, 0)} 70%)`,
322
+ opacity: 0.25 + 0.75 * handoff, mixBlendMode: 'screen',
323
+ }} />
324
+ <div style={{
325
+ position: 'absolute', left: VPX - 4, top: HY - 4, width: 8, height: 8, borderRadius: 4, background: '#f6ffe0',
326
+ boxShadow: `0 0 18px 6px ${alpha(L.accent, 0.6)}`, opacity: 0.4 + 0.6 * handoff,
327
+ }} />
328
+
329
+ {/* 远的先画、近的后画:近处胶囊正确遮住远处图钉 */}
330
+ {LABELS.map((l, i) => ({l, p: LABEL_PTS[i].p}))
331
+ .sort((a, b) => b.p.z - a.p.z)
332
+ .map(({l, p}) => (frame >= l.appear ? <Label key={l.id} spec={l} at={p} frame={frame} cam={cam} /> : null))}
333
+
334
+ {/* 近景大虚焦层(在标签之上:前景掠过) */}
335
+ <svg width={1920} height={1080} style={{position: 'absolute', inset: 0}}>
336
+ <g filter="url(#dv-near)">{near.map(lineRender)}</g>
337
+ </svg>
338
+ </AbsoluteFill>
339
+
340
+ {/* 标题:天空左上,收尾落字 */}
341
+ <div style={{position: 'absolute', left: 120, top: 128}}>
342
+ {/* 眉题:品牌名按字标规范全小写(不走大写科技字标) */}
343
+ <div style={{
344
+ fontFamily: FONT.mono, fontSize: 28, fontWeight: 600, color: L.accent, letterSpacing: '0.12em',
345
+ opacity: ramp(frame, 104, 14, EASE.out), transform: `translateY(${(1 - ramp(frame, 104, 18, EASE.snappy)) * 12}px)`,
346
+ }}>
347
+ {BRAND.name} · shot recipes
348
+ </div>
349
+ <div style={{...type(108, 650), color: L.ink, marginTop: 26}}>
350
+ <TextReveal text="Every shot," by="word" variant="rise" start={110} each={20} gap={5} />
351
+ </div>
352
+ <div style={{...type(108, 650), color: L.accent, marginTop: 4}}>
353
+ <TextReveal text="one film." by="word" variant="rise" start={121} each={20} gap={5} />
354
+ </div>
355
+ </div>
356
+ </AbsoluteFill>
357
+ );
358
+ };