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,345 +1,345 @@
1
- // hit-counter 连招计数:三张功能卡接连砸入槽位,每次命中 = 全局顿帧 2f + 落点伤害数字上浮渐隐
2
- // + 右上角 ×N combo 跳字(脉冲 / 倾斜 / 字号逐次加码)。组合:hitstop + damage-number-pop + combo-counter。
3
- //
4
- // 第二轮重设计(钴蓝街机海报 · 构建工具更新日):
5
- // - look = custom「cobalt arcade」:满版高饱和钴蓝色场(不是深海军蓝暗场)+ 白卡 + 街机黄。
6
- // 格斗游戏 combo UI 的语言直接拿来讲"功能连招":伤害数字是黄色斜体 900 字重 + 硬投影(漫画式错位影),
7
- // 计数器是 150→210px 的斜体「×N」,底下三格热度条逐格点亮。
8
- // - 内容:video-shotcraft 的三项能力,每一击的"伤害"= 做一支宣传片省下的制作时间(−2 h / −1 day / −3 days,示意值),
9
- // 三击打完收尾一行「Up to a week back on every promo.」——游戏梗落到真实收益上。
10
- // - 顿帧是全局的:背景斜纹滚动、浮尘、卡片、特效全部由同一个 remap 时间 t 驱动,命中时整幅画面一起冻 2f;
11
- // 只有卡面闪白与槽位受光用真实帧(冻结期间也要发生)。
12
- // - 触地:卡按速度竖向拉伸 + 运动模糊 → 触地压扁回弹(指数回落)→ 白色冲击环外扩 + 黄色火花八向迸射 + 槽底受光。
13
- //
14
- // 时间表(动画时间 t,30fps;真实帧 = t + 已冻结帧):
15
- // 0–22 建立:钴蓝场、三个虚线槽位(01/02/03)、眉题、暗色 ×0 计数器
16
- // 20/48/76 → 30/58/86 三张卡各 10f ease-in(quad) 砸落(间隔 28f 的均匀连招节拍)
17
- // 每命中 全局顿帧 2f;伤害数字打在卡面上 scale 1.45→1 + 上浮 150px 出卡沿,4f 后 12f 渐隐;计数器 exp(−t/2.4) 回落
18
- // 100–124 收尾行逐词升起,"a week" 用街机黄
19
- // 124–176 hold:背景斜纹极缓滚动,干净海报
20
- import React from 'react';
21
- import { AbsoluteFill, useCurrentFrame } from 'remotion';
22
- import { EASE, FONT, Grain, SpeedBlur, Vignette, bezier, mix, ramp } from '../../_fixtures/Polish';
23
- import { TextReveal, alpha, type } from '../../_fixtures/Look';
24
- import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
25
-
26
- export const HIT_COUNTER_DURATION = 176;
27
-
28
- // 自定义 look「cobalt arcade」
29
- const C = {
30
- bg0: '#1b3fd6', bg1: '#1230b0', bg2: '#0a1d78',
31
- card: '#f7f8ff', ink: '#0b1240', ink2: '#4a5488', ink3: '#8a93bf',
32
- hit: '#ffd23f', // 街机黄:只给伤害数字 / 计数器 / 火花 / 关键收益
33
- deep: '#06104a', // 硬投影色
34
- };
35
-
36
- const HITS_T = [30, 58, 86]; // 命中时刻(动画时间)
37
- const STOP = 2; // 每次顿帧帧数
38
- const HITS_REAL = HITS_T.map((h, i) => h + i * STOP); // 真实命中帧 = 动画命中帧 + 已冻结帧
39
-
40
- const SLOT_W = 480;
41
- const SLOT_H = 330;
42
- const SLOT_Y = 446;
43
- const GAP = 60;
44
- const SLOT_XS = [0, 1, 2].map((i) => 960 - (SLOT_W * 3 + GAP * 2) / 2 + i * (SLOT_W + GAP));
45
- const DROP_FROM = -460;
46
- const inQuad = bezier(0.55, 0.085, 0.68, 0.53);
47
-
48
- const DMG = ['−2 h', '−1 day', '−3 days'];
49
- const DMG_SIZE = [88, 104, 124]; // 伤害数字逐击加大
50
- const PULSE = [1.3, 1.45, 1.6];
51
- const TILT = [-2, -4, -6];
52
- const COUNTER_SIZE = [140, 166, 196];
53
-
54
- const FEATURES = [
55
- { icon: 'recipe', name: 'Shot recipes', desc: 'Pick a move, not a blank canvas.', note: 'per shot' },
56
- { icon: 'beat', name: 'Beat-synced cuts', desc: 'Every cut lands on the music.', note: 'per edit' },
57
- { icon: 'layers', name: '2.5D camera', desc: 'Real pages, filmed in depth.', note: 'per promo' },
58
- ];
59
-
60
- const Icon: React.FC<{ name: string }> = ({ name }) => {
61
- const sw = { fill: 'none', stroke: C.bg1, strokeWidth: 2, strokeLinecap: 'round' as const, strokeLinejoin: 'round' as const };
62
- return (
63
- <svg width={34} height={34} viewBox="0 0 24 24">
64
- {/* 镜头配方卡 */}
65
- {name === 'recipe' && (
66
- <>
67
- <rect x="4" y="3.5" width="16" height="17" rx="2.5" {...sw} />
68
- <path d="M8 8.5h8M8 12h8M8 15.5h5" {...sw} />
69
- </>
70
- )}
71
- {/* 踩点:波形 */}
72
- {name === 'beat' && <path d="M3 12h1.5M7 8.5v7M11 4.5v15M15 8v8M19 10.5v3M21 12h0.5" {...sw} />}
73
- {/* 2.5D:层叠景深 */}
74
- {name === 'layers' && (
75
- <>
76
- <path d="M3 8.5L12 4l9 4.5-9 4.5-9-4.5z" {...sw} />
77
- <path d="M3 12.5l9 4.5 9-4.5M3 16.5L12 21l9-4.5" {...sw} />
78
- </>
79
- )}
80
- </svg>
81
- );
82
- };
83
-
84
- // saved = 伤害数字飘走后,收益「落」进卡片页脚的进度(0–1)
85
- const FeatureCard: React.FC<{ i: number; elev: number; saved: number }> = ({ i, elev, saved }) => {
86
- const f = FEATURES[i];
87
- return (
88
- <div
89
- style={{
90
- width: SLOT_W, height: SLOT_H, boxSizing: 'border-box', borderRadius: 26, padding: '34px 38px 32px',
91
- background: `linear-gradient(180deg, #ffffff 0%, ${C.card} 100%)`,
92
- boxShadow: `inset 0 1px 0 #fff, 0 ${(2 + elev * 0.4).toFixed(1)}px ${(4 + elev * 0.6).toFixed(1)}px ${alpha(C.deep, 0.25)}, 0 ${(10 + elev * 0.8).toFixed(1)}px ${(30 + elev * 1.4).toFixed(1)}px -8px ${alpha(C.deep, 0.5)}`,
93
- display: 'flex', flexDirection: 'column', fontFamily: FONT.sans, color: C.ink,
94
- }}
95
- >
96
- <div style={{ display: 'flex', alignItems: 'center' }}>
97
- <div style={{ width: 62, height: 62, borderRadius: 18, background: alpha(C.bg0, 0.1), display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
98
- <Icon name={f.icon} />
99
- </div>
100
- <div style={{ marginLeft: 'auto', ...type(26, 600, { mono: true }), color: C.ink3 }}>0{i + 1}</div>
101
- </div>
102
- <div style={{ marginTop: 30, ...type(48, 760), letterSpacing: '-0.035em', lineHeight: 1.02 }}>{f.name}</div>
103
- <div style={{ marginTop: 12, ...type(30, 450), lineHeight: 1.3, color: C.ink2 }}>{f.desc}</div>
104
- <div
105
- style={{
106
- marginTop: 'auto', paddingTop: 18, borderTop: `1px solid ${alpha(C.ink, 0.1)}`, display: 'flex', alignItems: 'baseline',
107
- opacity: saved, transform: `translateY(${mix(10, 0, saved).toFixed(1)}px)`,
108
- }}
109
- >
110
- <span style={{ ...type(32, 800), fontStyle: 'italic', letterSpacing: '-0.02em', color: C.bg1 }}>{DMG[i]}</span>
111
- <span style={{ marginLeft: 'auto', ...type(26, 500), color: C.ink3 }}>{f.note}</span>
112
- </div>
113
- </div>
114
- );
115
- };
116
-
117
- const dropY = (t: number, hit: number) => mix(DROP_FROM, SLOT_Y, ramp(t, hit - 10, 10, inQuad));
118
-
119
- const hash = (n: number) => {
120
- const x = Math.sin(n * 127.1 + 311.7) * 43758.5453;
121
- return x - Math.floor(x);
122
- };
123
-
124
- export const HitCounter: React.FC = () => {
125
- const frame = useCurrentFrame();
126
-
127
- // —— 全局帧 remap:每个真实命中帧起冻结 2f ——
128
- const remap = (fr: number) => {
129
- let t = fr;
130
- for (const h of HITS_REAL) t -= Math.min(Math.max(fr - h, 0), STOP);
131
- return t;
132
- };
133
- const t = remap(frame);
134
- const count = HITS_T.filter((h) => t >= h).length;
135
-
136
- // —— 计数器 ——
137
- let cScale = 1;
138
- let cRot = 0;
139
- let cSize = 130;
140
- if (count > 0) {
141
- const i = count - 1;
142
- const since = t - HITS_T[i];
143
- cScale = 1 + (PULSE[i] - 1) * Math.exp(-since / 2.4);
144
- cRot = TILT[i];
145
- cSize = COUNTER_SIZE[i];
146
- }
147
- const stamp = count > 0 ? 1 - ramp(t, HITS_T[count - 1], 7, EASE.out) : 0;
148
-
149
- // 背景斜纹滚动(t 驱动 → 顿帧时一起冻住)
150
- const stripeShift = t * 2.2;
151
-
152
- return (
153
- <AbsoluteFill style={{ overflow: 'hidden', fontFamily: FONT.sans, background: `linear-gradient(170deg, ${C.bg0} 0%, ${C.bg1} 55%, ${C.bg2} 100%)` }}>
154
- {/* 背景:主光 + 斜纹(速度线的静态版)+ 网点 */}
155
- <div style={{ position: 'absolute', inset: 0, background: `radial-gradient(ellipse 60% 55% at 38% 30%, ${alpha('#6f8dff', 0.45)} 0%, ${alpha('#6f8dff', 0)} 70%)` }} />
156
- <div
157
- style={{
158
- position: 'absolute', inset: -200, opacity: 0.1,
159
- backgroundImage: 'repeating-linear-gradient(-58deg, #ffffff 0px, #ffffff 2px, transparent 2px, transparent 46px)',
160
- transform: `translateX(${(stripeShift % 54.2).toFixed(2)}px)`,
161
- }}
162
- />
163
- <div
164
- style={{
165
- position: 'absolute', inset: 0, opacity: 0.14,
166
- backgroundImage: `radial-gradient(circle, ${C.deep} 1.4px, transparent 1.6px)`, backgroundSize: '18px 18px',
167
- WebkitMaskImage: 'linear-gradient(180deg, transparent 40%, #000 100%)', maskImage: 'linear-gradient(180deg, transparent 40%, #000 100%)',
168
- }}
169
- />
170
-
171
- {/* 眉题 */}
172
- <div style={{ position: 'absolute', left: 120, top: 104, display: 'flex', alignItems: 'center', gap: 18, opacity: ramp(frame, 0, 14, EASE.out) }}>
173
- <ShotcraftMark size={52} tone="dark" />
174
- <div style={{ ...type(34, 760), color: '#fff', letterSpacing: '-0.02em' }}>{BRAND.name}</div>
175
- <div style={{ ...type(24, 650, { caps: true }), color: alpha('#ffffff', 0.62), letterSpacing: '0.24em', marginLeft: 8 }}>What’s new</div>
176
- </div>
177
-
178
- {/* 槽位:虚线 + 大号序号,建立期就立预期 */}
179
- {SLOT_XS.map((x, i) => {
180
- const near = ramp(t, HITS_T[i] - 10, 10, inQuad);
181
- const df = frame - HITS_REAL[i];
182
- const glowA = df >= 0 ? Math.exp(-df / 6) : 0; // 槽底受光(真实帧)
183
- return (
184
- <React.Fragment key={`slot-${i}`}>
185
- <div
186
- style={{
187
- position: 'absolute', left: x, top: SLOT_Y, width: SLOT_W, height: SLOT_H, borderRadius: 26, boxSizing: 'border-box',
188
- border: `2px dashed ${alpha('#ffffff', 0.28)}`, background: alpha(C.deep, 0.16),
189
- display: 'flex', alignItems: 'center', justifyContent: 'center',
190
- ...type(120, 800), color: alpha('#ffffff', 0.1), letterSpacing: '-0.04em',
191
- }}
192
- >
193
- 0{i + 1}
194
- </div>
195
- {near > 0 && t < HITS_T[i] && (
196
- <div
197
- style={{
198
- position: 'absolute', left: x + 40 - (1 - near) * 40, top: SLOT_Y + 50, width: SLOT_W - 80 + (1 - near) * 80, height: SLOT_H - 40,
199
- borderRadius: 30, background: C.deep, filter: `blur(${mix(44, 16, near).toFixed(1)}px)`, opacity: mix(0.05, 0.5, near),
200
- }}
201
- />
202
- )}
203
- {glowA > 0.02 && (
204
- <div
205
- style={{
206
- position: 'absolute', left: x - 120, top: SLOT_Y + SLOT_H - 80, width: SLOT_W + 240, height: 200, borderRadius: '50%',
207
- background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha(C.hit, 0.45 * glowA)} 0%, ${alpha(C.hit, 0)} 70%)`,
208
- }}
209
- />
210
- )}
211
- </React.Fragment>
212
- );
213
- })}
214
-
215
- {/* 三张功能卡 */}
216
- {HITS_T.map((hit, i) => {
217
- if (t < hit - 10) return null;
218
- const y = dropY(t, hit);
219
- const vy = t < hit ? dropY(t + 0.5, hit) - dropY(t - 0.5, hit) : 0;
220
- const speed = Math.min(1, vy / 200);
221
- const s = t - hit;
222
- const squash = s >= 0 ? 0.07 * Math.exp(-s / 1.6) : 0;
223
- const sy = 1 + speed * 0.06 - squash;
224
- const sx = 1 - speed * 0.025 + squash * 0.5;
225
- const elev = s >= 0 ? 6 : mix(6, 60, (SLOT_Y - y) / (SLOT_Y - DROP_FROM));
226
- const df = frame - HITS_REAL[i];
227
- const flash = df >= 0 && df < STOP + 4 ? (df < STOP ? 0.7 : 0.7 * (1 - (df - STOP + 1) / 5)) : 0;
228
- return (
229
- <SpeedBlur key={`card-${i}`} vx={0} vy={vy} amount={0.12} max={24}>
230
- <div style={{ position: 'absolute', left: SLOT_XS[i], top: y, transform: `scale(${sx.toFixed(4)}, ${sy.toFixed(4)})`, transformOrigin: 'bottom center' }}>
231
- <FeatureCard i={i} elev={elev} saved={ramp(t, hit + 12, 12, EASE.snappy)} />
232
- {flash > 0 && <div style={{ position: 'absolute', inset: 0, borderRadius: 26, background: '#ffffff', opacity: flash }} />}
233
- </div>
234
- </SpeedBlur>
235
- );
236
- })}
237
-
238
- {/* 触地冲击:白色冲击环 + 八向黄色火花(t 驱动,顿帧时冻住) */}
239
- {HITS_T.map((hit, i) => {
240
- const s = t - hit;
241
- if (s < 0 || s > 16) return null;
242
- const ring = ramp(t, hit, 14, EASE.out);
243
- const grow = mix(0, 46 + i * 10, ring);
244
- const x0 = SLOT_XS[i];
245
- const cx = x0 + SLOT_W / 2;
246
- const cy = SLOT_Y + SLOT_H / 2;
247
- const burst = ramp(t, hit, 12, EASE.snappy);
248
- const n = 10 + i * 3; // 火花逐击加码
249
- return (
250
- <React.Fragment key={`fx-${i}`}>
251
- <div
252
- style={{
253
- position: 'absolute', left: x0 - grow, top: SLOT_Y - grow * 0.7, width: SLOT_W + grow * 2, height: SLOT_H + grow * 1.4,
254
- borderRadius: 26 + grow * 0.6, boxSizing: 'border-box', border: `${mix(5, 1, ring).toFixed(2)}px solid #ffffff`, opacity: (1 - ring) * 0.8,
255
- }}
256
- />
257
- <svg width={1920} height={1080} style={{ position: 'absolute', left: 0, top: 0, overflow: 'visible' }}>
258
- {Array.from({ length: n }, (_, k) => {
259
- const ang = (k / n) * Math.PI * 2 + hash(i * 31 + k) * 0.4;
260
- const rx = SLOT_W * 0.52;
261
- const ry = SLOT_H * 0.56;
262
- const r0 = mix(1, 1.08 + hash(k + i * 7) * 0.15, burst);
263
- const r1 = mix(1.04, 1.3 + hash(k * 3 + i) * 0.35 + i * 0.06, Math.min(1, burst * 1.2));
264
- return (
265
- <line
266
- key={k}
267
- x1={cx + Math.cos(ang) * rx * r0} y1={cy + Math.sin(ang) * ry * r0}
268
- x2={cx + Math.cos(ang) * rx * r1} y2={cy + Math.sin(ang) * ry * r1}
269
- stroke={k % 3 === 0 ? '#ffffff' : C.hit} strokeWidth={mix(7, 2, burst)} strokeLinecap="round"
270
- opacity={Math.min(1, burst * 6) * (1 - burst)}
271
- />
272
- );
273
- })}
274
- </svg>
275
- </React.Fragment>
276
- );
277
- })}
278
-
279
- {/* 伤害数字:黄色斜体 + 漫画式硬投影 */}
280
- {HITS_T.map((hit, i) => {
281
- const s = t - hit;
282
- if (s < 0 || s > 17) return null;
283
- const scale = mix(1.45, 1, ramp(t, hit, 5, EASE.snappy));
284
- const rise = mix(0, -150, ramp(t, hit, 16, EASE.out));
285
- const opacity = s < 4 ? 1 : 1 - ramp(t, hit + 4, 12, EASE.swift);
286
- return (
287
- <div
288
- key={`dmg-${i}`}
289
- style={{
290
- // 落点在卡面中下部(打在目标身上),上浮出卡沿:不与右上角计数器抢位置
291
- position: 'absolute', left: SLOT_XS[i] + SLOT_W / 2, top: SLOT_Y + SLOT_H * 0.62 - DMG_SIZE[i] + rise,
292
- transform: `translateX(-50%) scale(${scale.toFixed(3)}) skewX(-8deg)`, transformOrigin: 'center bottom', opacity,
293
- ...type(DMG_SIZE[i], 900), fontStyle: 'italic', letterSpacing: '-0.04em', lineHeight: 1, color: C.hit, whiteSpace: 'nowrap',
294
- textShadow: `6px 6px 0 ${C.deep}`,
295
- }}
296
- >
297
- {DMG[i]}
298
- </div>
299
- );
300
- })}
301
-
302
- {/* 右上角 combo 计数器 */}
303
- <div
304
- style={{
305
- position: 'absolute', right: 120, top: 64, width: 400, height: 280,
306
- transform: `scale(${cScale.toFixed(4)}) rotate(${cRot}deg)`, transformOrigin: '90% 20%',
307
- display: 'flex', flexDirection: 'column', alignItems: 'flex-end',
308
- }}
309
- >
310
- <div style={{ ...type(26, 800, { caps: true }), letterSpacing: '0.3em', color: count ? '#ffffff' : alpha('#ffffff', 0.4), fontStyle: 'italic' }}>Combo</div>
311
- <div
312
- style={{
313
- ...type(cSize, 900), fontStyle: 'italic', letterSpacing: '-0.05em', lineHeight: 0.9, whiteSpace: 'nowrap',
314
- color: count ? C.hit : alpha('#ffffff', 0.22), textShadow: count ? `7px 7px 0 ${C.deep}` : 'none',
315
- transform: `translateY(${(-stamp * 0.14 * cSize).toFixed(1)}px) skewX(-6deg)`, marginTop: 6,
316
- }}
317
- >
318
- ×{count}
319
- </div>
320
- <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
321
- {[0, 1, 2].map((k) => (
322
- <div key={k} style={{ width: 56, height: 10, borderRadius: 5, background: k < count ? C.hit : alpha('#ffffff', 0.18), boxShadow: k < count ? `3px 3px 0 ${C.deep}` : 'none' }} />
323
- ))}
324
- </div>
325
- </div>
326
-
327
- {/* 收尾:真实收益 */}
328
- <div style={{ position: 'absolute', left: 0, right: 0, top: 866, textAlign: 'center' }}>
329
- <TextReveal
330
- text="Up to a week back on every promo."
331
- by="word"
332
- variant="rise"
333
- start={HITS_REAL[2] + 14}
334
- each={18}
335
- gap={3}
336
- style={{ ...type(60, 760), letterSpacing: '-0.03em', color: '#ffffff' }}
337
- unitStyle={(k) => (k === 2 || k === 3 ? { color: C.hit } : {})}
338
- />
339
- </div>
340
-
341
- <Vignette strength={0.42} inner={0.45} color={C.deep} />
342
- <Grain opacity={0.07} blend="soft-light" />
343
- </AbsoluteFill>
344
- );
345
- };
1
+ // hit-counter 连招计数:三张功能卡接连砸入槽位,每次命中 = 全局顿帧 2f + 落点伤害数字上浮渐隐
2
+ // + 右上角 ×N combo 跳字(脉冲 / 倾斜 / 字号逐次加码)。组合:hitstop + damage-number-pop + combo-counter。
3
+ //
4
+ // 第二轮重设计(钴蓝街机海报 · 构建工具更新日):
5
+ // - look = custom「cobalt arcade」:满版高饱和钴蓝色场(不是深海军蓝暗场)+ 白卡 + 街机黄。
6
+ // 格斗游戏 combo UI 的语言直接拿来讲"功能连招":伤害数字是黄色斜体 900 字重 + 硬投影(漫画式错位影),
7
+ // 计数器是 150→210px 的斜体「×N」,底下三格热度条逐格点亮。
8
+ // - 内容:video-shotcraft 的三项能力,每一击的"伤害"= 做一支宣传片省下的制作时间(−2 h / −1 day / −3 days,示意值),
9
+ // 三击打完收尾一行「Up to a week back on every promo.」——游戏梗落到真实收益上。
10
+ // - 顿帧是全局的:背景斜纹滚动、浮尘、卡片、特效全部由同一个 remap 时间 t 驱动,命中时整幅画面一起冻 2f;
11
+ // 只有卡面闪白与槽位受光用真实帧(冻结期间也要发生)。
12
+ // - 触地:卡按速度竖向拉伸 + 运动模糊 → 触地压扁回弹(指数回落)→ 白色冲击环外扩 + 黄色火花八向迸射 + 槽底受光。
13
+ //
14
+ // 时间表(动画时间 t,30fps;真实帧 = t + 已冻结帧):
15
+ // 0–22 建立:钴蓝场、三个虚线槽位(01/02/03)、眉题、暗色 ×0 计数器
16
+ // 20/48/76 → 30/58/86 三张卡各 10f ease-in(quad) 砸落(间隔 28f 的均匀连招节拍)
17
+ // 每命中 全局顿帧 2f;伤害数字打在卡面上 scale 1.45→1 + 上浮 150px 出卡沿,4f 后 12f 渐隐;计数器 exp(−t/2.4) 回落
18
+ // 100–124 收尾行逐词升起,"a week" 用街机黄
19
+ // 124–176 hold:背景斜纹极缓滚动,干净海报
20
+ import React from 'react';
21
+ import { AbsoluteFill, useCurrentFrame } from 'remotion';
22
+ import { EASE, FONT, Grain, SpeedBlur, Vignette, bezier, mix, ramp } from '../../_fixtures/Polish';
23
+ import { TextReveal, alpha, type } from '../../_fixtures/Look';
24
+ import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
25
+
26
+ export const HIT_COUNTER_DURATION = 176;
27
+
28
+ // 自定义 look「cobalt arcade」
29
+ const C = {
30
+ bg0: '#1b3fd6', bg1: '#1230b0', bg2: '#0a1d78',
31
+ card: '#f7f8ff', ink: '#0b1240', ink2: '#4a5488', ink3: '#8a93bf',
32
+ hit: '#ffd23f', // 街机黄:只给伤害数字 / 计数器 / 火花 / 关键收益
33
+ deep: '#06104a', // 硬投影色
34
+ };
35
+
36
+ const HITS_T = [30, 58, 86]; // 命中时刻(动画时间)
37
+ const STOP = 2; // 每次顿帧帧数
38
+ const HITS_REAL = HITS_T.map((h, i) => h + i * STOP); // 真实命中帧 = 动画命中帧 + 已冻结帧
39
+
40
+ const SLOT_W = 480;
41
+ const SLOT_H = 330;
42
+ const SLOT_Y = 446;
43
+ const GAP = 60;
44
+ const SLOT_XS = [0, 1, 2].map((i) => 960 - (SLOT_W * 3 + GAP * 2) / 2 + i * (SLOT_W + GAP));
45
+ const DROP_FROM = -460;
46
+ const inQuad = bezier(0.55, 0.085, 0.68, 0.53);
47
+
48
+ const DMG = ['−2 h', '−1 day', '−3 days'];
49
+ const DMG_SIZE = [88, 104, 124]; // 伤害数字逐击加大
50
+ const PULSE = [1.3, 1.45, 1.6];
51
+ const TILT = [-2, -4, -6];
52
+ const COUNTER_SIZE = [140, 166, 196];
53
+
54
+ const FEATURES = [
55
+ { icon: 'recipe', name: 'Shot recipes', desc: 'Pick a move, not a blank canvas.', note: 'per shot' },
56
+ { icon: 'beat', name: 'Beat-synced cuts', desc: 'Every cut lands on the music.', note: 'per edit' },
57
+ { icon: 'layers', name: '2.5D camera', desc: 'Real pages, filmed in depth.', note: 'per promo' },
58
+ ];
59
+
60
+ const Icon: React.FC<{ name: string }> = ({ name }) => {
61
+ const sw = { fill: 'none', stroke: C.bg1, strokeWidth: 2, strokeLinecap: 'round' as const, strokeLinejoin: 'round' as const };
62
+ return (
63
+ <svg width={34} height={34} viewBox="0 0 24 24">
64
+ {/* 镜头配方卡 */}
65
+ {name === 'recipe' && (
66
+ <>
67
+ <rect x="4" y="3.5" width="16" height="17" rx="2.5" {...sw} />
68
+ <path d="M8 8.5h8M8 12h8M8 15.5h5" {...sw} />
69
+ </>
70
+ )}
71
+ {/* 踩点:波形 */}
72
+ {name === 'beat' && <path d="M3 12h1.5M7 8.5v7M11 4.5v15M15 8v8M19 10.5v3M21 12h0.5" {...sw} />}
73
+ {/* 2.5D:层叠景深 */}
74
+ {name === 'layers' && (
75
+ <>
76
+ <path d="M3 8.5L12 4l9 4.5-9 4.5-9-4.5z" {...sw} />
77
+ <path d="M3 12.5l9 4.5 9-4.5M3 16.5L12 21l9-4.5" {...sw} />
78
+ </>
79
+ )}
80
+ </svg>
81
+ );
82
+ };
83
+
84
+ // saved = 伤害数字飘走后,收益「落」进卡片页脚的进度(0–1)
85
+ const FeatureCard: React.FC<{ i: number; elev: number; saved: number }> = ({ i, elev, saved }) => {
86
+ const f = FEATURES[i];
87
+ return (
88
+ <div
89
+ style={{
90
+ width: SLOT_W, height: SLOT_H, boxSizing: 'border-box', borderRadius: 26, padding: '34px 38px 32px',
91
+ background: `linear-gradient(180deg, #ffffff 0%, ${C.card} 100%)`,
92
+ boxShadow: `inset 0 1px 0 #fff, 0 ${(2 + elev * 0.4).toFixed(1)}px ${(4 + elev * 0.6).toFixed(1)}px ${alpha(C.deep, 0.25)}, 0 ${(10 + elev * 0.8).toFixed(1)}px ${(30 + elev * 1.4).toFixed(1)}px -8px ${alpha(C.deep, 0.5)}`,
93
+ display: 'flex', flexDirection: 'column', fontFamily: FONT.sans, color: C.ink,
94
+ }}
95
+ >
96
+ <div style={{ display: 'flex', alignItems: 'center' }}>
97
+ <div style={{ width: 62, height: 62, borderRadius: 18, background: alpha(C.bg0, 0.1), display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
98
+ <Icon name={f.icon} />
99
+ </div>
100
+ <div style={{ marginLeft: 'auto', ...type(26, 600, { mono: true }), color: C.ink3 }}>0{i + 1}</div>
101
+ </div>
102
+ <div style={{ marginTop: 30, ...type(48, 760), letterSpacing: '-0.035em', lineHeight: 1.02 }}>{f.name}</div>
103
+ <div style={{ marginTop: 12, ...type(30, 450), lineHeight: 1.3, color: C.ink2 }}>{f.desc}</div>
104
+ <div
105
+ style={{
106
+ marginTop: 'auto', paddingTop: 18, borderTop: `1px solid ${alpha(C.ink, 0.1)}`, display: 'flex', alignItems: 'baseline',
107
+ opacity: saved, transform: `translateY(${mix(10, 0, saved).toFixed(1)}px)`,
108
+ }}
109
+ >
110
+ <span style={{ ...type(32, 800), fontStyle: 'italic', letterSpacing: '-0.02em', color: C.bg1 }}>{DMG[i]}</span>
111
+ <span style={{ marginLeft: 'auto', ...type(26, 500), color: C.ink3 }}>{f.note}</span>
112
+ </div>
113
+ </div>
114
+ );
115
+ };
116
+
117
+ const dropY = (t: number, hit: number) => mix(DROP_FROM, SLOT_Y, ramp(t, hit - 10, 10, inQuad));
118
+
119
+ const hash = (n: number) => {
120
+ const x = Math.sin(n * 127.1 + 311.7) * 43758.5453;
121
+ return x - Math.floor(x);
122
+ };
123
+
124
+ export const HitCounter: React.FC = () => {
125
+ const frame = useCurrentFrame();
126
+
127
+ // —— 全局帧 remap:每个真实命中帧起冻结 2f ——
128
+ const remap = (fr: number) => {
129
+ let t = fr;
130
+ for (const h of HITS_REAL) t -= Math.min(Math.max(fr - h, 0), STOP);
131
+ return t;
132
+ };
133
+ const t = remap(frame);
134
+ const count = HITS_T.filter((h) => t >= h).length;
135
+
136
+ // —— 计数器 ——
137
+ let cScale = 1;
138
+ let cRot = 0;
139
+ let cSize = 130;
140
+ if (count > 0) {
141
+ const i = count - 1;
142
+ const since = t - HITS_T[i];
143
+ cScale = 1 + (PULSE[i] - 1) * Math.exp(-since / 2.4);
144
+ cRot = TILT[i];
145
+ cSize = COUNTER_SIZE[i];
146
+ }
147
+ const stamp = count > 0 ? 1 - ramp(t, HITS_T[count - 1], 7, EASE.out) : 0;
148
+
149
+ // 背景斜纹滚动(t 驱动 → 顿帧时一起冻住)
150
+ const stripeShift = t * 2.2;
151
+
152
+ return (
153
+ <AbsoluteFill style={{ overflow: 'hidden', fontFamily: FONT.sans, background: `linear-gradient(170deg, ${C.bg0} 0%, ${C.bg1} 55%, ${C.bg2} 100%)` }}>
154
+ {/* 背景:主光 + 斜纹(速度线的静态版)+ 网点 */}
155
+ <div style={{ position: 'absolute', inset: 0, background: `radial-gradient(ellipse 60% 55% at 38% 30%, ${alpha('#6f8dff', 0.45)} 0%, ${alpha('#6f8dff', 0)} 70%)` }} />
156
+ <div
157
+ style={{
158
+ position: 'absolute', inset: -200, opacity: 0.1,
159
+ backgroundImage: 'repeating-linear-gradient(-58deg, #ffffff 0px, #ffffff 2px, transparent 2px, transparent 46px)',
160
+ transform: `translateX(${(stripeShift % 54.2).toFixed(2)}px)`,
161
+ }}
162
+ />
163
+ <div
164
+ style={{
165
+ position: 'absolute', inset: 0, opacity: 0.14,
166
+ backgroundImage: `radial-gradient(circle, ${C.deep} 1.4px, transparent 1.6px)`, backgroundSize: '18px 18px',
167
+ WebkitMaskImage: 'linear-gradient(180deg, transparent 40%, #000 100%)', maskImage: 'linear-gradient(180deg, transparent 40%, #000 100%)',
168
+ }}
169
+ />
170
+
171
+ {/* 眉题 */}
172
+ <div style={{ position: 'absolute', left: 120, top: 104, display: 'flex', alignItems: 'center', gap: 18, opacity: ramp(frame, 0, 14, EASE.out) }}>
173
+ <ShotcraftMark size={52} tone="dark" />
174
+ <div style={{ ...type(34, 760), color: '#fff', letterSpacing: '-0.02em' }}>{BRAND.name}</div>
175
+ <div style={{ ...type(24, 650, { caps: true }), color: alpha('#ffffff', 0.62), letterSpacing: '0.24em', marginLeft: 8 }}>What’s new</div>
176
+ </div>
177
+
178
+ {/* 槽位:虚线 + 大号序号,建立期就立预期 */}
179
+ {SLOT_XS.map((x, i) => {
180
+ const near = ramp(t, HITS_T[i] - 10, 10, inQuad);
181
+ const df = frame - HITS_REAL[i];
182
+ const glowA = df >= 0 ? Math.exp(-df / 6) : 0; // 槽底受光(真实帧)
183
+ return (
184
+ <React.Fragment key={`slot-${i}`}>
185
+ <div
186
+ style={{
187
+ position: 'absolute', left: x, top: SLOT_Y, width: SLOT_W, height: SLOT_H, borderRadius: 26, boxSizing: 'border-box',
188
+ border: `2px dashed ${alpha('#ffffff', 0.28)}`, background: alpha(C.deep, 0.16),
189
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
190
+ ...type(120, 800), color: alpha('#ffffff', 0.1), letterSpacing: '-0.04em',
191
+ }}
192
+ >
193
+ 0{i + 1}
194
+ </div>
195
+ {near > 0 && t < HITS_T[i] && (
196
+ <div
197
+ style={{
198
+ position: 'absolute', left: x + 40 - (1 - near) * 40, top: SLOT_Y + 50, width: SLOT_W - 80 + (1 - near) * 80, height: SLOT_H - 40,
199
+ borderRadius: 30, background: C.deep, filter: `blur(${mix(44, 16, near).toFixed(1)}px)`, opacity: mix(0.05, 0.5, near),
200
+ }}
201
+ />
202
+ )}
203
+ {glowA > 0.02 && (
204
+ <div
205
+ style={{
206
+ position: 'absolute', left: x - 120, top: SLOT_Y + SLOT_H - 80, width: SLOT_W + 240, height: 200, borderRadius: '50%',
207
+ background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha(C.hit, 0.45 * glowA)} 0%, ${alpha(C.hit, 0)} 70%)`,
208
+ }}
209
+ />
210
+ )}
211
+ </React.Fragment>
212
+ );
213
+ })}
214
+
215
+ {/* 三张功能卡 */}
216
+ {HITS_T.map((hit, i) => {
217
+ if (t < hit - 10) return null;
218
+ const y = dropY(t, hit);
219
+ const vy = t < hit ? dropY(t + 0.5, hit) - dropY(t - 0.5, hit) : 0;
220
+ const speed = Math.min(1, vy / 200);
221
+ const s = t - hit;
222
+ const squash = s >= 0 ? 0.07 * Math.exp(-s / 1.6) : 0;
223
+ const sy = 1 + speed * 0.06 - squash;
224
+ const sx = 1 - speed * 0.025 + squash * 0.5;
225
+ const elev = s >= 0 ? 6 : mix(6, 60, (SLOT_Y - y) / (SLOT_Y - DROP_FROM));
226
+ const df = frame - HITS_REAL[i];
227
+ const flash = df >= 0 && df < STOP + 4 ? (df < STOP ? 0.7 : 0.7 * (1 - (df - STOP + 1) / 5)) : 0;
228
+ return (
229
+ <SpeedBlur key={`card-${i}`} vx={0} vy={vy} amount={0.12} max={24}>
230
+ <div style={{ position: 'absolute', left: SLOT_XS[i], top: y, transform: `scale(${sx.toFixed(4)}, ${sy.toFixed(4)})`, transformOrigin: 'bottom center' }}>
231
+ <FeatureCard i={i} elev={elev} saved={ramp(t, hit + 12, 12, EASE.snappy)} />
232
+ {flash > 0 && <div style={{ position: 'absolute', inset: 0, borderRadius: 26, background: '#ffffff', opacity: flash }} />}
233
+ </div>
234
+ </SpeedBlur>
235
+ );
236
+ })}
237
+
238
+ {/* 触地冲击:白色冲击环 + 八向黄色火花(t 驱动,顿帧时冻住) */}
239
+ {HITS_T.map((hit, i) => {
240
+ const s = t - hit;
241
+ if (s < 0 || s > 16) return null;
242
+ const ring = ramp(t, hit, 14, EASE.out);
243
+ const grow = mix(0, 46 + i * 10, ring);
244
+ const x0 = SLOT_XS[i];
245
+ const cx = x0 + SLOT_W / 2;
246
+ const cy = SLOT_Y + SLOT_H / 2;
247
+ const burst = ramp(t, hit, 12, EASE.snappy);
248
+ const n = 10 + i * 3; // 火花逐击加码
249
+ return (
250
+ <React.Fragment key={`fx-${i}`}>
251
+ <div
252
+ style={{
253
+ position: 'absolute', left: x0 - grow, top: SLOT_Y - grow * 0.7, width: SLOT_W + grow * 2, height: SLOT_H + grow * 1.4,
254
+ borderRadius: 26 + grow * 0.6, boxSizing: 'border-box', border: `${mix(5, 1, ring).toFixed(2)}px solid #ffffff`, opacity: (1 - ring) * 0.8,
255
+ }}
256
+ />
257
+ <svg width={1920} height={1080} style={{ position: 'absolute', left: 0, top: 0, overflow: 'visible' }}>
258
+ {Array.from({ length: n }, (_, k) => {
259
+ const ang = (k / n) * Math.PI * 2 + hash(i * 31 + k) * 0.4;
260
+ const rx = SLOT_W * 0.52;
261
+ const ry = SLOT_H * 0.56;
262
+ const r0 = mix(1, 1.08 + hash(k + i * 7) * 0.15, burst);
263
+ const r1 = mix(1.04, 1.3 + hash(k * 3 + i) * 0.35 + i * 0.06, Math.min(1, burst * 1.2));
264
+ return (
265
+ <line
266
+ key={k}
267
+ x1={cx + Math.cos(ang) * rx * r0} y1={cy + Math.sin(ang) * ry * r0}
268
+ x2={cx + Math.cos(ang) * rx * r1} y2={cy + Math.sin(ang) * ry * r1}
269
+ stroke={k % 3 === 0 ? '#ffffff' : C.hit} strokeWidth={mix(7, 2, burst)} strokeLinecap="round"
270
+ opacity={Math.min(1, burst * 6) * (1 - burst)}
271
+ />
272
+ );
273
+ })}
274
+ </svg>
275
+ </React.Fragment>
276
+ );
277
+ })}
278
+
279
+ {/* 伤害数字:黄色斜体 + 漫画式硬投影 */}
280
+ {HITS_T.map((hit, i) => {
281
+ const s = t - hit;
282
+ if (s < 0 || s > 17) return null;
283
+ const scale = mix(1.45, 1, ramp(t, hit, 5, EASE.snappy));
284
+ const rise = mix(0, -150, ramp(t, hit, 16, EASE.out));
285
+ const opacity = s < 4 ? 1 : 1 - ramp(t, hit + 4, 12, EASE.swift);
286
+ return (
287
+ <div
288
+ key={`dmg-${i}`}
289
+ style={{
290
+ // 落点在卡面中下部(打在目标身上),上浮出卡沿:不与右上角计数器抢位置
291
+ position: 'absolute', left: SLOT_XS[i] + SLOT_W / 2, top: SLOT_Y + SLOT_H * 0.62 - DMG_SIZE[i] + rise,
292
+ transform: `translateX(-50%) scale(${scale.toFixed(3)}) skewX(-8deg)`, transformOrigin: 'center bottom', opacity,
293
+ ...type(DMG_SIZE[i], 900), fontStyle: 'italic', letterSpacing: '-0.04em', lineHeight: 1, color: C.hit, whiteSpace: 'nowrap',
294
+ textShadow: `6px 6px 0 ${C.deep}`,
295
+ }}
296
+ >
297
+ {DMG[i]}
298
+ </div>
299
+ );
300
+ })}
301
+
302
+ {/* 右上角 combo 计数器 */}
303
+ <div
304
+ style={{
305
+ position: 'absolute', right: 120, top: 64, width: 400, height: 280,
306
+ transform: `scale(${cScale.toFixed(4)}) rotate(${cRot}deg)`, transformOrigin: '90% 20%',
307
+ display: 'flex', flexDirection: 'column', alignItems: 'flex-end',
308
+ }}
309
+ >
310
+ <div style={{ ...type(26, 800, { caps: true }), letterSpacing: '0.3em', color: count ? '#ffffff' : alpha('#ffffff', 0.4), fontStyle: 'italic' }}>Combo</div>
311
+ <div
312
+ style={{
313
+ ...type(cSize, 900), fontStyle: 'italic', letterSpacing: '-0.05em', lineHeight: 0.9, whiteSpace: 'nowrap',
314
+ color: count ? C.hit : alpha('#ffffff', 0.22), textShadow: count ? `7px 7px 0 ${C.deep}` : 'none',
315
+ transform: `translateY(${(-stamp * 0.14 * cSize).toFixed(1)}px) skewX(-6deg)`, marginTop: 6,
316
+ }}
317
+ >
318
+ ×{count}
319
+ </div>
320
+ <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
321
+ {[0, 1, 2].map((k) => (
322
+ <div key={k} style={{ width: 56, height: 10, borderRadius: 5, background: k < count ? C.hit : alpha('#ffffff', 0.18), boxShadow: k < count ? `3px 3px 0 ${C.deep}` : 'none' }} />
323
+ ))}
324
+ </div>
325
+ </div>
326
+
327
+ {/* 收尾:真实收益 */}
328
+ <div style={{ position: 'absolute', left: 0, right: 0, top: 866, textAlign: 'center' }}>
329
+ <TextReveal
330
+ text="Up to a week back on every promo."
331
+ by="word"
332
+ variant="rise"
333
+ start={HITS_REAL[2] + 14}
334
+ each={18}
335
+ gap={3}
336
+ style={{ ...type(60, 760), letterSpacing: '-0.03em', color: '#ffffff' }}
337
+ unitStyle={(k) => (k === 2 || k === 3 ? { color: C.hit } : {})}
338
+ />
339
+ </div>
340
+
341
+ <Vignette strength={0.42} inner={0.45} color={C.deep} />
342
+ <Grain opacity={0.07} blend="soft-light" />
343
+ </AbsoluteFill>
344
+ );
345
+ };