dsh-drawai 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/README.md +96 -253
  2. package/lib/client.js +28 -7
  3. package/lib/index.js +474 -97
  4. package/lib/motion/asset-pack.js +109 -50
  5. package/lib/motion/assets.js +291 -291
  6. package/lib/motion/demo-assets-lock.js +10 -0
  7. package/lib/motion/mgstyles/vendor/README.md +28 -0
  8. package/lib/motion/mgstyles/vendor/modules/d3/LICENSE +13 -0
  9. package/lib/motion/mgstyles/vendor/modules/d3/dist/d3.min.js +2 -0
  10. package/lib/motion/mgstyles/vendor/modules/opentype.js/LICENSE +20 -0
  11. package/lib/motion/mgstyles/vendor/modules/opentype.js/dist/opentype.mjs +14460 -0
  12. package/lib/motion/mgstyles/vendor/modules/simplex-noise/LICENSE +21 -0
  13. package/lib/motion/mgstyles/vendor/modules/simplex-noise/dist/esm/simplex-noise.js +466 -0
  14. package/lib/motion/mgstyles/vendor/modules/topojson-client/LICENSE +13 -0
  15. package/lib/motion/mgstyles/vendor/modules/topojson-client/dist/topojson-client.min.js +2 -0
  16. package/lib/motion/preview.js +10 -3
  17. package/lib/motion/render.js +19 -1
  18. package/lib/motion/shotcraft/upstream/SKILL.md +286 -286
  19. package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -54
  20. package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -200
  21. package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -45
  22. package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -20
  23. package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -65
  24. package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -151
  25. package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -129
  26. package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -75
  27. package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -40
  28. package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -11
  29. package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -10
  30. package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -49
  31. package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -210
  32. package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -423
  33. package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -170
  34. package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -157
  35. package/lib/motion/shotcraft/upstream/demos/README.md +120 -120
  36. package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -112
  37. package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -647
  38. package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -316
  39. package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -82
  40. package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -115
  41. package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -243
  42. package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +388 -388
  43. package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -250
  44. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -305
  45. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -246
  46. package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -390
  47. package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -138
  48. package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -542
  49. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -315
  50. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -299
  51. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -173
  52. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -348
  53. package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -366
  54. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -279
  55. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -184
  56. package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -390
  57. package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -155
  58. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -303
  59. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -290
  60. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -278
  61. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -307
  62. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -215
  63. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -299
  64. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -232
  65. package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -290
  66. package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -273
  67. package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -167
  68. package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -536
  69. package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -164
  70. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -175
  71. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -197
  72. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -241
  73. package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -279
  74. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -230
  75. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -345
  76. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -275
  77. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -229
  78. package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -312
  79. package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -222
  80. package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -295
  81. package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -329
  82. package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -315
  83. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -264
  84. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -260
  85. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -263
  86. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -123
  87. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -187
  88. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -175
  89. package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -305
  90. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -350
  91. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -352
  92. package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -218
  93. package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -297
  94. package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -157
  95. package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -218
  96. package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -202
  97. package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -265
  98. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -457
  99. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -446
  100. package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -249
  101. package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -278
  102. package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -332
  103. package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -358
  104. package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -201
  105. package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -200
  106. package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -208
  107. package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -341
  108. package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -389
  109. package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -293
  110. package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -183
  111. package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -245
  112. package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -222
  113. package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -223
  114. package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -217
  115. package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -343
  116. package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -357
  117. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -187
  118. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -333
  119. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -274
  120. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -270
  121. package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -430
  122. package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -252
  123. package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -106
  124. package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -288
  125. package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -362
  126. package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -168
  127. package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -310
  128. package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -261
  129. package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -459
  130. package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -294
  131. package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -161
  132. package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -248
  133. package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -359
  134. package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -227
  135. package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -162
  136. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -248
  137. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -186
  138. package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -355
  139. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -272
  140. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -262
  141. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -217
  142. package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -285
  143. package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -205
  144. package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -178
  145. package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -147
  146. package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -143
  147. package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -134
  148. package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -217
  149. package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -198
  150. package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -221
  151. package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -312
  152. package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -261
  153. package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -121
  154. package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -153
  155. package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -179
  156. package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -140
  157. package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -309
  158. package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -191
  159. package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -292
  160. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -135
  161. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -124
  162. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -255
  163. package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -173
  164. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -225
  165. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -141
  166. package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -137
  167. package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -147
  168. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -409
  169. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -280
  170. package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -271
  171. package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -385
  172. package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -312
  173. package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -303
  174. package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -77
  175. package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -311
  176. package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -307
  177. package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -349
  178. package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -255
  179. package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -244
  180. package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -217
  181. package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -652
  182. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -153
  183. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -238
  184. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -324
  185. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -354
  186. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -101
  187. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -129
  188. package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -297
  189. package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -57
  190. package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -155
  191. package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -175
  192. package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -153
  193. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -146
  194. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -226
  195. package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -1
  196. package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -193
  197. package/lib/motion/shotcraft/upstream/references/final-review.md +121 -121
  198. package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -199
  199. package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -183
  200. package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -257
  201. package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -382
  202. package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -111
  203. package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -50
  204. package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -95
  205. package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -41
  206. package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -52
  207. package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -39
  208. package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -39
  209. package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -57
  210. package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -51
  211. package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -46
  212. package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -52
  213. package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -43
  214. package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -42
  215. package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -48
  216. package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -52
  217. package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -45
  218. package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -46
  219. package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -44
  220. package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -63
  221. package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -54
  222. package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -58
  223. package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -35
  224. package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -53
  225. package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -42
  226. package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -50
  227. package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -46
  228. package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -56
  229. package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -49
  230. package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -50
  231. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -53
  232. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -53
  233. package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -55
  234. package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -52
  235. package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -60
  236. package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -57
  237. package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -51
  238. package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -41
  239. package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -53
  240. package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -60
  241. package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -55
  242. package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -57
  243. package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -47
  244. package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -37
  245. package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -54
  246. package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -36
  247. package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -56
  248. package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -56
  249. package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -40
  250. package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -60
  251. package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -57
  252. package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -73
  253. package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -87
  254. package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -55
  255. package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -50
  256. package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -59
  257. package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -38
  258. package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -38
  259. package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -59
  260. package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -39
  261. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -61
  262. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -52
  263. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -50
  264. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -66
  265. package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -43
  266. package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -38
  267. package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -38
  268. package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -56
  269. package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -44
  270. package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -38
  271. package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -63
  272. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -57
  273. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -63
  274. package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -58
  275. package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -45
  276. package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -55
  277. package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -49
  278. package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -42
  279. package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -42
  280. package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -45
  281. package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -48
  282. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -55
  283. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -43
  284. package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -41
  285. package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -42
  286. package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -59
  287. package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -55
  288. package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -65
  289. package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -42
  290. package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -64
  291. package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -64
  292. package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -54
  293. package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -91
  294. package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -51
  295. package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -66
  296. package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -38
  297. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -66
  298. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -58
  299. package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -61
  300. package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -64
  301. package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -45
  302. package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -41
  303. package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -51
  304. package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -42
  305. package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -63
  306. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -57
  307. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -75
  308. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -59
  309. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -67
  310. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -60
  311. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -66
  312. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -40
  313. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -45
  314. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -62
  315. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -55
  316. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -37
  317. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -55
  318. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -50
  319. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -43
  320. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -55
  321. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -51
  322. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -51
  323. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -56
  324. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -49
  325. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -57
  326. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -36
  327. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -64
  328. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -47
  329. package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -170
  330. package/lib/motion/shotcraft/upstream/references/workbench.md +157 -157
  331. package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -103
  332. package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -44
  333. package/lib/motion/shotcraft/upstream/template/package.json +20 -20
  334. package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -6
  335. package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -17
  336. package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -65
  337. package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -48
  338. package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -24
  339. package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -192
  340. package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -111
  341. package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -150
  342. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -158
  343. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -468
  344. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -552
  345. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -411
  346. package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -200
  347. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -324
  348. package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +388 -388
  349. package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -4
  350. package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -7
  351. package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -68
  352. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -1
  353. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -24
  354. package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -74
  355. package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -91
  356. package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -213
  357. package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -15
  358. package/lib/motion/style-frames.js +47 -12
  359. package/lib/motion-project.js +22 -3
  360. package/lib/motion-render-worker.js +31 -9
  361. package/lib/routing/router.js +12 -1
  362. package/lib/style-kernel.js +16 -6
  363. package/lib/video-trace-pool.js +128 -128
  364. package/package.json +1 -1
  365. package/LICENSE +0 -4175
@@ -1,305 +1,305 @@
1
- // autolayout-gap-dial —— framer-ai 4.5–5.5s
2
- // 间距拨盘驱动布局:一个 gap 数值同帧驱动整排导航块的位置、测量线、徽章与读数。
3
- //
4
- // 第二轮重设计(石墨暗场 · 设计工具检查器海报):
5
- // - look = graphite(近单色暗场)。设计工具的"选择白 + 测量金"两色语义:框选描边/手柄用近白,
6
- // 间距测量线/徽章/拨盘指针用 accent2 香槟金——画面里只有"被拨动的那个数"是有颜色的。
7
- // - 主角是"数":顶部 196px 超大 tabular 读数(GAP 眉题 + 数值 + px 单位),下面一把 760px 拨盘刻度尺,
8
- // 刻度随 gap 横向滚过中心金针;拨动时读数由白转金、松手后回白——数值就是缰绳。
9
- // - 布局主体:一排 120px 高的导航块(video-shotcraft 站点的顶部导航),占画宽 ~64–86%;激活项白底黑字,
10
- // 其余是带色相深灰面板 + 发丝线 + 顶部内高光;块按自身速度做横向运动模糊(外侧块位移最大,拖影最长)。
11
- // - 节奏「预备—拉开—屏息—回弹」:开场先把 gap 往里收一点(anticip 预备,12→6),再 swift 不对称曲线
12
- // 拉到 104;hold 一拍屏息;松手后欠阻尼弹簧过冲到比起点更紧再回稳(过冲段 ×0.45 压缩,gap 永不为负)。
13
- //
14
- // 时间表(30fps,共 150f):
15
- // 0–20 入场:舞台光 + 点阵画布;导航块错峰上浮(父先到)、框选描边从外侧收拢、8 手柄 2f 错峰弹出
16
- // 6–22 读数入场:眉题字距收拢、数值从线下升起、刻度尺淡入
17
- // 22–32 预备:gap 12→6(anticip,观众先看到"往回收"再看到"冲出去")
18
- // 32–66 主动作:gap 6→104(34f swift),读数逐 2 跳、转金;测量线与徽章实时拉长
19
- // 66–86 屏息 hold 20f:相机极缓推近(总 +2.5%),金色读数停在 104
20
- // 86–118 回弹:spring(damping 9, stiffness 80) 104→~7→12,~118f 落定,读数回白
21
- // 118–150 落定 hold:完整海报(读数 12 + 收紧的导航条),相机继续极缓推进
22
- import React from 'react';
23
- import { AbsoluteFill, useCurrentFrame, spring } from 'remotion';
24
- import { EASE, FONT, ramp, softShadow } from '../../_fixtures/Polish';
25
- import { LOOKS, Stage, alpha, springAt, type } from '../../_fixtures/Look';
26
-
27
- export const AUTOLAYOUT_GAP_DIAL_DURATION = 150;
28
-
29
- const L = LOOKS.graphite;
30
- const FPS = 30;
31
- const SEL = 'rgba(244,244,242,0.92)'; // 选择白:框选描边 / 手柄
32
- const GOLD = L.accent2; // 测量金:间距线 / 徽章 / 指针 / 拨动中的读数
33
-
34
- const LABELS = ['Recipes', 'Gallery', 'Workbench', 'Showcase', 'Install']; // video-shotcraft 站点导航
35
- const BLOCK_WIDTHS = [252, 206, 278, 268, 220]; // 不等宽才像真导航
36
- const BLOCK_H = 120;
37
- const ROW_Y = 684; // 行中心
38
- const G_REST = 12;
39
- const G_PRE = 6; // 预备回收值
40
- const G_MAX = 104;
41
-
42
- const PRE_START = 22;
43
- const PRE_END = 32;
44
- const GROW_END = 66;
45
- const HOLD_END = 86;
46
- // damping 9 的原始过冲 ≈18%×106px 会把 gap 拉成负数;过冲段 ×0.45 → 最紧约 6px,仍"比起点更紧再回稳"
47
- const OVERSHOOT_K = 0.45;
48
-
49
- // 同一个 gap 参数派生全部几何(块位置、测量线、徽章、读数、刻度尺)
50
- const gapAt = (f: number) => {
51
- if (f < PRE_END) return G_REST + (G_PRE - G_REST) * ramp(f, PRE_START, PRE_END - PRE_START, EASE.swift);
52
- if (f < HOLD_END) return G_PRE + (G_MAX - G_PRE) * ramp(f, PRE_END, GROW_END - PRE_END, EASE.swift);
53
- const s = spring({ frame: f - HOLD_END, fps: FPS, config: { damping: 9, stiffness: 80, mass: 1.1 } });
54
- const s2 = s > 1 ? 1 + (s - 1) * OVERSHOOT_K : s;
55
- return G_MAX + (G_REST - G_MAX) * s2;
56
- };
57
-
58
- // 两个 hex 颜色按 t 混合
59
- const mixHex = (a: string, b: string, t: number) => {
60
- const pa = a.match(/[0-9a-f]{2}/gi)!.map((h) => parseInt(h, 16));
61
- const pb = b.match(/[0-9a-f]{2}/gi)!.map((h) => parseInt(h, 16));
62
- const k = Math.max(0, Math.min(1, t));
63
- return `rgb(${pa.slice(0, 3).map((x, i) => Math.round(x + (pb[i] - x) * k)).join(',')})`;
64
- };
65
-
66
- const rowLayout = (gap: number) => {
67
- const total = BLOCK_WIDTHS.reduce((a, b) => a + b, 0) + gap * (BLOCK_WIDTHS.length - 1);
68
- const startX = (1920 - total) / 2;
69
- const xs: number[] = [];
70
- let acc = startX;
71
- for (const w of BLOCK_WIDTHS) {
72
- xs.push(acc);
73
- acc += w + gap;
74
- }
75
- return { total, startX, xs };
76
- };
77
-
78
- const IconAutoLayout: React.FC<{ c: string; size?: number }> = ({ c, size = 22 }) => (
79
- <svg width={size} height={size} viewBox="0 0 14 14" fill="none">
80
- <rect x={1} y={3} width={3.4} height={8} rx={1} fill={c} />
81
- <rect x={5.3} y={3} width={3.4} height={8} rx={1} fill={c} opacity={0.7} />
82
- <rect x={9.6} y={3} width={3.4} height={8} rx={1} fill={c} opacity={0.45} />
83
- </svg>
84
- );
85
-
86
- // 拨盘刻度尺:每 1 单位 = UNIT px,中心金针读当前 gap
87
- const RULER_W = 760;
88
- const UNIT = 6.5;
89
- const Ruler: React.FC<{ gap: number; op: number; hot: number }> = ({ gap, op, hot }) => {
90
- const ticks: React.ReactNode[] = [];
91
- for (let u = -60; u <= 180; u += 2) {
92
- const x = RULER_W / 2 + (u - gap) * UNIT;
93
- if (x < -10 || x > RULER_W + 10) continue;
94
- const major = u % 10 === 0;
95
- const edge = Math.max(0, Math.min(1, Math.min(x, RULER_W - x) / 150)); // 两端淡出
96
- const near = Math.abs(x - RULER_W / 2);
97
- ticks.push(
98
- <div key={u} style={{
99
- position: 'absolute', left: x - 1, bottom: 0, width: 2, height: major ? 30 : 14, borderRadius: 1,
100
- background: u < 0 ? alpha(L.ink, 0.08) : major ? alpha(L.ink, 0.5) : alpha(L.ink, 0.22), opacity: edge,
101
- }} />,
102
- );
103
- if (major && u >= 0) {
104
- ticks.push(
105
- <div key={`l${u}`} style={{
106
- position: 'absolute', left: x, bottom: 40, transform: 'translateX(-50%)',
107
- ...type(22, 500, { mono: true }), color: L.ink3,
108
- opacity: edge * Math.min(1, Math.max(0, (near - 18) / 22)), // 靠近指针的数字让位
109
- }}>{u}</div>,
110
- );
111
- }
112
- }
113
- return (
114
- <div style={{ position: 'absolute', left: 960 - RULER_W / 2, top: 414, width: RULER_W, height: 76, opacity: op }}>
115
- <div style={{ position: 'absolute', inset: 0, overflow: 'hidden' }}>{ticks}</div>
116
- {/* 基线 */}
117
- <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 1, background: `linear-gradient(90deg, transparent, ${alpha(L.ink, 0.18)} 20%, ${alpha(L.ink, 0.18)} 80%, transparent)` }} />
118
- {/* 金针:拨动时泛光 */}
119
- <div style={{
120
- position: 'absolute', left: RULER_W / 2 - 1.5, bottom: -6, width: 3, height: 50, borderRadius: 2, background: GOLD,
121
- boxShadow: `0 0 ${8 + hot * 14}px ${alpha(GOLD, 0.35 + hot * 0.4)}`,
122
- }} />
123
- <div style={{
124
- position: 'absolute', left: RULER_W / 2 - 8, bottom: 44, width: 0, height: 0,
125
- borderLeft: '8px solid transparent', borderRight: '8px solid transparent', borderTop: `10px solid ${GOLD}`,
126
- }} />
127
- </div>
128
- );
129
- };
130
-
131
- export const AutolayoutGapDial: React.FC = () => {
132
- const frame = useCurrentFrame();
133
-
134
- const gap = gapAt(frame);
135
- const gapShown = Math.max(0, Math.round(gap / 2) * 2); // 逐格跳数(步进 2 = 拨盘咔哒的颗粒)
136
- const v = gapAt(frame + 0.5) - gapAt(frame - 0.5); // gap 速度(px/帧)
137
- const moving = Math.min(1, Math.abs(v) / 1.2);
138
- // 拨动热度:读数白→金,带 ~6f 余温(松手回稳后慢慢褪回白)
139
- let hot = 0;
140
- for (let k = 0; k <= 6; k++) hot = Math.max(hot, Math.min(1, Math.abs(gapAt(frame - k + 0.5) - gapAt(frame - k - 0.5)) / 1.5) * (1 - k / 7));
141
- // 跳数脉冲:相位由数值本身驱动(每跨一个步进格脉冲一次)× 速度门限
142
- const tickPulse = 1 + 0.06 * Math.abs(Math.sin((Math.PI * gap) / 2)) * moving;
143
-
144
- const { total, startX, xs } = rowLayout(gap);
145
-
146
- // 相机:整段极缓推近(smooth,起止无速度突变)
147
- const cam = 1 + 0.025 * ramp(frame, 0, AUTOLAYOUT_GAP_DIAL_DURATION, EASE.smooth);
148
-
149
- // 框选描边:spring 从外侧 26px 收拢
150
- const selIn = springAt(frame, 4, { damping: 16, stiffness: 140 });
151
- const pad = 30;
152
- const grow = (1 - selIn) * 26;
153
- const selX = startX - pad - grow;
154
- const selW = total + pad * 2 + grow * 2;
155
- const selY = ROW_Y - BLOCK_H / 2 - pad - grow;
156
- const selH = BLOCK_H + pad * 2 + grow * 2;
157
-
158
- const measOp = ramp(frame, 14, 10, EASE.out);
159
- const eyebrow = ramp(frame, 4, 18, EASE.snappy);
160
- const numIn = ramp(frame, 8, 18, EASE.snappy);
161
- const rulerIn = ramp(frame, 12, 16, EASE.out);
162
-
163
- // 读数颜色:白 ↔ 金
164
- const numColor = mixHex(L.ink, GOLD, hot);
165
-
166
- return (
167
- <AbsoluteFill style={{ background: L.bg[1], overflow: 'hidden', fontFamily: FONT.sans }}>
168
- <Stage look={L} keyLight={{ x: 0.5, y: 0.0 }} fill={{ x: 0.5, y: 1.05 }} horizon={0.62} breathe={0.4}>
169
- {/* 画布点阵:围绕导航条清楚、四周隐去 */}
170
- <AbsoluteFill style={{
171
- backgroundImage: `radial-gradient(${alpha(L.ink, 0.13)} 1.4px, transparent 1.7px)`,
172
- backgroundSize: '36px 36px', backgroundPosition: '6px 16px',
173
- WebkitMaskImage: 'radial-gradient(ellipse 52% 40% at 50% 62%, #000 20%, transparent 100%)',
174
- maskImage: 'radial-gradient(ellipse 52% 40% at 50% 62%, #000 20%, transparent 100%)',
175
- }} />
176
- {/* 导航条落脚的光池:条子"站"在画布上 */}
177
- <div style={{
178
- position: 'absolute', left: 260, right: 260, top: ROW_Y + 40, height: 200,
179
- background: `radial-gradient(ellipse 50% 50% at 50% 30%, ${alpha(L.light, 0.1)} 0%, transparent 70%)`,
180
- }} />
181
- </Stage>
182
-
183
- <AbsoluteFill style={{ transform: `scale(${cam})`, transformOrigin: '50% 52%' }}>
184
- {/* ── 读数:眉题 + 超大数值 + 单位 ── */}
185
- <div style={{
186
- position: 'absolute', left: 0, right: 0, top: 150, display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 16,
187
- opacity: eyebrow, letterSpacing: `${(0.28 + (1 - eyebrow) * 0.4).toFixed(3)}em`,
188
- ...type(22, 600, { caps: true }), color: L.ink2,
189
- }}>
190
- <IconAutoLayout c={L.ink2} />
191
- <span style={{ letterSpacing: 'inherit' }}>Auto layout · Gap</span>
192
- </div>
193
- <div style={{
194
- position: 'absolute', left: 0, right: 0, top: 186, height: 220, overflow: 'hidden',
195
- display: 'flex', justifyContent: 'center', alignItems: 'flex-end',
196
- }}>
197
- <div style={{
198
- display: 'flex', alignItems: 'baseline', gap: 18,
199
- transform: `translateY(${((1 - numIn) * 105).toFixed(2)}%)`,
200
- }}>
201
- <span style={{
202
- ...type(196, 300), letterSpacing: '-0.05em', color: numColor, display: 'inline-block',
203
- minWidth: '1.9em', textAlign: 'right', transform: `scale(${tickPulse})`, transformOrigin: '100% 80%',
204
- textShadow: hot > 0.05 ? `0 0 ${(40 * hot).toFixed(1)}px ${alpha(GOLD, 0.35 * hot)}` : undefined,
205
- }}>{gapShown}</span>
206
- <span style={{ ...type(60, 500), color: L.ink3, width: '1.9em' }}>px</span>
207
- </div>
208
- </div>
209
- <Ruler gap={gap} op={rulerIn} hot={hot} />
210
-
211
- {/* ── 导航块(video-shotcraft 站点顶部导航) ── */}
212
- {BLOCK_WIDTHS.map((w, i) => {
213
- const inP = ramp(frame, 1 + i * 2, 16, EASE.snappy);
214
- const active = i === 0;
215
- const vx = (i - 2) * v; // 块速度 = (i−2)·dgap/dt:外侧块位移最大
216
- const blur = Math.min(9, Math.abs(vx) * 0.5);
217
- const fid = `nb${i}`;
218
- const dy = (1 - inP) * 34;
219
- return (
220
- <div key={i} style={{
221
- position: 'absolute', left: xs[i], top: ROW_Y - BLOCK_H / 2, width: w, height: BLOCK_H,
222
- opacity: inP, transform: `translateY(${dy.toFixed(2)}px)`,
223
- }}>
224
- {blur > 0.5 && (
225
- <svg width={0} height={0} style={{ position: 'absolute' }} aria-hidden>
226
- <filter id={fid} x="-20%" y="-10%" width="140%" height="120%" colorInterpolationFilters="sRGB">
227
- <feGaussianBlur stdDeviation={`${blur.toFixed(2)} 0`} />
228
- </filter>
229
- </svg>
230
- )}
231
- <div style={{
232
- position: 'absolute', inset: 0, boxSizing: 'border-box', borderRadius: 24,
233
- background: active ? 'linear-gradient(180deg, #fbfbf8, #e6e6e1)' : 'linear-gradient(180deg, #212327, #17181b)',
234
- border: active ? '1px solid rgba(255,255,255,0.7)' : `1px solid ${alpha('#ffffff', 0.09)}`,
235
- boxShadow: active
236
- ? `inset 0 1px 0 rgba(255,255,255,1), inset 0 -2px 0 rgba(0,0,0,0.08), ${softShadow(18, { color: '#000000', strength: 2.4 })}`
237
- : `inset 0 1px 0 ${alpha('#ffffff', 0.08)}, ${softShadow(12, { color: '#000000', strength: 2.4 })}`,
238
- display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 14,
239
- filter: blur > 0.5 ? `url(#${fid})` : undefined,
240
- }}>
241
- {active && <div style={{ width: 12, height: 12, borderRadius: 99, background: '#111214' }} />}
242
- <span style={{ ...type(36, active ? 650 : 520), color: active ? '#0d0e10' : alpha(L.ink, 0.86) }}>{LABELS[i]}</span>
243
- </div>
244
- </div>
245
- );
246
- })}
247
-
248
- {/* ── 框选描边 + 8 手柄 + 图层名 ── */}
249
- <div style={{
250
- position: 'absolute', left: selX, top: selY, width: selW, height: selH, boxSizing: 'border-box',
251
- border: `2px solid ${SEL}`, borderRadius: 6, opacity: Math.min(1, selIn * 1.4),
252
- }}>
253
- <div style={{
254
- position: 'absolute', left: -2, top: -50, display: 'flex', alignItems: 'center', gap: 10,
255
- ...type(26, 560), color: SEL, whiteSpace: 'nowrap',
256
- }}>
257
- <IconAutoLayout c={SEL} size={20} />
258
- Nav links
259
- <span style={{ ...type(22, 500, { mono: true }), color: L.ink3, marginLeft: 8 }}>
260
- {Math.round(total)} × {BLOCK_H}
261
- </span>
262
- </div>
263
- {[[0, 0], [0.5, 0], [1, 0], [0, 0.5], [1, 0.5], [0, 1], [0.5, 1], [1, 1]].map(([hx, hy], i) => {
264
- const hp = springAt(frame, 7 + i * 1.2, { damping: 13, stiffness: 240 });
265
- return (
266
- <div key={i} style={{
267
- position: 'absolute', left: `${hx * 100}%`, top: `${hy * 100}%`, width: 16, height: 16, marginLeft: -8, marginTop: -8,
268
- background: L.bg[1], border: `2px solid ${SEL}`, borderRadius: 3, boxSizing: 'border-box', transform: `scale(${hp})`,
269
- }} />
270
- );
271
- })}
272
- </div>
273
-
274
- {/* ── 间距标注:延长线 ×2 + 测量线 + 徽章(全部由 gap 实时重算) ── */}
275
- {xs.slice(0, -1).map((x, i) => {
276
- const gx = x + BLOCK_WIDTHS[i];
277
- const cy = ROW_Y + BLOCK_H / 2 + 74;
278
- const extTop = ROW_Y + BLOCK_H / 2 + 34;
279
- const span = Math.max(0, gap);
280
- const bp = ramp(frame, 14 + i * 2, 12, EASE.snappy);
281
- return (
282
- <div key={i} style={{ position: 'absolute', left: 0, top: 0, opacity: measOp }}>
283
- {[gx, gx + gap].map((lx, k) => (
284
- <div key={k} style={{
285
- position: 'absolute', left: lx - 0.75, top: extTop, width: 1.5, height: 58,
286
- backgroundImage: `linear-gradient(${GOLD} 55%, transparent 55%)`, backgroundSize: '1.5px 7px', opacity: 0.7,
287
- }} />
288
- ))}
289
- <div style={{ position: 'absolute', left: gx, top: cy - 1, width: span, height: 2, background: GOLD, boxShadow: `0 0 10px ${alpha(GOLD, 0.4)}` }} />
290
- <div style={{ position: 'absolute', left: gx - 1, top: cy - 8, width: 2, height: 16, background: GOLD }} />
291
- <div style={{ position: 'absolute', left: gx + gap - 1, top: cy - 8, width: 2, height: 16, background: GOLD }} />
292
- <div style={{
293
- position: 'absolute', left: gx + gap / 2, top: cy + 20,
294
- transform: `translateX(-50%) translateY(${((1 - bp) * 10).toFixed(1)}px) scale(${(tickPulse * (0.7 + 0.3 * bp)).toFixed(3)})`,
295
- opacity: bp, minWidth: 64, textAlign: 'center', boxSizing: 'border-box', padding: '6px 14px', borderRadius: 10,
296
- background: GOLD, color: L.onAccent, ...type(28, 700), lineHeight: 1.1,
297
- boxShadow: `inset 0 1px 0 rgba(255,255,255,0.45), 0 6px 18px -6px ${alpha(GOLD, 0.6)}`,
298
- }}>{gapShown}</div>
299
- </div>
300
- );
301
- })}
302
- </AbsoluteFill>
303
- </AbsoluteFill>
304
- );
305
- };
1
+ // autolayout-gap-dial —— framer-ai 4.5–5.5s
2
+ // 间距拨盘驱动布局:一个 gap 数值同帧驱动整排导航块的位置、测量线、徽章与读数。
3
+ //
4
+ // 第二轮重设计(石墨暗场 · 设计工具检查器海报):
5
+ // - look = graphite(近单色暗场)。设计工具的"选择白 + 测量金"两色语义:框选描边/手柄用近白,
6
+ // 间距测量线/徽章/拨盘指针用 accent2 香槟金——画面里只有"被拨动的那个数"是有颜色的。
7
+ // - 主角是"数":顶部 196px 超大 tabular 读数(GAP 眉题 + 数值 + px 单位),下面一把 760px 拨盘刻度尺,
8
+ // 刻度随 gap 横向滚过中心金针;拨动时读数由白转金、松手后回白——数值就是缰绳。
9
+ // - 布局主体:一排 120px 高的导航块(video-shotcraft 站点的顶部导航),占画宽 ~64–86%;激活项白底黑字,
10
+ // 其余是带色相深灰面板 + 发丝线 + 顶部内高光;块按自身速度做横向运动模糊(外侧块位移最大,拖影最长)。
11
+ // - 节奏「预备—拉开—屏息—回弹」:开场先把 gap 往里收一点(anticip 预备,12→6),再 swift 不对称曲线
12
+ // 拉到 104;hold 一拍屏息;松手后欠阻尼弹簧过冲到比起点更紧再回稳(过冲段 ×0.45 压缩,gap 永不为负)。
13
+ //
14
+ // 时间表(30fps,共 150f):
15
+ // 0–20 入场:舞台光 + 点阵画布;导航块错峰上浮(父先到)、框选描边从外侧收拢、8 手柄 2f 错峰弹出
16
+ // 6–22 读数入场:眉题字距收拢、数值从线下升起、刻度尺淡入
17
+ // 22–32 预备:gap 12→6(anticip,观众先看到"往回收"再看到"冲出去")
18
+ // 32–66 主动作:gap 6→104(34f swift),读数逐 2 跳、转金;测量线与徽章实时拉长
19
+ // 66–86 屏息 hold 20f:相机极缓推近(总 +2.5%),金色读数停在 104
20
+ // 86–118 回弹:spring(damping 9, stiffness 80) 104→~7→12,~118f 落定,读数回白
21
+ // 118–150 落定 hold:完整海报(读数 12 + 收紧的导航条),相机继续极缓推进
22
+ import React from 'react';
23
+ import { AbsoluteFill, useCurrentFrame, spring } from 'remotion';
24
+ import { EASE, FONT, ramp, softShadow } from '../../_fixtures/Polish';
25
+ import { LOOKS, Stage, alpha, springAt, type } from '../../_fixtures/Look';
26
+
27
+ export const AUTOLAYOUT_GAP_DIAL_DURATION = 150;
28
+
29
+ const L = LOOKS.graphite;
30
+ const FPS = 30;
31
+ const SEL = 'rgba(244,244,242,0.92)'; // 选择白:框选描边 / 手柄
32
+ const GOLD = L.accent2; // 测量金:间距线 / 徽章 / 指针 / 拨动中的读数
33
+
34
+ const LABELS = ['Recipes', 'Gallery', 'Workbench', 'Showcase', 'Install']; // video-shotcraft 站点导航
35
+ const BLOCK_WIDTHS = [252, 206, 278, 268, 220]; // 不等宽才像真导航
36
+ const BLOCK_H = 120;
37
+ const ROW_Y = 684; // 行中心
38
+ const G_REST = 12;
39
+ const G_PRE = 6; // 预备回收值
40
+ const G_MAX = 104;
41
+
42
+ const PRE_START = 22;
43
+ const PRE_END = 32;
44
+ const GROW_END = 66;
45
+ const HOLD_END = 86;
46
+ // damping 9 的原始过冲 ≈18%×106px 会把 gap 拉成负数;过冲段 ×0.45 → 最紧约 6px,仍"比起点更紧再回稳"
47
+ const OVERSHOOT_K = 0.45;
48
+
49
+ // 同一个 gap 参数派生全部几何(块位置、测量线、徽章、读数、刻度尺)
50
+ const gapAt = (f: number) => {
51
+ if (f < PRE_END) return G_REST + (G_PRE - G_REST) * ramp(f, PRE_START, PRE_END - PRE_START, EASE.swift);
52
+ if (f < HOLD_END) return G_PRE + (G_MAX - G_PRE) * ramp(f, PRE_END, GROW_END - PRE_END, EASE.swift);
53
+ const s = spring({ frame: f - HOLD_END, fps: FPS, config: { damping: 9, stiffness: 80, mass: 1.1 } });
54
+ const s2 = s > 1 ? 1 + (s - 1) * OVERSHOOT_K : s;
55
+ return G_MAX + (G_REST - G_MAX) * s2;
56
+ };
57
+
58
+ // 两个 hex 颜色按 t 混合
59
+ const mixHex = (a: string, b: string, t: number) => {
60
+ const pa = a.match(/[0-9a-f]{2}/gi)!.map((h) => parseInt(h, 16));
61
+ const pb = b.match(/[0-9a-f]{2}/gi)!.map((h) => parseInt(h, 16));
62
+ const k = Math.max(0, Math.min(1, t));
63
+ return `rgb(${pa.slice(0, 3).map((x, i) => Math.round(x + (pb[i] - x) * k)).join(',')})`;
64
+ };
65
+
66
+ const rowLayout = (gap: number) => {
67
+ const total = BLOCK_WIDTHS.reduce((a, b) => a + b, 0) + gap * (BLOCK_WIDTHS.length - 1);
68
+ const startX = (1920 - total) / 2;
69
+ const xs: number[] = [];
70
+ let acc = startX;
71
+ for (const w of BLOCK_WIDTHS) {
72
+ xs.push(acc);
73
+ acc += w + gap;
74
+ }
75
+ return { total, startX, xs };
76
+ };
77
+
78
+ const IconAutoLayout: React.FC<{ c: string; size?: number }> = ({ c, size = 22 }) => (
79
+ <svg width={size} height={size} viewBox="0 0 14 14" fill="none">
80
+ <rect x={1} y={3} width={3.4} height={8} rx={1} fill={c} />
81
+ <rect x={5.3} y={3} width={3.4} height={8} rx={1} fill={c} opacity={0.7} />
82
+ <rect x={9.6} y={3} width={3.4} height={8} rx={1} fill={c} opacity={0.45} />
83
+ </svg>
84
+ );
85
+
86
+ // 拨盘刻度尺:每 1 单位 = UNIT px,中心金针读当前 gap
87
+ const RULER_W = 760;
88
+ const UNIT = 6.5;
89
+ const Ruler: React.FC<{ gap: number; op: number; hot: number }> = ({ gap, op, hot }) => {
90
+ const ticks: React.ReactNode[] = [];
91
+ for (let u = -60; u <= 180; u += 2) {
92
+ const x = RULER_W / 2 + (u - gap) * UNIT;
93
+ if (x < -10 || x > RULER_W + 10) continue;
94
+ const major = u % 10 === 0;
95
+ const edge = Math.max(0, Math.min(1, Math.min(x, RULER_W - x) / 150)); // 两端淡出
96
+ const near = Math.abs(x - RULER_W / 2);
97
+ ticks.push(
98
+ <div key={u} style={{
99
+ position: 'absolute', left: x - 1, bottom: 0, width: 2, height: major ? 30 : 14, borderRadius: 1,
100
+ background: u < 0 ? alpha(L.ink, 0.08) : major ? alpha(L.ink, 0.5) : alpha(L.ink, 0.22), opacity: edge,
101
+ }} />,
102
+ );
103
+ if (major && u >= 0) {
104
+ ticks.push(
105
+ <div key={`l${u}`} style={{
106
+ position: 'absolute', left: x, bottom: 40, transform: 'translateX(-50%)',
107
+ ...type(22, 500, { mono: true }), color: L.ink3,
108
+ opacity: edge * Math.min(1, Math.max(0, (near - 18) / 22)), // 靠近指针的数字让位
109
+ }}>{u}</div>,
110
+ );
111
+ }
112
+ }
113
+ return (
114
+ <div style={{ position: 'absolute', left: 960 - RULER_W / 2, top: 414, width: RULER_W, height: 76, opacity: op }}>
115
+ <div style={{ position: 'absolute', inset: 0, overflow: 'hidden' }}>{ticks}</div>
116
+ {/* 基线 */}
117
+ <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 1, background: `linear-gradient(90deg, transparent, ${alpha(L.ink, 0.18)} 20%, ${alpha(L.ink, 0.18)} 80%, transparent)` }} />
118
+ {/* 金针:拨动时泛光 */}
119
+ <div style={{
120
+ position: 'absolute', left: RULER_W / 2 - 1.5, bottom: -6, width: 3, height: 50, borderRadius: 2, background: GOLD,
121
+ boxShadow: `0 0 ${8 + hot * 14}px ${alpha(GOLD, 0.35 + hot * 0.4)}`,
122
+ }} />
123
+ <div style={{
124
+ position: 'absolute', left: RULER_W / 2 - 8, bottom: 44, width: 0, height: 0,
125
+ borderLeft: '8px solid transparent', borderRight: '8px solid transparent', borderTop: `10px solid ${GOLD}`,
126
+ }} />
127
+ </div>
128
+ );
129
+ };
130
+
131
+ export const AutolayoutGapDial: React.FC = () => {
132
+ const frame = useCurrentFrame();
133
+
134
+ const gap = gapAt(frame);
135
+ const gapShown = Math.max(0, Math.round(gap / 2) * 2); // 逐格跳数(步进 2 = 拨盘咔哒的颗粒)
136
+ const v = gapAt(frame + 0.5) - gapAt(frame - 0.5); // gap 速度(px/帧)
137
+ const moving = Math.min(1, Math.abs(v) / 1.2);
138
+ // 拨动热度:读数白→金,带 ~6f 余温(松手回稳后慢慢褪回白)
139
+ let hot = 0;
140
+ for (let k = 0; k <= 6; k++) hot = Math.max(hot, Math.min(1, Math.abs(gapAt(frame - k + 0.5) - gapAt(frame - k - 0.5)) / 1.5) * (1 - k / 7));
141
+ // 跳数脉冲:相位由数值本身驱动(每跨一个步进格脉冲一次)× 速度门限
142
+ const tickPulse = 1 + 0.06 * Math.abs(Math.sin((Math.PI * gap) / 2)) * moving;
143
+
144
+ const { total, startX, xs } = rowLayout(gap);
145
+
146
+ // 相机:整段极缓推近(smooth,起止无速度突变)
147
+ const cam = 1 + 0.025 * ramp(frame, 0, AUTOLAYOUT_GAP_DIAL_DURATION, EASE.smooth);
148
+
149
+ // 框选描边:spring 从外侧 26px 收拢
150
+ const selIn = springAt(frame, 4, { damping: 16, stiffness: 140 });
151
+ const pad = 30;
152
+ const grow = (1 - selIn) * 26;
153
+ const selX = startX - pad - grow;
154
+ const selW = total + pad * 2 + grow * 2;
155
+ const selY = ROW_Y - BLOCK_H / 2 - pad - grow;
156
+ const selH = BLOCK_H + pad * 2 + grow * 2;
157
+
158
+ const measOp = ramp(frame, 14, 10, EASE.out);
159
+ const eyebrow = ramp(frame, 4, 18, EASE.snappy);
160
+ const numIn = ramp(frame, 8, 18, EASE.snappy);
161
+ const rulerIn = ramp(frame, 12, 16, EASE.out);
162
+
163
+ // 读数颜色:白 ↔ 金
164
+ const numColor = mixHex(L.ink, GOLD, hot);
165
+
166
+ return (
167
+ <AbsoluteFill style={{ background: L.bg[1], overflow: 'hidden', fontFamily: FONT.sans }}>
168
+ <Stage look={L} keyLight={{ x: 0.5, y: 0.0 }} fill={{ x: 0.5, y: 1.05 }} horizon={0.62} breathe={0.4}>
169
+ {/* 画布点阵:围绕导航条清楚、四周隐去 */}
170
+ <AbsoluteFill style={{
171
+ backgroundImage: `radial-gradient(${alpha(L.ink, 0.13)} 1.4px, transparent 1.7px)`,
172
+ backgroundSize: '36px 36px', backgroundPosition: '6px 16px',
173
+ WebkitMaskImage: 'radial-gradient(ellipse 52% 40% at 50% 62%, #000 20%, transparent 100%)',
174
+ maskImage: 'radial-gradient(ellipse 52% 40% at 50% 62%, #000 20%, transparent 100%)',
175
+ }} />
176
+ {/* 导航条落脚的光池:条子"站"在画布上 */}
177
+ <div style={{
178
+ position: 'absolute', left: 260, right: 260, top: ROW_Y + 40, height: 200,
179
+ background: `radial-gradient(ellipse 50% 50% at 50% 30%, ${alpha(L.light, 0.1)} 0%, transparent 70%)`,
180
+ }} />
181
+ </Stage>
182
+
183
+ <AbsoluteFill style={{ transform: `scale(${cam})`, transformOrigin: '50% 52%' }}>
184
+ {/* ── 读数:眉题 + 超大数值 + 单位 ── */}
185
+ <div style={{
186
+ position: 'absolute', left: 0, right: 0, top: 150, display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 16,
187
+ opacity: eyebrow, letterSpacing: `${(0.28 + (1 - eyebrow) * 0.4).toFixed(3)}em`,
188
+ ...type(22, 600, { caps: true }), color: L.ink2,
189
+ }}>
190
+ <IconAutoLayout c={L.ink2} />
191
+ <span style={{ letterSpacing: 'inherit' }}>Auto layout · Gap</span>
192
+ </div>
193
+ <div style={{
194
+ position: 'absolute', left: 0, right: 0, top: 186, height: 220, overflow: 'hidden',
195
+ display: 'flex', justifyContent: 'center', alignItems: 'flex-end',
196
+ }}>
197
+ <div style={{
198
+ display: 'flex', alignItems: 'baseline', gap: 18,
199
+ transform: `translateY(${((1 - numIn) * 105).toFixed(2)}%)`,
200
+ }}>
201
+ <span style={{
202
+ ...type(196, 300), letterSpacing: '-0.05em', color: numColor, display: 'inline-block',
203
+ minWidth: '1.9em', textAlign: 'right', transform: `scale(${tickPulse})`, transformOrigin: '100% 80%',
204
+ textShadow: hot > 0.05 ? `0 0 ${(40 * hot).toFixed(1)}px ${alpha(GOLD, 0.35 * hot)}` : undefined,
205
+ }}>{gapShown}</span>
206
+ <span style={{ ...type(60, 500), color: L.ink3, width: '1.9em' }}>px</span>
207
+ </div>
208
+ </div>
209
+ <Ruler gap={gap} op={rulerIn} hot={hot} />
210
+
211
+ {/* ── 导航块(video-shotcraft 站点顶部导航) ── */}
212
+ {BLOCK_WIDTHS.map((w, i) => {
213
+ const inP = ramp(frame, 1 + i * 2, 16, EASE.snappy);
214
+ const active = i === 0;
215
+ const vx = (i - 2) * v; // 块速度 = (i−2)·dgap/dt:外侧块位移最大
216
+ const blur = Math.min(9, Math.abs(vx) * 0.5);
217
+ const fid = `nb${i}`;
218
+ const dy = (1 - inP) * 34;
219
+ return (
220
+ <div key={i} style={{
221
+ position: 'absolute', left: xs[i], top: ROW_Y - BLOCK_H / 2, width: w, height: BLOCK_H,
222
+ opacity: inP, transform: `translateY(${dy.toFixed(2)}px)`,
223
+ }}>
224
+ {blur > 0.5 && (
225
+ <svg width={0} height={0} style={{ position: 'absolute' }} aria-hidden>
226
+ <filter id={fid} x="-20%" y="-10%" width="140%" height="120%" colorInterpolationFilters="sRGB">
227
+ <feGaussianBlur stdDeviation={`${blur.toFixed(2)} 0`} />
228
+ </filter>
229
+ </svg>
230
+ )}
231
+ <div style={{
232
+ position: 'absolute', inset: 0, boxSizing: 'border-box', borderRadius: 24,
233
+ background: active ? 'linear-gradient(180deg, #fbfbf8, #e6e6e1)' : 'linear-gradient(180deg, #212327, #17181b)',
234
+ border: active ? '1px solid rgba(255,255,255,0.7)' : `1px solid ${alpha('#ffffff', 0.09)}`,
235
+ boxShadow: active
236
+ ? `inset 0 1px 0 rgba(255,255,255,1), inset 0 -2px 0 rgba(0,0,0,0.08), ${softShadow(18, { color: '#000000', strength: 2.4 })}`
237
+ : `inset 0 1px 0 ${alpha('#ffffff', 0.08)}, ${softShadow(12, { color: '#000000', strength: 2.4 })}`,
238
+ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 14,
239
+ filter: blur > 0.5 ? `url(#${fid})` : undefined,
240
+ }}>
241
+ {active && <div style={{ width: 12, height: 12, borderRadius: 99, background: '#111214' }} />}
242
+ <span style={{ ...type(36, active ? 650 : 520), color: active ? '#0d0e10' : alpha(L.ink, 0.86) }}>{LABELS[i]}</span>
243
+ </div>
244
+ </div>
245
+ );
246
+ })}
247
+
248
+ {/* ── 框选描边 + 8 手柄 + 图层名 ── */}
249
+ <div style={{
250
+ position: 'absolute', left: selX, top: selY, width: selW, height: selH, boxSizing: 'border-box',
251
+ border: `2px solid ${SEL}`, borderRadius: 6, opacity: Math.min(1, selIn * 1.4),
252
+ }}>
253
+ <div style={{
254
+ position: 'absolute', left: -2, top: -50, display: 'flex', alignItems: 'center', gap: 10,
255
+ ...type(26, 560), color: SEL, whiteSpace: 'nowrap',
256
+ }}>
257
+ <IconAutoLayout c={SEL} size={20} />
258
+ Nav links
259
+ <span style={{ ...type(22, 500, { mono: true }), color: L.ink3, marginLeft: 8 }}>
260
+ {Math.round(total)} × {BLOCK_H}
261
+ </span>
262
+ </div>
263
+ {[[0, 0], [0.5, 0], [1, 0], [0, 0.5], [1, 0.5], [0, 1], [0.5, 1], [1, 1]].map(([hx, hy], i) => {
264
+ const hp = springAt(frame, 7 + i * 1.2, { damping: 13, stiffness: 240 });
265
+ return (
266
+ <div key={i} style={{
267
+ position: 'absolute', left: `${hx * 100}%`, top: `${hy * 100}%`, width: 16, height: 16, marginLeft: -8, marginTop: -8,
268
+ background: L.bg[1], border: `2px solid ${SEL}`, borderRadius: 3, boxSizing: 'border-box', transform: `scale(${hp})`,
269
+ }} />
270
+ );
271
+ })}
272
+ </div>
273
+
274
+ {/* ── 间距标注:延长线 ×2 + 测量线 + 徽章(全部由 gap 实时重算) ── */}
275
+ {xs.slice(0, -1).map((x, i) => {
276
+ const gx = x + BLOCK_WIDTHS[i];
277
+ const cy = ROW_Y + BLOCK_H / 2 + 74;
278
+ const extTop = ROW_Y + BLOCK_H / 2 + 34;
279
+ const span = Math.max(0, gap);
280
+ const bp = ramp(frame, 14 + i * 2, 12, EASE.snappy);
281
+ return (
282
+ <div key={i} style={{ position: 'absolute', left: 0, top: 0, opacity: measOp }}>
283
+ {[gx, gx + gap].map((lx, k) => (
284
+ <div key={k} style={{
285
+ position: 'absolute', left: lx - 0.75, top: extTop, width: 1.5, height: 58,
286
+ backgroundImage: `linear-gradient(${GOLD} 55%, transparent 55%)`, backgroundSize: '1.5px 7px', opacity: 0.7,
287
+ }} />
288
+ ))}
289
+ <div style={{ position: 'absolute', left: gx, top: cy - 1, width: span, height: 2, background: GOLD, boxShadow: `0 0 10px ${alpha(GOLD, 0.4)}` }} />
290
+ <div style={{ position: 'absolute', left: gx - 1, top: cy - 8, width: 2, height: 16, background: GOLD }} />
291
+ <div style={{ position: 'absolute', left: gx + gap - 1, top: cy - 8, width: 2, height: 16, background: GOLD }} />
292
+ <div style={{
293
+ position: 'absolute', left: gx + gap / 2, top: cy + 20,
294
+ transform: `translateX(-50%) translateY(${((1 - bp) * 10).toFixed(1)}px) scale(${(tickPulse * (0.7 + 0.3 * bp)).toFixed(3)})`,
295
+ opacity: bp, minWidth: 64, textAlign: 'center', boxSizing: 'border-box', padding: '6px 14px', borderRadius: 10,
296
+ background: GOLD, color: L.onAccent, ...type(28, 700), lineHeight: 1.1,
297
+ boxShadow: `inset 0 1px 0 rgba(255,255,255,0.45), 0 6px 18px -6px ${alpha(GOLD, 0.6)}`,
298
+ }}>{gapShown}</div>
299
+ </div>
300
+ );
301
+ })}
302
+ </AbsoluteFill>
303
+ </AbsoluteFill>
304
+ );
305
+ };