dsh-drawai 0.3.3 → 0.4.0
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.
- package/LICENSE +4142 -0
- package/README.md +43 -10
- package/lib/audio-media.js +147 -0
- package/lib/audio-service.js +66 -0
- package/lib/canvas-format.js +134 -0
- package/lib/client.js +5283 -223
- package/lib/comfyui-default-workflow.mjs +1825 -0
- package/lib/comfyui-workflow.mjs +426 -0
- package/lib/document-commands.js +12 -0
- package/lib/document-core.js +29 -0
- package/lib/drawing-tasks.js +26 -0
- package/lib/imagegen.mjs +596 -0
- package/lib/index.js +1758 -129
- package/lib/media.js +26 -13
- package/lib/mgstyle-core.js +75 -0
- package/lib/motion/apply.js +180 -0
- package/lib/motion/asset-pack-lock.js +10 -0
- package/lib/motion/asset-pack.js +335 -0
- package/lib/motion/assets.js +290 -0
- package/lib/motion/audio.js +103 -0
- package/lib/motion/audiolevel.js +63 -0
- package/lib/motion/audiomix.js +144 -0
- package/lib/motion/beats.js +337 -0
- package/lib/motion/builtin-assets.js +62 -0
- package/lib/motion/canvas-spec.js +442 -0
- package/lib/motion/capture.js +95 -0
- package/lib/motion/cards.js +80 -0
- package/lib/motion/collect.js +447 -0
- package/lib/motion/delivery.js +112 -0
- package/lib/motion/edge-speech.py +90 -0
- package/lib/motion/entry.jsx +73 -0
- package/lib/motion/export.js +200 -0
- package/lib/motion/ffmpeg.js +42 -0
- package/lib/motion/fonts.js +71 -0
- package/lib/motion/jobs.js +113 -0
- package/lib/motion/json.js +4 -0
- package/lib/motion/media-catalog.js +59 -0
- package/lib/motion/mgstyles/BRIEF-TEMPLATE.md +63 -0
- package/lib/motion/mgstyles/briefs/01-flat-vector.md +104 -0
- package/lib/motion/mgstyles/briefs/02-line-art.md +97 -0
- package/lib/motion/mgstyles/briefs/03-isometric.md +108 -0
- package/lib/motion/mgstyles/briefs/05-cel-boil.md +145 -0
- package/lib/motion/mgstyles/briefs/06-collage.md +149 -0
- package/lib/motion/mgstyles/briefs/07-liquid.md +106 -0
- package/lib/motion/mgstyles/briefs/08-morph.md +111 -0
- package/lib/motion/mgstyles/briefs/09-bauhaus.md +150 -0
- package/lib/motion/mgstyles/briefs/10-synthwave.md +151 -0
- package/lib/motion/mgstyles/briefs/12-aurora-glass.md +147 -0
- package/lib/motion/mgstyles/briefs/18-hanazi.md +140 -0
- package/lib/motion/mgstyles/briefs/19-paperclip.md +156 -0
- package/lib/motion/mgstyles/briefs/20-pixel.md +118 -0
- package/lib/motion/mgstyles/briefs/22-hud.md +118 -0
- package/lib/motion/mgstyles/catalog.d/01-flat-vector.json +34 -0
- package/lib/motion/mgstyles/catalog.d/02-line-art.json +34 -0
- package/lib/motion/mgstyles/catalog.d/03-isometric.json +35 -0
- package/lib/motion/mgstyles/catalog.d/05-cel-boil.json +28 -0
- package/lib/motion/mgstyles/catalog.d/06-collage.json +28 -0
- package/lib/motion/mgstyles/catalog.d/07-liquid.json +28 -0
- package/lib/motion/mgstyles/catalog.d/08-morph.json +28 -0
- package/lib/motion/mgstyles/catalog.d/09-bauhaus.json +28 -0
- package/lib/motion/mgstyles/catalog.d/10-synthwave.json +28 -0
- package/lib/motion/mgstyles/catalog.d/12-aurora-glass.json +28 -0
- package/lib/motion/mgstyles/catalog.d/18-hanazi.json +28 -0
- package/lib/motion/mgstyles/catalog.d/19-paperclip.json +28 -0
- package/lib/motion/mgstyles/catalog.d/20-pixel.json +28 -0
- package/lib/motion/mgstyles/catalog.d/22-hud.json +28 -0
- package/lib/motion/mgstyles/catalog.json +1356 -0
- package/lib/motion/mgstyles/upstream/README.md +147 -0
- package/lib/motion/mgstyles/upstream/README.zh-CN.md +147 -0
- package/lib/motion/mgstyles/upstream/demos/01-flat-vector/cues.json +1 -0
- package/lib/motion/mgstyles/upstream/demos/01-flat-vector/index.html +712 -0
- package/lib/motion/mgstyles/upstream/demos/02-line-art/cues.json +331 -0
- package/lib/motion/mgstyles/upstream/demos/02-line-art/film.js +676 -0
- package/lib/motion/mgstyles/upstream/demos/02-line-art/index.html +18 -0
- package/lib/motion/mgstyles/upstream/demos/02-line-art/tools/dump_timing.mjs +26 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/cues.json +109 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/index.html +25 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/anim.js +82 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/main.js +219 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/night5.js +180 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/render.js +202 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/title.js +167 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/title5.js +294 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/ui.js +141 -0
- package/lib/motion/mgstyles/upstream/demos/03-isometric/js/world.js +1399 -0
- package/lib/motion/mgstyles/upstream/demos/05-cel-boil/cues.json +157 -0
- package/lib/motion/mgstyles/upstream/demos/05-cel-boil/index.html +34 -0
- package/lib/motion/mgstyles/upstream/demos/05-cel-boil/js/engine.js +326 -0
- package/lib/motion/mgstyles/upstream/demos/05-cel-boil/js/scene.js +2036 -0
- package/lib/motion/mgstyles/upstream/demos/06-collage/assets/gen/layout.json +157 -0
- package/lib/motion/mgstyles/upstream/demos/06-collage/cues.json +80 -0
- package/lib/motion/mgstyles/upstream/demos/06-collage/index.html +889 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/cues.json +100 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/index.html +108 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/engine.js +153 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/links.js +64 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/lookdev.js +46 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/scene.js +963 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/shaders.js +647 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/textsdf.js +114 -0
- package/lib/motion/mgstyles/upstream/demos/07-liquid/js/type.js +50 -0
- package/lib/motion/mgstyles/upstream/demos/08-morph/cues.json +131 -0
- package/lib/motion/mgstyles/upstream/demos/08-morph/glyphs.json +1 -0
- package/lib/motion/mgstyles/upstream/demos/08-morph/index.html +901 -0
- package/lib/motion/mgstyles/upstream/demos/09-bauhaus/cues.json +270 -0
- package/lib/motion/mgstyles/upstream/demos/09-bauhaus/film.js +697 -0
- package/lib/motion/mgstyles/upstream/demos/09-bauhaus/index.html +12 -0
- package/lib/motion/mgstyles/upstream/demos/10-synthwave/cues.json +44 -0
- package/lib/motion/mgstyles/upstream/demos/10-synthwave/index.html +1028 -0
- package/lib/motion/mgstyles/upstream/demos/12-aurora-glass/cues.json +67 -0
- package/lib/motion/mgstyles/upstream/demos/12-aurora-glass/index.html +16 -0
- package/lib/motion/mgstyles/upstream/demos/12-aurora-glass/main.js +967 -0
- package/lib/motion/mgstyles/upstream/demos/12-aurora-glass/shaders.js +468 -0
- package/lib/motion/mgstyles/upstream/demos/18-hanazi/cues.json +117 -0
- package/lib/motion/mgstyles/upstream/demos/18-hanazi/index.html +541 -0
- package/lib/motion/mgstyles/upstream/demos/19-paperclip/assets/countries-110m.json +1 -0
- package/lib/motion/mgstyles/upstream/demos/19-paperclip/assets/stickers/meta.json +34 -0
- package/lib/motion/mgstyles/upstream/demos/19-paperclip/cues.json +285 -0
- package/lib/motion/mgstyles/upstream/demos/19-paperclip/index.html +599 -0
- package/lib/motion/mgstyles/upstream/demos/20-pixel/cues.json +42 -0
- package/lib/motion/mgstyles/upstream/demos/20-pixel/film.js +914 -0
- package/lib/motion/mgstyles/upstream/demos/20-pixel/index.html +18 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/cues.json +108 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/index.html +125 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/js/holo.js +275 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/js/hud.js +855 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/js/post.js +150 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/js/util.js +65 -0
- package/lib/motion/mgstyles/upstream/demos/22-hud/js/v5.js +142 -0
- package/lib/motion/mgstyles/upstream/harness/render.mjs +319 -0
- package/lib/motion/mgstyles/upstream/manifest.json +269 -0
- package/lib/motion/mgstyles/upstream/prompts/01-flat-vector.md +98 -0
- package/lib/motion/mgstyles/upstream/prompts/02-line-art.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/03-isometric.md +97 -0
- package/lib/motion/mgstyles/upstream/prompts/05-cel-boil.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/06-collage.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/07-liquid.md +98 -0
- package/lib/motion/mgstyles/upstream/prompts/08-morph.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/09-bauhaus.md +96 -0
- package/lib/motion/mgstyles/upstream/prompts/10-synthwave.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/12-aurora-glass.md +96 -0
- package/lib/motion/mgstyles/upstream/prompts/18-hanazi.md +95 -0
- package/lib/motion/mgstyles/upstream/prompts/19-paperclip.md +96 -0
- package/lib/motion/mgstyles/upstream/prompts/20-pixel.md +96 -0
- package/lib/motion/mgstyles/upstream/prompts/22-hud.md +95 -0
- package/lib/motion/mgstyles/upstream/rubric.md +51 -0
- package/lib/motion/mgstyles/upstream/template.md +36 -0
- package/lib/motion/pixelqa.js +198 -0
- package/lib/motion/preview.js +95 -0
- package/lib/motion/project.js +395 -0
- package/lib/motion/qa.js +290 -0
- package/lib/motion/reference-media.jsx +10 -0
- package/lib/motion/render-settings.js +112 -0
- package/lib/motion/render.js +159 -0
- package/lib/motion/scene-kit.js +183 -0
- package/lib/motion/sfx.js +232 -0
- package/lib/motion/shotcraft/ClipCard.tsx +204 -0
- package/lib/motion/shotcraft/catalog.json +2461 -0
- package/lib/motion/shotcraft/upstream/SKILL.md +286 -0
- package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -0
- package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -0
- package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -0
- package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -0
- package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -0
- package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -0
- package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -0
- package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -0
- package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -0
- package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -0
- package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/__pycache__/sfx-source.cpython-313.pyc +0 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -0
- package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -0
- package/lib/motion/shotcraft/upstream/demos/README.md +120 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -0
- package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -0
- package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +389 -0
- package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -0
- package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -0
- package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -0
- package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -0
- package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -0
- package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -0
- package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -0
- package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -0
- package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -0
- package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -0
- package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -0
- package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -0
- package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -0
- package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -0
- package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -0
- package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -0
- package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -0
- package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -0
- package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -0
- package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -0
- package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -0
- package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -0
- package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -0
- package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -0
- package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -0
- package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -0
- package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -0
- package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -0
- package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -0
- package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -0
- package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -0
- package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -0
- package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -0
- package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -0
- package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -0
- package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -0
- package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -0
- package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -0
- package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -0
- package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -0
- package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -0
- package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -0
- package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -0
- package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -0
- package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -0
- package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -0
- package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -0
- package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -0
- package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -0
- package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -0
- package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -0
- package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -0
- package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -0
- package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -0
- package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -0
- package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -0
- package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -0
- package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -0
- package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -0
- package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -0
- package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -0
- package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -0
- package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -0
- package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -0
- package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -0
- package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -0
- package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -0
- package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -0
- package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -0
- package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -0
- package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -0
- package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -0
- package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -0
- package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -0
- package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -0
- package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -0
- package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -0
- package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -0
- package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -0
- package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -0
- package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -0
- package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -0
- package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -0
- package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -0
- package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -0
- package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -0
- package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -0
- package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -0
- package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -0
- package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -0
- package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -0
- package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -0
- package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -0
- package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -0
- package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -0
- package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -0
- package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -0
- package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -0
- package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -0
- package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -0
- package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -0
- package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -0
- package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -0
- package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -0
- package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -0
- package/lib/motion/shotcraft/upstream/manifest.json +2715 -0
- package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -0
- package/lib/motion/shotcraft/upstream/references/final-review.md +121 -0
- package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -0
- package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -0
- package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -0
- package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -0
- package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -0
- package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -0
- package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -0
- package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -0
- package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -0
- package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -0
- package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -0
- package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -0
- package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -0
- package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -0
- package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -0
- package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -0
- package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -0
- package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -0
- package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -0
- package/lib/motion/shotcraft/upstream/references/workbench.md +157 -0
- package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -0
- package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -0
- package/lib/motion/shotcraft/upstream/template/package.json +20 -0
- package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -0
- package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -0
- package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +389 -0
- package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -0
- package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -0
- package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -0
- package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -0
- package/lib/motion/spec.js +113 -0
- package/lib/motion/style-engine.js +153 -0
- package/lib/motion/style-frames.js +268 -0
- package/lib/motion/sync.js +214 -0
- package/lib/motion/theme.js +121 -0
- package/lib/motion/voice.js +417 -0
- package/lib/motion-agent-files.js +82 -0
- package/lib/motion-agent-protocol.js +66 -0
- package/lib/motion-agent-tools.js +196 -0
- package/lib/motion-agent.js +171 -0
- package/lib/motion-capture.js +92 -0
- package/lib/motion-core.js +238 -0
- package/lib/motion-film-review.js +71 -0
- package/lib/motion-library.js +210 -0
- package/lib/motion-planner.js +254 -0
- package/lib/motion-project.js +80 -0
- package/lib/motion-render-worker.js +145 -0
- package/lib/motion-session.js +32 -0
- package/lib/motion-source.js +49 -0
- package/lib/motion-tasks.js +452 -0
- package/lib/motion-vision.js +43 -0
- package/lib/mxfile.js +27 -7
- package/lib/routing/node-runtime.js +14 -0
- package/lib/routing/router.js +211 -0
- package/lib/routing/vendor/README.md +96 -0
- package/lib/routing/vendor/libavoid-routing.js +753 -0
- package/lib/routing/vendor/libavoid.min.js +59 -0
- package/lib/shotcard-core.js +39 -0
- package/lib/shotcard-reference.js +56 -0
- package/lib/style-kernel.js +37 -3
- package/lib/task-patches.js +26 -2
- package/lib/video-export.js +17 -2
- package/package.json +29 -4
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html><head><meta charset="utf-8">
|
|
3
|
+
<link rel="stylesheet" href="/assets/fonts/fonts.css">
|
|
4
|
+
<style>
|
|
5
|
+
html,body{margin:0;background:#000;overflow:hidden}
|
|
6
|
+
#stage{position:relative;width:1080px;height:1920px;overflow:hidden;background:#1b1b22}
|
|
7
|
+
.shot{position:absolute;left:0;top:0;width:1080px;height:1920px;overflow:hidden;transform-origin:540px 960px}
|
|
8
|
+
.shot img{position:absolute;left:0;top:0;transform-origin:0 0;max-width:none}
|
|
9
|
+
.ear{visibility:hidden}
|
|
10
|
+
#cardwrap{position:absolute;left:0;top:0;width:1080px;height:1920px;transform-origin:0 0}
|
|
11
|
+
#cardborder{position:absolute;background:#fff;border-radius:36px}
|
|
12
|
+
#vig{position:absolute;left:0;top:0;width:1080px;height:1920px;pointer-events:none;
|
|
13
|
+
background:radial-gradient(ellipse 80% 62% at 50% 46%, rgba(0,0,0,0) 58%, rgba(28,8,30,.42) 100%)}
|
|
14
|
+
#flash{position:absolute;left:0;top:0;width:1080px;height:1920px;background:#fff;opacity:0}
|
|
15
|
+
#grain{position:absolute;left:0;top:0;width:1080px;height:1920px;background:url(/assets/textures/grain/grain_fine_2048.png);
|
|
16
|
+
mix-blend-mode:overlay;opacity:.09;pointer-events:none}
|
|
17
|
+
svg{position:absolute;left:0;top:0;overflow:visible}
|
|
18
|
+
#sun{position:absolute;left:0;top:0;width:1080px;height:1920px;mix-blend-mode:screen;background:radial-gradient(circle at 92% 6%, rgba(255,236,170,.85) 0, rgba(255,196,110,.35) 22%, rgba(255,170,90,0) 55%)}
|
|
19
|
+
#cutw{position:absolute;left:0;top:0;width:1080px;height:1920px;transform-origin:540px 1420px}
|
|
20
|
+
</style></head>
|
|
21
|
+
<body>
|
|
22
|
+
<div id="stage">
|
|
23
|
+
<svg id="bg" width="1080" height="1920" viewBox="0 0 1080 1920"></svg>
|
|
24
|
+
<div id="s1" class="shot"><img id="i1" src="/demos/18-hanazi/assets/white_dof.jpg"><img id="e6" class="ear" src="/demos/18-hanazi/assets/white_ear6.png"><img id="e11" class="ear" src="/demos/18-hanazi/assets/white_ear11.png"><img id="e16" class="ear" src="/demos/18-hanazi/assets/white_ear16.png"><div id="sun"></div></div>
|
|
25
|
+
<div id="s2" class="shot"><img id="i2" src="/demos/18-hanazi/assets/grey_r2.jpg"></div>
|
|
26
|
+
<div id="cardwrap">
|
|
27
|
+
<div id="cardborder"></div>
|
|
28
|
+
<div id="s3" class="shot">
|
|
29
|
+
<img id="i3" src="/demos/18-hanazi/assets/tux_r1.jpg"><canvas id="zb" width="1080" height="1920" style="position:absolute;left:0;top:0;filter:saturate(1.2) contrast(1.06)"></canvas>
|
|
30
|
+
<svg id="rays" width="1080" height="1920" viewBox="0 0 1080 1920"></svg>
|
|
31
|
+
<div id="cutw"><img id="hL06" src="/demos/18-hanazi/assets/hero_L06.png"><img id="hL12" src="/demos/18-hanazi/assets/hero_L12.png"><img id="hB0" src="/demos/18-hanazi/assets/hero_B0.png"><img id="hB1" src="/demos/18-hanazi/assets/hero_B1.png"><img id="hB2" src="/demos/18-hanazi/assets/hero_B2.png"><img id="hL135" src="/demos/18-hanazi/assets/hero_L135.png"></div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div id="vig"></div>
|
|
35
|
+
<svg id="fx" width="1080" height="1920" viewBox="0 0 1080 1920"></svg>
|
|
36
|
+
<div id="flash"></div>
|
|
37
|
+
<div id="grain"></div>
|
|
38
|
+
</div>
|
|
39
|
+
<script>
|
|
40
|
+
window.DEMO = { width: 1080, height: 1920, fps: 30, duration: 10, motionBlur: { samples: 1, shutter: 0.5 } };
|
|
41
|
+
const NS = 'http://www.w3.org/2000/svg', FR = 1 / 30;
|
|
42
|
+
const $ = id => document.getElementById(id);
|
|
43
|
+
const clamp = (x, a = 0, b = 1) => x < a ? a : x > b ? b : x;
|
|
44
|
+
const lerp = (a, b, u) => a + (b - a) * u;
|
|
45
|
+
const E = {
|
|
46
|
+
outCubic: u => 1 - Math.pow(1 - u, 3), inCubic: u => u * u * u, outQuart: u => 1 - Math.pow(1 - u, 4),
|
|
47
|
+
inOutCubic: u => u < .5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2, inOutSine: u => -(Math.cos(Math.PI * u) - 1) / 2,
|
|
48
|
+
inSine: u => 1 - Math.cos(u * Math.PI / 2), outExpo: u => u >= 1 ? 1 : 1 - Math.pow(2, -10 * u), outBack: u => 1 + 2.70158 * Math.pow(u - 1, 3) + 1.70158 * Math.pow(u - 1, 2), inQuad: u => u * u, outQuad: u => 1 - (1 - u) * (1 - u),
|
|
49
|
+
};
|
|
50
|
+
// damped spring step: zeta .517 / omega 22 -> peak 1.15 at frame 5, ~1.01 at frame 8
|
|
51
|
+
function spring(t, z = 0.517, w = 22) {
|
|
52
|
+
if (t <= 0) return 0; const wd = w * Math.sqrt(1 - z * z);
|
|
53
|
+
return 1 - Math.exp(-z * w * t) * (Math.cos(wd * t) + z * w / wd * Math.sin(wd * t));
|
|
54
|
+
}
|
|
55
|
+
function h1(i) { let x = Math.imul((i | 0) ^ 0x9e3779b9, 0x85ebca6b); x ^= x >>> 13; x = Math.imul(x, 0xc2b2ae35); x ^= x >>> 16; return (x >>> 0) / 4294967296; }
|
|
56
|
+
function rnd(seed) { let s = seed >>> 0; return () => { s = (s + 0x6D2B79F5) >>> 0; let t = s; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
|
|
57
|
+
function vn(x, seed) { const i = Math.floor(x), f = x - i, u = f * f * (3 - 2 * f); return lerp(h1(i * 7919 + seed * 104729), h1((i + 1) * 7919 + seed * 104729), u) * 2 - 1; }
|
|
58
|
+
function hand(t, seed, a = 1) { return { x: a * (7 * vn(t * .9, seed) + 2.5 * vn(t * 2.3, seed + 11)), y: a * (6 * vn(t * .8, seed + 23) + 2 * vn(t * 2.6, seed + 37)), r: a * .32 * vn(t * .7, seed + 51) }; }
|
|
59
|
+
function kick(t, t0, A, k = 8, f = 12) {
|
|
60
|
+
const u = t - t0; if (u < 0 || u > 1.5) return { x: 0, y: 0, r: 0 }; const e = A * Math.exp(-k * u);
|
|
61
|
+
return { x: e * Math.sin(2 * Math.PI * f * u), y: e * .8 * Math.cos(2 * Math.PI * f * .83 * u + .7), r: e * .03 * Math.sin(2 * Math.PI * f * .6 * u) };
|
|
62
|
+
}
|
|
63
|
+
const addK = (...ks) => ks.reduce((a, k) => ({ x: a.x + k.x, y: a.y + k.y, r: a.r + k.r }), { x: 0, y: 0, r: 0 });
|
|
64
|
+
function el(tag, attrs = {}, parent) { const e = document.createElementNS(NS, tag); for (const k in attrs) e.setAttribute(k, attrs[k]); if (parent) parent.appendChild(e); return e; }
|
|
65
|
+
let gid = 0, DEFS;
|
|
66
|
+
function grad(stops, vertical = true) {
|
|
67
|
+
const id = 'g' + (gid++); const g = el('linearGradient', vertical ? { id, x1: 0, y1: 0, x2: 0, y2: 1 } : { id, x1: 0, y1: 0, x2: 1, y2: 0 }, DEFS);
|
|
68
|
+
stops.forEach(([o, c, a]) => el('stop', { offset: o, 'stop-color': c, 'stop-opacity': a ?? 1 }, g)); return `url(#${id})`;
|
|
69
|
+
}
|
|
70
|
+
const show = (e, v) => e.setAttribute('visibility', v ? 'visible' : 'hidden');
|
|
71
|
+
const disp = (e, v) => { e.style.display = v ? '' : 'none'; }; // hard-hides a whole group (children can't override)
|
|
72
|
+
const X = (e, x, y, r = 0, s = 1, sy) => e.setAttribute('transform', `translate(${x.toFixed(2)} ${y.toFixed(2)}) rotate(${r.toFixed(3)}) scale(${s.toFixed(4)} ${(sy ?? s).toFixed(4)})`);
|
|
73
|
+
|
|
74
|
+
/* ---------- 花字 component: extrude x2 -> outer colour stroke -> white stroke -> gradient fill -> gloss ---------- */
|
|
75
|
+
function HZ(parent, sp) {
|
|
76
|
+
const root = el('g', {}, parent);
|
|
77
|
+
if (sp.soft !== false) root.setAttribute('filter', sp.filter || 'url(#soft)');
|
|
78
|
+
const fillPaint = sp.fillStops ? grad(sp.fillStops) : sp.fill;
|
|
79
|
+
const gloss = sp.gloss ? grad([[0, '#fff', sp.gloss], [0.46, '#fff', 0], [1, '#fff', 0]]) : null;
|
|
80
|
+
const items = sp.chars.map(c => {
|
|
81
|
+
const g = el('g', {}, parent === root ? root : root);
|
|
82
|
+
const inner = el('g', sp.skew ? { transform: `skewX(${sp.skew})` } : {}, g);
|
|
83
|
+
const fs = c.size || sp.size, sc = fs / sp.size;
|
|
84
|
+
const base = { 'font-family': sp.font, 'font-size': fs, 'font-weight': sp.weight || 400, 'text-anchor': sp.anchor || 'middle', 'dominant-baseline': 'central', 'stroke-linejoin': 'round', 'stroke-linecap': 'round' };
|
|
85
|
+
const dy = (sp.dy || 0) * sc, W = 2 * ((sp.white || 0) + (sp.outer || 0)) * sc;
|
|
86
|
+
const mk = a => { const e = el('text', { ...base, ...a }, inner); e.textContent = c.ch; return e; };
|
|
87
|
+
if (sp.ext) { const ec = sp.extColor; mk({ y: dy + sp.ext * sc, x: (sp.extX || 0) * sc, fill: ec, stroke: ec, 'stroke-width': W }); mk({ y: dy + sp.ext * .5 * sc, x: (sp.extX || 0) * .5 * sc, fill: ec, stroke: ec, 'stroke-width': W }); }
|
|
88
|
+
if (sp.outer) mk({ y: dy, fill: sp.outerColor, stroke: sp.outerColor, 'stroke-width': W });
|
|
89
|
+
if (sp.white) mk({ y: dy, fill: sp.whiteColor || '#fff', stroke: sp.whiteColor || '#fff', 'stroke-width': 2 * sp.white * sc });
|
|
90
|
+
const f = mk({ y: dy, fill: c.fillStops ? grad(c.fillStops) : fillPaint });
|
|
91
|
+
if (gloss) mk({ y: dy, fill: gloss });
|
|
92
|
+
return { g, inner, x: c.x, y: c.y, rot: c.rot || 0, fillEl: f, t0: c.t0, drop: c.drop, r0: c.r0, ph: c.ph ?? (c.x * .013), bob: c.bob };
|
|
93
|
+
});
|
|
94
|
+
return { root, items };
|
|
95
|
+
}
|
|
96
|
+
// per-char pop: spring scale 0 -> 1.15 -> 1, drop-in, rotate-in, hold wiggle, optional pop-out at t1
|
|
97
|
+
function charXf(t, c, o = {}) {
|
|
98
|
+
const u = t - c.t0; if (u < 0) return null;
|
|
99
|
+
let s = spring(u, o.z ?? .517, o.w ?? 22);
|
|
100
|
+
let y = -(c.drop ?? o.drop ?? 0) * (1 - spring(u, .55, 20));
|
|
101
|
+
let r = (c.r0 ?? o.r0 ?? 0) * (1 - spring(u, .45, 18));
|
|
102
|
+
const hold = clamp((u - .22) / .35), wf = o.wf ?? 1.15;
|
|
103
|
+
r += hold * (o.wig ?? 1.8) * Math.sin(2 * Math.PI * wf * t + c.ph);
|
|
104
|
+
y += hold * (c.bob ?? o.bob ?? 3) * Math.sin(2 * Math.PI * wf * t + c.ph + 1.9);
|
|
105
|
+
s *= 1 + hold * (o.breath ?? .012) * Math.sin(2 * Math.PI * wf * 2 * t + c.ph * 1.7);
|
|
106
|
+
if (o.t1 != null && t >= o.t1) { const k = clamp((t - o.t1) / .17); if (k >= 1) return null; s *= k < .3 ? 1 + .12 * E.outQuad(k / .3) : 1.12 * (1 - E.inCubic((k - .3) / .7)); }
|
|
107
|
+
return { s, y, r };
|
|
108
|
+
}
|
|
109
|
+
function popOut(t, t1) { if (t < t1) return 1; const k = (t - t1) / .17; return k >= 1 ? 0 : k < .3 ? 1 + .12 * E.outQuad(k / .3) : 1.12 * (1 - E.inCubic((k - .3) / .7)); }
|
|
110
|
+
function driveHZ(t, hz, o = {}, off = { x: 0, y: 0 }) {
|
|
111
|
+
for (const c of hz.items) {
|
|
112
|
+
const f = charXf(t, c, o); if (!f || (o.until != null && t >= o.until) || (o.from != null && t < o.from)) { show(c.g, false); continue; }
|
|
113
|
+
show(c.g, true); X(c.g, c.x + off.x, c.y + f.y + off.y, c.rot + f.r, f.s);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/* ---------- decorations ---------- */
|
|
117
|
+
function sparkleD(r) { const k = r * .16; return `M0 ${-r}Q${k} ${-k} ${r} 0Q${k} ${k} 0 ${r}Q${-k} ${k} ${-r} 0Q${-k} ${-k} 0 ${-r}Z`; }
|
|
118
|
+
function burstD(cx, cy, rx, ry, n, seed, spike = .3) {
|
|
119
|
+
const R = rnd(seed); let d = '';
|
|
120
|
+
for (let i = 0; i < 2 * n; i++) {
|
|
121
|
+
const a = i / (2 * n) * Math.PI * 2 + (R() - .5) * .09, out = i % 2 === 0;
|
|
122
|
+
const k = out ? 1 + (R() - .45) * .26 : (1 - spike) + (R() - .5) * .07;
|
|
123
|
+
d += (i ? 'L' : 'M') + (cx + Math.cos(a) * rx * k).toFixed(1) + ' ' + (cy + Math.sin(a) * ry * k).toFixed(1);
|
|
124
|
+
}
|
|
125
|
+
return d + 'Z';
|
|
126
|
+
}
|
|
127
|
+
function focusD(cx, cy, seed, n = 120) {
|
|
128
|
+
const R = rnd(seed); let d = '';
|
|
129
|
+
for (let i = 0; i < n; i++) {
|
|
130
|
+
const a = i / n * Math.PI * 2 + (R() - .5) * (Math.PI * 2 / n) * .9, w = .0035 + R() * .011, ri = 470 + R() * 260, ro = 1600;
|
|
131
|
+
const p = (ang, rr) => (cx + Math.cos(ang) * rr).toFixed(1) + ' ' + (cy + Math.sin(ang) * rr * 1.18).toFixed(1);
|
|
132
|
+
d += `M${p(a, ri)}L${p(a - w, ro)}L${p(a + w, ro)}Z`;
|
|
133
|
+
}
|
|
134
|
+
return d;
|
|
135
|
+
}
|
|
136
|
+
function raysD(n, R) { let d = ''; for (let i = 0; i < n; i++) { const a0 = i / n * Math.PI * 2, a1 = a0 + Math.PI / n; d += `M0 0L${(Math.cos(a0) * R).toFixed(1)} ${(Math.sin(a0) * R).toFixed(1)}L${(Math.cos(a1) * R).toFixed(1)} ${(Math.sin(a1) * R).toFixed(1)}Z`; } return d; }
|
|
137
|
+
const DROP_D = 'M0 -64C9 -42 36 -12 36 14A36 36 0 0 1 -36 14C-36 -12 -9 -42 0 -64Z';
|
|
138
|
+
const PAW_D = 'M0 10c-20 0-34 14-34 28 0 12 12 16 34 16s34-4 34-16c0-14-14-28-34-28zM-30-4a11 14 0 1 0 .1 0zM30-4a11 14 0 1 0 .1 0zM-12-24a10 13 0 1 0 .1 0zM12-24a10 13 0 1 0 .1 0z';
|
|
139
|
+
|
|
140
|
+
/* ---------- photo plates ---------- */
|
|
141
|
+
const PL = {
|
|
142
|
+
i1: { iw: 1536, ih: 2048, fx: .775, fy: .44 },
|
|
143
|
+
i2: { iw: 3300, ih: 2200, fx: .565, fy: .6 },
|
|
144
|
+
i3: { iw: 2400, ih: 2400, fx: .585, fy: .40 },
|
|
145
|
+
hero: { iw: 1800, ih: 1800 },
|
|
146
|
+
};
|
|
147
|
+
function geom(P, Z, sx, sy, sh, fx = P.fx, fy = P.fy, free = false) {
|
|
148
|
+
const S = Math.max(1080 / P.iw, 1920 / P.ih) * 1.05 * Z, W = P.iw * S, H = P.ih * S, m = 14;
|
|
149
|
+
let x = sx - fx * W, y = sy - fy * H;
|
|
150
|
+
if (!free) { x = clamp(x, 1080 - W + m, -m); y = clamp(y, 1920 - H + m, -m); }
|
|
151
|
+
return { x: x + sh.x, y: y + sh.y, S };
|
|
152
|
+
}
|
|
153
|
+
function place(img, P, Z, sx, sy, sh, fx = P.fx, fy = P.fy, free = false) {
|
|
154
|
+
const g = geom(P, Z, sx, sy, sh, fx, fy, free);
|
|
155
|
+
img.style.width = P.iw + 'px'; img.style.height = P.ih + 'px';
|
|
156
|
+
img.style.transform = `translate(${g.x.toFixed(2)}px,${g.y.toFixed(2)}px) scale(${g.S.toFixed(5)})`;
|
|
157
|
+
}
|
|
158
|
+
const HERO = ['hL06', 'hL12', 'hB0', 'hB1', 'hB2', 'hL135'];
|
|
159
|
+
/* shot-3 plate (pre-drop): creep, 三连推 triple snap push onto the eyes (2-frame outExpo + 1-frame 3 % overshoot), tension creep + ramping shake */
|
|
160
|
+
function plate3(tt) {
|
|
161
|
+
let h = hand(tt, 3, 1), Z = lerp(1.0, 1.08, E.inSine(clamp((tt - C.wipe) / 1.25))), fe = 0;
|
|
162
|
+
C.push.forEach((p, k) => { if (tt >= p) { const u = tt - p, e = E.outExpo(clamp(u / (2 * FR)));
|
|
163
|
+
const last = k === C.push.length - 1, creep = last ? 1 + .16 * u : 1 + .03 * u, os = 1 + .03 * Math.exp(-Math.pow((u - 1.6 * FR) / (.9 * FR), 2));
|
|
164
|
+
Z = lerp(k ? C.pushZ[k - 1] : Z, C.pushZ[k], e) * creep * os; fe = lerp(k / 3, (k + 1) / 3, e); h = addK(h, kick(tt, p, 9 + 4 * k, 14, 13)); } });
|
|
165
|
+
const p3 = C.push[C.push.length - 1];
|
|
166
|
+
if (tt >= p3 + 2 * FR) { const a = lerp(2, 8, clamp((tt - p3 - 2 * FR) / (C.drop - p3 - 2 * FR))), q = Math.floor(tt * 30);
|
|
167
|
+
h = addK(h, { x: (h1(q * 3 + 1) - .5) * 2 * a, y: (h1(q * 3 + 2) - .5) * 2 * a, r: (h1(q * 3 + 3) - .5) * .5 * a / 8 }); }
|
|
168
|
+
const zi = 1 + .09 * (1 - E.outCubic(clamp((tt - C.wipe) / .5)));
|
|
169
|
+
return { g: geom(PL.i3, Z * zi, 540, lerp(760, 800, fe), h, lerp(PL.i3.fx, .578, fe), lerp(PL.i3.fy, .371, fe)), h };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let C, fx, rays, bgPat, B = {};
|
|
173
|
+
async function build() {
|
|
174
|
+
C = await (await fetch('/demos/18-hanazi/cues.json')).json();
|
|
175
|
+
for (const [f, w] of [['Resource Han Rounded', 900], ['Alimama ShuHeiTi', 700], ['Douyin Sans', 700], ['LXGW Marker Gothic', 400], ['ZCOOL KuaiLe', 400], ['Luckiest Guy', 400]])
|
|
176
|
+
await document.fonts.load(`${w} 100px "${f}"`, '今日份快乐?空气突然安静震惊!前方高能这发量合理吗绝子下期见~猫主认证喵呜日记小声正在光作用…()发量检测爆表正常MIAOWU EP.07★');
|
|
177
|
+
await document.fonts.ready;
|
|
178
|
+
const mctx = document.createElement('canvas').getContext('2d');
|
|
179
|
+
fx = $('fx');
|
|
180
|
+
DEFS = el('defs', {}, fx);
|
|
181
|
+
const f1 = el('filter', { id: 'soft', x: '-30%', y: '-30%', width: '160%', height: '175%' }, DEFS);
|
|
182
|
+
el('feDropShadow', { dx: 0, dy: 12, stdDeviation: 11, 'flood-color': '#1a0a28', 'flood-opacity': .36 }, f1);
|
|
183
|
+
const f1b = el('filter', { id: 'soft2', x: '-40%', y: '-30%', width: '180%', height: '175%' }, DEFS);
|
|
184
|
+
el('feDropShadow', { dx: 0, dy: 14, stdDeviation: 14, 'flood-color': '#0B1030', 'flood-opacity': .4 }, f1b);
|
|
185
|
+
const f2 = el('filter', { id: 'glow', x: '-50%', y: '-50%', width: '200%', height: '200%' }, DEFS);
|
|
186
|
+
el('feDropShadow', { dx: 0, dy: 0, stdDeviation: 7, 'flood-color': '#FFE14D', 'flood-opacity': .9 }, f2);
|
|
187
|
+
// stamp grunge: rough edge + speckle knock-outs
|
|
188
|
+
const f3 = el('filter', { id: 'rough', x: '-10%', y: '-10%', width: '120%', height: '120%' }, DEFS);
|
|
189
|
+
el('feTurbulence', { type: 'fractalNoise', baseFrequency: .045, numOctaves: 2, seed: 4, result: 'n' }, f3);
|
|
190
|
+
el('feDisplacementMap', { in: 'SourceGraphic', in2: 'n', scale: 7, xChannelSelector: 'R', yChannelSelector: 'G', result: 'd' }, f3);
|
|
191
|
+
el('feTurbulence', { type: 'fractalNoise', baseFrequency: .11, numOctaves: 3, seed: 9, result: 'sp' }, f3);
|
|
192
|
+
el('feColorMatrix', { in: 'sp', type: 'matrix', values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -18 0 0 0 12.6', result: 'spa' }, f3);
|
|
193
|
+
el('feComposite', { in: 'd', in2: 'spa', operator: 'in' }, f3);
|
|
194
|
+
|
|
195
|
+
/* end board: cyan stripes */
|
|
196
|
+
const bg = $('bg'); const bdefs = el('defs', {}, bg);
|
|
197
|
+
bgPat = el('pattern', { id: 'stripes', width: 92, height: 92, patternUnits: 'userSpaceOnUse' }, bdefs);
|
|
198
|
+
el('rect', { width: 92, height: 92, fill: '#2CCBF2' }, bgPat); el('rect', { width: 46, height: 92, fill: '#56D8F6' }, bgPat);
|
|
199
|
+
const rg = el('radialGradient', { id: 'bgglow', cx: .5, cy: .42, r: .6 }, bdefs);
|
|
200
|
+
el('stop', { offset: 0, 'stop-color': '#fff', 'stop-opacity': .55 }, rg); el('stop', { offset: 1, 'stop-color': '#fff', 'stop-opacity': 0 }, rg);
|
|
201
|
+
el('rect', { width: 1080, height: 1920, fill: 'url(#stripes)' }, bg);
|
|
202
|
+
el('rect', { width: 1080, height: 1920, fill: 'url(#bgglow)' }, bg);
|
|
203
|
+
// dotted confetti on the board
|
|
204
|
+
const Rb = rnd(77);
|
|
205
|
+
for (let i = 0; i < 26; i++) el('circle', { cx: Rb() * 1080, cy: Rb() * 1920, r: 5 + Rb() * 9, fill: ['#FFE14D', '#FF7FC8', '#fff'][i % 3], opacity: .85 }, bg);
|
|
206
|
+
|
|
207
|
+
/* hero rays behind the cut-out cat */
|
|
208
|
+
rays = $('rays'); const rdefs = el('defs', {}, rays);
|
|
209
|
+
const rg2 = el('radialGradient', { id: 'raycore' }, rdefs);
|
|
210
|
+
el('stop', { offset: 0, 'stop-color': '#fff', 'stop-opacity': .95 }, rg2); el('stop', { offset: .55, 'stop-color': '#FFF6C0', 'stop-opacity': .35 }, rg2); el('stop', { offset: 1, 'stop-color': '#FFF6C0', 'stop-opacity': 0 }, rg2);
|
|
211
|
+
el('rect', { width: 1080, height: 1920, fill: '#FFD23F' }, rays);
|
|
212
|
+
B.raysG = el('g', {}, rays); el('path', { d: raysD(20, 2400), fill: '#FF6FA5' }, B.raysG);
|
|
213
|
+
el('circle', { cx: 540, cy: 760, r: 760, fill: 'url(#raycore)' }, rays);
|
|
214
|
+
|
|
215
|
+
/* ---- candy wipe bands (shot 2 -> 3) ---- */
|
|
216
|
+
B.wipe = el('g', {}, fx);
|
|
217
|
+
B.wpat = [];
|
|
218
|
+
{ const pt = el('pattern', { id: 'wp0', width: 128, height: 128, patternUnits: 'userSpaceOnUse' }, DEFS); B.wpat.push(pt);
|
|
219
|
+
el('rect', { width: 128, height: 128, fill: '#2CCBF2' }, pt); el('rect', { width: 58, height: 128, fill: '#FFFFFF' }, pt);
|
|
220
|
+
B.wband = el('g', {}, B.wipe); const BW = 1900, bar = 90, dv = 8;
|
|
221
|
+
el('rect', { x: -BW / 2, y: -1700, width: BW, height: 3400, fill: 'url(#wp0)' }, B.wband);
|
|
222
|
+
for (const sg of [-1, 1]) { let x = BW / 2; // body outward: navy | cyan | navy | lemon | navy | pink | navy edge (all opaque)
|
|
223
|
+
for (const c of ['#2CCBF2', '#FFE14D', '#FF3D7F']) { el('rect', { x: sg > 0 ? x : -x - dv, y: -1700, width: dv, height: 3400, fill: '#1E2A78' }, B.wband); x += dv;
|
|
224
|
+
el('rect', { x: sg > 0 ? x : -x - bar, y: -1700, width: bar, height: 3400, fill: c }, B.wband); x += bar; }
|
|
225
|
+
el('rect', { x: sg > 0 ? x : -x - 14, y: -1700, width: 14, height: 3400, fill: '#1E2A78' }, B.wband); } }
|
|
226
|
+
|
|
227
|
+
/* ---- focus lines + burst (hero) ---- */
|
|
228
|
+
B.focus = el('path', { fill: '#fff', opacity: .92 }, fx);
|
|
229
|
+
B.puff = [[330, 262, -118, 1], [800, 300, -62, 1], [150, 560, -160, 1.1], [936, 590, -20, 1.1], [96, 860, 178, 1], [986, 860, 2, 1], [226, 405, -140, .8], [888, 430, -40, .8]].map(([x, y, a, k], i) => {
|
|
230
|
+
const g = el('g', {}, fx), inner = el('g', {}, g);
|
|
231
|
+
for (const [w, c] of [[24, '#fff'], [11, '#1A1030']]) [-26, 0, 26].forEach((o, j) => el('path', { d: `M0 ${o}Q${34} ${o * 1.25 - 6} ${j === 1 ? 74 : 56} ${o * 1.6}`, fill: 'none', stroke: c, 'stroke-width': w, 'stroke-linecap': 'round' }, inner));
|
|
232
|
+
return { g, x, y, a, k, i }; });
|
|
233
|
+
B.burstBack = el('path', { fill: '#FF3D7F', stroke: '#1A1030', 'stroke-width': 9, 'stroke-linejoin': 'round' }, fx);
|
|
234
|
+
B.burst = el('path', { fill: '#FFF15A', stroke: '#1A1030', 'stroke-width': 10, 'stroke-linejoin': 'round' }, fx);
|
|
235
|
+
|
|
236
|
+
/* ---- SHOT 1 ---- */
|
|
237
|
+
const tx = [196, 368, 540, 712, 884], tdy = [6, -16, 10, -12, 4], tr = [-7, 4, -3, 6, -5];
|
|
238
|
+
B.title = HZ(fx, { font: 'Resource Han Rounded', weight: 900, size: 172, white: 13, outer: 12, outerColor: '#FF3D7F', ext: 16, extColor: '#A3124F', gloss: .55,
|
|
239
|
+
fillStops: [[0, '#FFFBD6'], [.42, '#FFE23A'], [1, '#FF9A1F']],
|
|
240
|
+
chars: [...'今日份快乐'].map((ch, i) => ({ ch, x: tx[i], y: 1515 + tdy[i], rot: tr[i], t0: C.title[i], drop: 90, r0: (i % 2 ? 16 : -16) })) });
|
|
241
|
+
B.sp1 = [[100, 1372, 36, .80], [990, 1395, 26, .867], [948, 1660, 40, .933], [140, 1690, 24, 1.0], [560, 1330, 18, 1.067]].map(([x, y, r, t0]) => ({ x, y, r, t0, e: el('path', { d: sparkleD(r), fill: '#fff', stroke: '#FFD23F', 'stroke-width': 3.5, filter: 'url(#glow)' }, fx) }));
|
|
242
|
+
B.asideG = el('g', {}, fx);
|
|
243
|
+
const aclip = el('clipPath', { id: 'aclip' }, DEFS); B.aclip = [el('rect', { x: 40, y: 330, width: 0, height: 80 }, aclip), el('rect', { x: 40, y: 410, width: 0, height: 100 }, aclip)];
|
|
244
|
+
B.aside = HZ(B.asideG, { font: 'LXGW Marker Gothic', size: 66, white: 0, outer: 7, outerColor: '#5A3A22', ext: 5, extColor: '#3A2412', fill: '#FFFFFF', anchor: 'start',
|
|
245
|
+
chars: [{ ch: '(小声)', x: 70, y: 372, size: 46 }, { ch: '正在光合作用…', x: 92, y: 452 }] });
|
|
246
|
+
B.aside.items[0].fillEl.setAttribute('fill', '#FFE88A');
|
|
247
|
+
B.aside.root.setAttribute('clip-path', 'url(#aclip)');
|
|
248
|
+
mctx.font = '46px "LXGW Marker Gothic"'; B.aw1 = mctx.measureText('(小声)').width; mctx.font = '66px "LXGW Marker Gothic"'; B.aw2 = mctx.measureText('正在光合作用…').width;
|
|
249
|
+
B.aside.items.forEach(c => X(c.g, c.x, c.y));
|
|
250
|
+
/* battery gag: 光合作用 = solar charging */
|
|
251
|
+
B.batt = el('g', { filter: 'url(#soft)' }, fx);
|
|
252
|
+
el('rect', { x: -89, y: -37, width: 180, height: 92, rx: 24, fill: '#0E1440' }, B.batt); el('rect', { x: 91, y: -11, width: 22, height: 40, rx: 7, fill: '#0E1440' }, B.batt);
|
|
253
|
+
el('rect', { x: 84, y: -20, width: 22, height: 40, rx: 7, fill: '#1E2A78' }, B.batt);
|
|
254
|
+
el('rect', { x: -96, y: -46, width: 180, height: 92, rx: 24, fill: '#fff', stroke: '#1E2A78', 'stroke-width': 9 }, B.batt);
|
|
255
|
+
B.bars = [0, 1, 2].map(j => { const g = el('g', {}, B.batt); el('rect', { x: -21, y: -29, width: 42, height: 58, rx: 10, fill: '#7BE35A', stroke: '#1E2A78', 'stroke-width': 4 }, g); el('rect', { x: -13, y: -21, width: 9, height: 28, rx: 4.5, fill: '#fff', opacity: .7 }, g); return g; });
|
|
256
|
+
B.bolt = el('g', {}, B.batt); el('path', { d: 'M10 -44L-24 6L-3 6L-13 44L24 -8L3 -8Z', fill: '#FFE14D', stroke: '#1E2A78', 'stroke-width': 7, 'stroke-linejoin': 'round' }, B.bolt);
|
|
257
|
+
B.battL = el('g', {}, B.batt); ['M112 -62L136 -92', 'M128 -34L164 -46', 'M78 -76L82 -110'].forEach(d => el('path', { d, stroke: '#1E2A78', 'stroke-width': 9, 'stroke-linecap': 'round', fill: 'none' }, B.battL));
|
|
258
|
+
B.battLbl = HZ(fx, { font: 'Douyin Sans', weight: 700, size: 50, white: 0, outer: 7, outerColor: '#1E2A78', ext: 6, extColor: '#0E1440', fill: '#fff',
|
|
259
|
+
chars: [{ ch: '充电中…', x: 222, y: 738, t0: C.battery + 3 * FR, drop: 12 }, { ch: '满电!', x: 214, y: 738, size: 60, t0: C.charge[2] + 2 * FR, drop: 0, r0: -10 }] });
|
|
260
|
+
B.battLbl.items[1].fillEl.setAttribute('fill', '#FFE14D');
|
|
261
|
+
|
|
262
|
+
/* ---- SHOT 2 ---- */
|
|
263
|
+
const qs = [[250, 560, 200, -14, [[0, '#E6FCFF'], [.45, '#3FD8FF'], [1, '#1A86F0']]], [478, 430, 245, 6, [[0, '#FFE6F3'], [.45, '#FF68AE'], [1, '#E0247A']]], [760, 330, 290, 15, [[0, '#FFFBD6'], [.45, '#FFE23A'], [1, '#FF9A1F']]]];
|
|
264
|
+
B.qm = HZ(fx, { font: 'Resource Han Rounded', weight: 900, size: 245, white: 12, outer: 11, outerColor: '#1E2A78', ext: 15, extColor: '#0E1440', gloss: .5,
|
|
265
|
+
chars: qs.map(([x, y, s, r, st], i) => ({ ch: '?', x, y, size: s, rot: r, fillStops: st, t0: C.qmarks[i], drop: 0, r0: -20 })) });
|
|
266
|
+
B.quiet = HZ(fx, { font: 'LXGW Marker Gothic', size: 100, white: 8, outer: 10, outerColor: '#1E2A78', ext: 9, extColor: '#0E1440', skew: -7, filter: 'url(#soft2)', fillStops: [[0, '#FFFFFF'], [1, '#A9C4E0']],
|
|
267
|
+
chars: [...'空气突然安静'].map((ch, i) => ({ ch, x: 150 + [0, 10, -6, 8, -4, 6][i], y: 760 + i * 112, rot: [-5, 3, -2, 4, -3, 2][i], t0: C.quiet[i] })) });
|
|
268
|
+
B.sweat = C.sweat.map((t0, i) => { const g = el('g', {}, fx); el('path', { d: DROP_D, fill: '#8EE8FF', stroke: '#1E2A78', 'stroke-width': 6, 'stroke-linejoin': 'round' }, g); el('ellipse', { cx: -12, cy: 6, rx: 7, ry: 12, fill: '#fff', transform: 'rotate(18 -12 6)' }, g); return { g, t0, x: [880, 968][i], y: [560, 700][i], s: [1.35, 1][i] }; });
|
|
269
|
+
|
|
270
|
+
/* ---- SHOT 3 ---- */
|
|
271
|
+
B.tag = el('g', {}, fx);
|
|
272
|
+
B.tagPill = el('g', {}, B.tag);
|
|
273
|
+
el('rect', { x: -118, y: -26, width: 250, height: 70, rx: 35, fill: '#0E1440' }, B.tagPill);
|
|
274
|
+
el('rect', { x: -125, y: -35, width: 250, height: 70, rx: 35, fill: '#FF3D7F', stroke: '#1E2A78', 'stroke-width': 7 }, B.tagPill);
|
|
275
|
+
{ const e = el('text', { y: 2, 'font-family': 'Douyin Sans', 'font-weight': 700, 'font-size': 40, fill: '#fff', 'text-anchor': 'middle', 'dominant-baseline': 'central', 'letter-spacing': 6 }, B.tagPill); e.textContent = '本期嘉宾'; }
|
|
276
|
+
B.tagName = HZ(B.tag, { font: 'Resource Han Rounded', weight: 900, size: 164, white: 12, outer: 11, outerColor: '#1E2A78', ext: 14, extColor: '#0E1440', gloss: .5,
|
|
277
|
+
fillStops: [[0, '#7FE3FF'], [.5, '#2CCBF2'], [1, '#1E8FE0']],
|
|
278
|
+
chars: [{ ch: '警', x: 178, y: 1214, rot: -4, t0: C.tag[1], drop: 60, r0: -14 }, { ch: '长', x: 342, y: 1206, rot: 4, t0: C.tag[2], drop: 60, r0: 14 }] });
|
|
279
|
+
B.tagRib = el('g', {}, B.tag);
|
|
280
|
+
const ribD = 'M-150 -30L150 -30L138 -18L150 -6L138 6L150 18L150 30L-150 30L-138 18L-150 6L-138 -6L-150 -18Z';
|
|
281
|
+
el('path', { d: ribD, fill: '#0E1440', transform: 'translate(6 8)' }, B.tagRib);
|
|
282
|
+
el('path', { d: ribD, fill: '#FFE14D', stroke: '#1E2A78', 'stroke-width': 5, 'stroke-linejoin': 'round' }, B.tagRib);
|
|
283
|
+
{ const e = el('text', { y: 2, 'font-family': 'LXGW Marker Gothic', 'font-size': 46, fill: '#1E2A78', 'text-anchor': 'middle', 'dominant-baseline': 'central', 'letter-spacing': 4 }, B.tagRib); e.textContent = '发量担当'; }
|
|
284
|
+
|
|
285
|
+
B.warn = el('g', {}, fx);
|
|
286
|
+
el('rect', { x: -420, y: -92, width: 840, height: 184, rx: 26, fill: '#1A1030' }, B.warn);
|
|
287
|
+
el('rect', { x: -408, y: -80, width: 816, height: 160, rx: 18, fill: '#FF2E4D' }, B.warn);
|
|
288
|
+
const hz = el('g', {}, B.warn); const clipR = el('clipPath', { id: 'wclip' }, DEFS); el('rect', { x: -408, y: -80, width: 816, height: 160, rx: 18 }, clipR); hz.setAttribute('clip-path', 'url(#wclip)');
|
|
289
|
+
for (let i = -12; i < 14; i++) { el('path', { d: `M${i * 64} -80l32 0l-26 22l-32 0z`, fill: '#FFE14D' }, hz); el('path', { d: `M${i * 64} 58l32 0l-26 22l-32 0z`, fill: '#FFE14D' }, hz); }
|
|
290
|
+
[-330, 330].forEach(x => { const g = el('g', { transform: `translate(${x} 0)` }, B.warn); el('path', { d: 'M0 -44L42 32L-42 32Z', fill: '#FFE14D', stroke: '#1A1030', 'stroke-width': 7, 'stroke-linejoin': 'round' }, g); el('rect', { x: -5, y: -18, width: 10, height: 30, rx: 4, fill: '#1A1030' }, g); el('circle', { cx: 0, cy: 22, r: 5.5, fill: '#1A1030' }, g); });
|
|
291
|
+
B.warnT = HZ(B.warn, { font: 'Alimama ShuHeiTi', weight: 700, size: 112, white: 0, outer: 7, outerColor: '#1A1030', ext: 7, extColor: '#1A1030', soft: false, fill: '#FFE14D',
|
|
292
|
+
chars: [...'前方高能'].map((ch, i) => ({ ch, x: -168 + i * 112, y: -2 })) });
|
|
293
|
+
B.warnT.items.forEach(c => X(c.g, c.x, c.y));
|
|
294
|
+
B.warnBlink = el('rect', { x: -408, y: -80, width: 816, height: 160, rx: 18, fill: '#fff', opacity: 0 }); B.warn.insertBefore(B.warnBlink, B.warnT.root);
|
|
295
|
+
|
|
296
|
+
const sx = [292, 548, 742, 826];
|
|
297
|
+
B.shock = HZ(fx, { font: 'Alimama ShuHeiTi', weight: 700, size: 250, white: 13, outer: 13, outerColor: '#1A1030', ext: 18, extColor: '#1A1030', extX: 6, skew: -8, gloss: .45,
|
|
298
|
+
fillStops: [[0, '#FF8A8A'], [.5, '#FF1E3C'], [1, '#C4001E']],
|
|
299
|
+
chars: [...'震惊!!'].map((ch, i) => ({ ch, x: sx[i], y: 1318 + [12, -10, -22, -34][i], rot: [-7, -3, 6, 12][i], t0: C.shock[Math.min(i, 2)] + (i === 3 ? FR : 0), drop: 0, r0: [-18, 14, 20, 24][i] })) });
|
|
300
|
+
const sub = [...'这发量合理吗?!']; B.sub = HZ(fx, { font: 'Douyin Sans', weight: 700, size: 92, white: 0, outer: 11, outerColor: '#16B9F0', ext: 10, extColor: '#0F2A6B', whiteColor: '#fff',
|
|
301
|
+
fill: '#FFFFFF', chars: sub.map((ch, i) => ({ ch, x: 540 - 3.3 * 90 + i * 90 + (i === 6 ? 10 : i === 7 ? -24 : 0), y: 1712 + (i % 2 ? -5 : 5), rot: 0, t0: C.subline + i * FR })) });
|
|
302
|
+
B.sub.root.setAttribute('transform', 'rotate(-3 540 1712)');
|
|
303
|
+
/* ---- 发量检测 meter sticker (second beat on the 7.00 brass stab) ---- */
|
|
304
|
+
B.meter = el('g', {}, fx);
|
|
305
|
+
{ const g = B.meter, arcP = (a0, a1, r) => { const p = a => [Math.cos(a) * r, 58 + Math.sin(a) * r], [x0, y0] = p(a0), [x1, y1] = p(a1); return `M${x0.toFixed(1)} ${y0.toFixed(1)}A${r} ${r} 0 0 1 ${x1.toFixed(1)} ${y1.toFixed(1)}`; };
|
|
306
|
+
el('rect', { x: -161, y: -101, width: 340, height: 214, rx: 30, fill: '#1E2A78', opacity: .6 }, g);
|
|
307
|
+
el('rect', { x: -170, y: -112, width: 340, height: 214, rx: 30, fill: '#fff', stroke: '#1E2A78', 'stroke-width': 8 }, g);
|
|
308
|
+
[['#7BE35A', 1, 1.36], ['#FFE14D', 1.36, 1.7], ['#FF2E4D', 1.7, 2]].forEach(([c, a0, a1]) => el('path', { d: arcP(a0 * Math.PI, a1 * Math.PI, 100), fill: 'none', stroke: c, 'stroke-width': 34 }, g));
|
|
309
|
+
el('path', { d: arcP(Math.PI, 2 * Math.PI, 119), fill: 'none', stroke: '#1E2A78', 'stroke-width': 6, 'stroke-linecap': 'round' }, g);
|
|
310
|
+
for (let i = 0; i <= 10; i++) { const a = Math.PI * (1 + i / 10); el('path', { d: `M${(Math.cos(a) * 64).toFixed(1)} ${(58 + Math.sin(a) * 64).toFixed(1)}L${(Math.cos(a) * (i % 5 ? 76 : 82)).toFixed(1)} ${(58 + Math.sin(a) * (i % 5 ? 76 : 82)).toFixed(1)}`, stroke: '#1E2A78', 'stroke-width': i % 5 ? 4 : 6, 'stroke-linecap': 'round' }, g); }
|
|
311
|
+
const lb = (txt, x, c) => { const e = el('text', { x, y: 84, 'font-family': 'Douyin Sans', 'font-weight': 700, 'font-size': 26, fill: c, 'text-anchor': 'middle', 'dominant-baseline': 'central' }, g); e.textContent = txt; };
|
|
312
|
+
lb('正常', -100, '#1E2A78'); lb('爆表', 100, '#E8283C');
|
|
313
|
+
B.needle = el('g', {}, g); el('path', { d: 'M-11 0L0 -104L11 0Z', fill: '#1A1030', stroke: '#1A1030', 'stroke-width': 4, 'stroke-linejoin': 'round' }, B.needle);
|
|
314
|
+
el('circle', { cx: 0, cy: 58, r: 17, fill: '#FF3D7F', stroke: '#1A1030', 'stroke-width': 6 }, g);
|
|
315
|
+
const pill = el('g', { transform: 'translate(-58 -118) rotate(-4)' }, g);
|
|
316
|
+
el('rect', { x: -112, y: -30, width: 224, height: 62, rx: 31, fill: '#FF3D7F', stroke: '#1E2A78', 'stroke-width': 6 }, pill);
|
|
317
|
+
const pt = el('text', { y: 2, 'font-family': 'Douyin Sans', 'font-weight': 700, 'font-size': 40, fill: '#fff', 'text-anchor': 'middle', 'dominant-baseline': 'central', 'letter-spacing': 4 }, pill); pt.textContent = '发量检测'; }
|
|
318
|
+
B.bao = HZ(fx, { font: 'Alimama ShuHeiTi', weight: 700, size: 104, white: 10, outer: 9, outerColor: '#1A1030', ext: 11, extColor: '#1A1030', skew: -8, gloss: .45,
|
|
319
|
+
fillStops: [[0, '#FFF3A0'], [.5, '#FFE14D'], [1, '#FF9A1F']],
|
|
320
|
+
chars: [...'爆表!'].map((ch, i) => ({ ch, x: 796 + i * 92 - (i === 2 ? 22 : 0), y: 528 + [0, -12, -22][i], rot: [6, 10, 14][i], t0: C.bao + i * FR, drop: 0, r0: [-16, 14, 22][i] })) });
|
|
321
|
+
|
|
322
|
+
/* ---- END CARD ---- */
|
|
323
|
+
B.sp2 = [[118, 1228, 46, 8.13], [966, 1270, 36, 8.197], [1004, 1560, 28, 8.263], [80, 1580, 32, 8.33], [960, 410, 42, 8.6], [128, 470, 28, 8.667], [540, 300, 22, 8.733]].map(([x, y, r, t0]) => ({ x, y, r, t0, e: el('path', { d: sparkleD(r), fill: '#fff', stroke: '#FFD23F', 'stroke-width': 3.5, filter: 'url(#glow)' }, fx) }));
|
|
324
|
+
B.jue = HZ(fx, { font: 'Douyin Sans', weight: 700, size: 250, white: 16, outer: 13, outerColor: '#4A1A8C', ext: 18, extColor: '#2A0B5A', gloss: .55,
|
|
325
|
+
fillStops: [[0, '#FFF0FA'], [.45, '#FF7FC8'], [1, '#B04CFF']],
|
|
326
|
+
chars: [...'绝绝子'].map((ch, i) => ({ ch, x: [282, 540, 798][i], y: 1400 + [14, -16, 8][i], rot: [-9, 3, 10][i], t0: C.jue[i], drop: 110, r0: [-20, 16, 22][i] })) });
|
|
327
|
+
B.bye = HZ(fx, { font: 'Douyin Sans', weight: 700, size: 168, white: 12, outer: 11, outerColor: '#FF3D7F', ext: 15, extColor: '#A3124F', gloss: .5,
|
|
328
|
+
fillStops: [[0, '#FFE14D'], [1, '#FF9A1F']],
|
|
329
|
+
chars: [...'下期见~'].map((ch, i) => ({ ch, x: 290 + i * 166 + (i === 3 ? -14 : 0), y: 1722, rot: [-5, 3, -4, 7][i], t0: C.bye + i * 2 * FR, drop: 60, r0: [-14, 10, -10, 18][i], bob: i === 3 ? 14 : undefined })) });
|
|
330
|
+
// stamp 猫主子认证
|
|
331
|
+
B.stamp = el('g', {}, fx); const st = el('g', { filter: 'url(#rough)' }, B.stamp);
|
|
332
|
+
el('circle', { r: 150, fill: '#E8283C' }, st); el('circle', { r: 131, fill: 'none', stroke: '#fff', 'stroke-width': 5 }, st); el('circle', { r: 94, fill: 'none', stroke: '#fff', 'stroke-width': 3 }, st);
|
|
333
|
+
const arc = el('path', { id: 'arcT', d: 'M-112 0A112 112 0 0 1 112 0', fill: 'none' }, DEFS); const arc2 = el('path', { id: 'arcB', d: 'M-112 0A112 112 0 0 0 112 0', fill: 'none' }, DEFS);
|
|
334
|
+
const tp = (id, txt, dy) => { const tt = el('text', { 'font-family': 'Luckiest Guy', 'font-size': 29, fill: '#fff', 'letter-spacing': 3, dy }, st); const p = el('textPath', { href: '#' + id, startOffset: '50%', 'text-anchor': 'middle' }, tt); p.textContent = txt; };
|
|
335
|
+
tp('arcT', 'MIAOWU DIARY', 10); tp('arcB', '★ OFFICIAL ★', 22);
|
|
336
|
+
const t1 = el('text', { 'font-family': 'Alimama ShuHeiTi', 'font-weight': 700, 'font-size': 58, fill: '#fff', 'text-anchor': 'middle', 'dominant-baseline': 'central', y: -26 }, st); t1.textContent = '猫主子';
|
|
337
|
+
const t2 = el('text', { 'font-family': 'Alimama ShuHeiTi', 'font-weight': 700, 'font-size': 70, fill: '#fff', 'text-anchor': 'middle', 'dominant-baseline': 'central', y: 40, 'letter-spacing': 8 }, st); t2.textContent = '认证';
|
|
338
|
+
|
|
339
|
+
/* ---- program badge (persistent) ---- */
|
|
340
|
+
B.badgeArt = el('g', { id: 'badgeArt' }, DEFS); B.badge = el('g', {}, fx); B.bcl = Array.from({ length: 48 }, () => el('use', { href: '#badgeArt' }, B.badge));
|
|
341
|
+
el('path', { d: 'M24 18L44 -16L66 18Z M170 18L192 -16L212 18Z', fill: '#FFE14D', stroke: '#1E2A78', 'stroke-width': 7, 'stroke-linejoin': 'round' }, B.badgeArt);
|
|
342
|
+
el('rect', { x: 0, y: 8, width: 236, height: 86, rx: 30, fill: '#FFE14D', stroke: '#1E2A78', 'stroke-width': 7 }, B.badgeArt);
|
|
343
|
+
const bt = el('text', { x: 118, y: 53, 'font-family': 'ZCOOL KuaiLe', 'font-size': 52, fill: '#1E2A78', 'text-anchor': 'middle', 'dominant-baseline': 'central' }, B.badgeArt); bt.textContent = '喵呜日记';
|
|
344
|
+
const tag = el('g', { transform: 'translate(250 34) rotate(8)' }, B.badgeArt);
|
|
345
|
+
el('rect', { x: 0, y: 0, width: 108, height: 50, rx: 14, fill: '#FF3D7F', stroke: '#1E2A78', 'stroke-width': 6 }, tag);
|
|
346
|
+
const tg = el('text', { x: 54, y: 28, 'font-family': 'Luckiest Guy', 'font-size': 32, fill: '#fff', 'text-anchor': 'middle', 'dominant-baseline': 'central' }, tag); tg.textContent = 'EP.07';
|
|
347
|
+
|
|
348
|
+
fx.appendChild(B.wipe); fx.appendChild(B.badge); // wipe covers captions; program badge stays on top
|
|
349
|
+
await Promise.all(['i1', 'e6', 'e11', 'e16', 'i2', 'i3', ...HERO].map(id => $(id).decode()));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* ---------- frame ---------- */
|
|
353
|
+
window.renderAt = async (t) => {
|
|
354
|
+
{ const tf = Math.round(t * 30) / 30; // cut frames must be weight 0 or 1: no sub-sample may straddle a cut
|
|
355
|
+
for (const c of [C.scratch, C.drop, C.freeze]) { if (tf >= c - 1e-6 && t < c) t = c; else if (tf < c - 1e-6 && t >= c) t = c - 1e-4; } }
|
|
356
|
+
const fN = Math.round(t * 30), HOLD = C.freeze_hold, TPOP = C.freeze + HOLD, TOUT = C.freeze + 4 * FR;
|
|
357
|
+
const s1 = $('s1'), s2 = $('s2'), s3 = $('s3'), cw = $('cardwrap');
|
|
358
|
+
const inS1 = t < C.scratch, inS2 = t >= C.scratch && t < C.wipe, inS3 = t >= C.wipe;
|
|
359
|
+
s1.style.visibility = inS1 ? 'visible' : 'hidden';
|
|
360
|
+
s2.style.visibility = inS2 ? 'visible' : 'hidden';
|
|
361
|
+
cw.style.visibility = inS3 ? 'visible' : 'hidden';
|
|
362
|
+
$('bg').style.visibility = t >= C.freeze ? 'visible' : 'hidden';
|
|
363
|
+
const K6 = kick(t, C.drop, 26, 7, 11), K3 = kick(t, C.punch2, 10, 10, 13), K25 = kick(t, C.scratch, 12, 12, 14), K85 = kick(t, C.stamp, 14, 10, 13);
|
|
364
|
+
|
|
365
|
+
/* shot 1: sunbathing, slow push */
|
|
366
|
+
if (inS1) {
|
|
367
|
+
const up = t - C.charge[2], pz = up < 0 ? 0 : up < 2 * FR ? E.outQuad(up / (2 * FR)) : Math.exp(-(up - 2 * FR) * 6);
|
|
368
|
+
const h = addK(hand(t, 1, .8), kick(t, C.charge[2], 7, 12, 14)), Z = lerp(1.02, 1.1, E.inOutSine(clamp(t / 2.5))) * (1 + .15 * (1 - E.outExpo(clamp(t / (4 * FR))))) * (1 + .06 * pz);
|
|
369
|
+
place($('i1'), PL.i1, Z, 640, 900, h); $('sun').style.opacity = (.6 + .1 * Math.sin(t * 2.1)).toFixed(3); s1.style.transform = `rotate(${h.r}deg)`;
|
|
370
|
+
$('i1').style.filter = 'saturate(1.22) contrast(1.06) brightness(1.05)';
|
|
371
|
+
/* ear flick on the squeak (4 frames: 11/16/11/6 deg overlay sprites, same placement as #i1) */
|
|
372
|
+
const ef = fN - Math.round(C.ear * 30), ek = ef >= 0 && ef < 4 ? ['e11', 'e16', 'e11', 'e6'][ef] : '';
|
|
373
|
+
for (const id of ['e6', 'e11', 'e16']) { const on = id === ek; $(id).style.visibility = on ? 'visible' : 'hidden';
|
|
374
|
+
if (on) { place($(id), PL.i1, Z, 640, 900, h); $(id).style.filter = $('i1').style.filter; } }
|
|
375
|
+
} else for (const id of ['e6', 'e11', 'e16']) $(id).style.visibility = 'hidden';
|
|
376
|
+
/* shot 2: side-eye; snap settle on the cut, punch-in on the eyes at 3.0 */
|
|
377
|
+
if (inS2) {
|
|
378
|
+
const h = addK(hand(t, 2, 1), K25, K3);
|
|
379
|
+
const zc = 1 + .1 * Math.exp(-(t - C.scratch) * 14);
|
|
380
|
+
const zp = t < C.punch2 ? 0 : E.outQuart(clamp((t - C.punch2) / (4 * FR)));
|
|
381
|
+
const Z = zc * lerp(1.0, 1.36, zp) * (1 + .015 * (t - C.scratch));
|
|
382
|
+
place($('i2'), PL.i2, Z, lerp(540, 600, zp), lerp(1080, 1010, zp), h, lerp(PL.i2.fx, .64, zp), lerp(.6, .58, zp)); // punch into ONE staring eye s2.style.transform = `rotate(${h.r}deg)`;
|
|
383
|
+
$('i2').style.filter = 'saturate(1.08) contrast(1.08)';
|
|
384
|
+
}
|
|
385
|
+
/* shot 3: creep, anticipation pull-back, SNAP punch-in at the drop, freeze at 7.5 */
|
|
386
|
+
if (inS3) {
|
|
387
|
+
const tt = Math.min(t, C.freeze), hero = tt >= C.drop, zb = $('zb'), i3 = $('i3');
|
|
388
|
+
let h;
|
|
389
|
+
if (!hero) { // radial zoom-blur on snap frames: 16 in-page sub-samples of the frame's shutter, identical for every harness sample (no stepped copies)
|
|
390
|
+
const tf = Math.min(fN * FR, C.drop - 1e-4), a = plate3(tf - .25 * FR), b = plate3(Math.min(tf + .25 * FR, C.drop - 1e-4));
|
|
391
|
+
const P = plate3(tt); h = P.h;
|
|
392
|
+
if (Math.abs(b.g.S / a.g.S - 1) > .035) {
|
|
393
|
+
const cx = zb.getContext('2d'); cx.setTransform(1, 0, 0, 1, 0, 0); cx.clearRect(0, 0, 1080, 1920); const n = 16;
|
|
394
|
+
for (let i = 0; i < n; i++) { const g = plate3(Math.min(tf + (i / (n - 1) - .5) * .5 * FR, C.drop - 1e-4)).g; cx.globalAlpha = 1 / (i + 1); cx.drawImage(i3, g.x, g.y, PL.i3.iw * g.S, PL.i3.ih * g.S); }
|
|
395
|
+
zb.style.visibility = 'visible'; i3.style.visibility = 'hidden'; h = plate3(tf).h;
|
|
396
|
+
} else { zb.style.visibility = 'hidden'; i3.style.visibility = 'inherit';
|
|
397
|
+
i3.style.width = PL.i3.iw + 'px'; i3.style.height = PL.i3.ih + 'px'; i3.style.transform = `translate(${P.g.x.toFixed(2)}px,${P.g.y.toFixed(2)}px) scale(${P.g.S.toFixed(5)})`; }
|
|
398
|
+
} else { h = addK(hand(tt, 3, 1.3), kick(tt, C.drop, 26, 7, 11), kick(tt, C.meter, 14, 9, 13)); zb.style.visibility = 'hidden'; }
|
|
399
|
+
s3.style.transform = `rotate(${h.r}deg)`;
|
|
400
|
+
i3.style.filter = 'saturate(1.2) contrast(1.06)';
|
|
401
|
+
rays.style.visibility = hero ? 'visible' : 'hidden'; disp($('cutw'), hero);
|
|
402
|
+
if (hero) { const u = tt - C.drop, Zc = lerp(.8, .86, E.outCubic(clamp(u / 1.5))), fq = Math.round(tt * 30), fd = fq - Math.round(C.drop * 30), fm = fq - Math.round(C.meter * 30);
|
|
403
|
+
// 炸毛 sprites: grow 0.6 -> 1.2 overshoot -> boiled 1.0 (3 drawings @12 fps); the 7.00 re-hit puffs to 1.35
|
|
404
|
+
const pick = fm >= 0 && fm < 2 ? 'hL135' : (fm >= 2 && fm < 4) || (fd >= 2 && fd < 4) ? 'hL12' : fd < 2 ? 'hL06' : 'hB' + (Math.floor(tt * 12) % 3);
|
|
405
|
+
for (const id of HERO) { const on = id === pick; $(id).style.visibility = on ? 'visible' : 'hidden'; if (on) place($(id), PL.hero, Zc, 540, 880, h, .53, .51, true); }
|
|
406
|
+
const um = tt - C.meter, q = um >= 0 ? .06 * Math.exp(-um * 9) * Math.cos(um * 26) : 0, pop = 1 + .05 * Math.exp(-Math.max(0, u - FR) * 14);
|
|
407
|
+
$('cutw').style.transform = `scale(${(pop * (1 + q)).toFixed(4)},${(pop * (1 - .7 * q)).toFixed(4)})`; }
|
|
408
|
+
B.raysG.setAttribute('transform', `translate(540 760) rotate(${(8 + (tt - C.drop) * 14).toFixed(2)})`);
|
|
409
|
+
// freeze -> card
|
|
410
|
+
const uf = t - C.freeze, uh = (uf - HOLD) / (11 * FR);
|
|
411
|
+
const p = uf < HOLD ? 0 : uh < 1 ? E.inOutSine(uh) : 1 + .035 * Math.exp(-(uh - 1) * 2.2) * Math.sin((uh - 1) * 4.4), e = clamp(p, 0, 1.06);
|
|
412
|
+
const zf = uf >= 0 ? lerp(1, 1.03, E.outCubic(clamp(uf / HOLD))) : 1;
|
|
413
|
+
s3.style.filter = uf >= 0 ? `saturate(${lerp(.7, 1, clamp(p)).toFixed(3)})` : 'none';
|
|
414
|
+
const sc = lerp(zf, .72, p), rot = lerp(0, -4, p) + (t >= C.stamp ? K85.r * 12 : 0), ty = lerp(0, -40, p);
|
|
415
|
+
const kx = t >= C.stamp ? K85.x : 0, ky = t >= C.stamp ? K85.y : 0;
|
|
416
|
+
cw.style.transform = `translate(${kx}px,${ty + ky}px) translate(540px,960px) rotate(${rot}deg) scale(${sc}) translate(-540px,-960px)`;
|
|
417
|
+
const T = 190 * e, Bm = 560 * e, L = 70 * e, b = 30 * e;
|
|
418
|
+
s3.style.clipPath = p > 0 ? `inset(${T}px ${L}px ${Bm}px ${L}px round ${30 * e}px)` : 'none';
|
|
419
|
+
const cb = $('cardborder'); cb.style.display = p > 0 ? 'block' : 'none';
|
|
420
|
+
Object.assign(cb.style, { left: (L - b) + 'px', top: (T - b) + 'px', width: (1080 - 2 * L + 2 * b) + 'px', height: (1920 - T - Bm + 2 * b) + 'px', boxShadow: `0 ${34 * e}px ${60 * e}px rgba(8,40,70,${.4 * e})` });
|
|
421
|
+
}
|
|
422
|
+
bgPat.setAttribute('patternTransform', `rotate(-35) translate(${(t * 36) % 92} 0)`);
|
|
423
|
+
|
|
424
|
+
/* fx layer follows impacts */
|
|
425
|
+
const FK = t >= C.drop && t < C.freeze ? K6 : inS2 ? addK(K25, K3) : { x: 0, y: 0, r: 0 };
|
|
426
|
+
const off = { x: FK.x * .6, y: FK.y * .6 };
|
|
427
|
+
|
|
428
|
+
// title + sparkles (shot 1)
|
|
429
|
+
for (const [i, c] of B.title.items.entries()) { // pop-in, then a squash-and-hop wave on each quarter beat
|
|
430
|
+
const f = charXf(t, c, { wig: 2.2, bob: 4 }); if (!f || t >= C.scratch) { show(c.g, false); continue; } show(c.g, true);
|
|
431
|
+
let hy = 0, sq = 0;
|
|
432
|
+
for (const b of C.title_beats) { const u = t - b - i * 2 * FR, air = .24;
|
|
433
|
+
if (u > -.07 && u < 0) sq += .11 * (u + .07) / .07;
|
|
434
|
+
else if (u >= 0 && u < air) { const k = u / air; hy += 40 * 4 * k * (1 - k); sq += (k < .15 ? .11 * (1 - k / .15) : 0) - .07 * Math.sin(Math.PI * k); }
|
|
435
|
+
else if (u >= air && u < air + .16) { const w = (u - air) / .16; sq += .13 * Math.exp(-w * 3) * Math.cos(w * 7.5); } }
|
|
436
|
+
X(c.g, c.x + off.x, c.y + f.y - hy + off.y + 60 * sq, c.rot + f.r, f.s * (1 + sq), f.s * (1 - sq));
|
|
437
|
+
}
|
|
438
|
+
{ const u = t - C.battery, v = u >= 0 && t < C.scratch; disp(B.batt, v); disp(B.battLbl.root, v);
|
|
439
|
+
if (v) { const full = t - C.charge[2]; let s = spring(u, .5, 22), sy = s;
|
|
440
|
+
if (full >= 0) { const w = Math.exp(-full * 9) * Math.sin(full * 40); s *= 1 + .13 * w; sy *= 1 - .13 * w; }
|
|
441
|
+
for (const [j, b] of B.bars.entries()) { const ub = t - C.charge[j]; show(b, ub >= 0); if (ub >= 0) { const k = spring(ub, .5, 28); X(b, -54 + j * 52, 29 - 29 * k, 0, 1, k); } }
|
|
442
|
+
X(B.bolt, -92, -40, -14 + 8 * Math.sin(2 * Math.PI * 2.2 * t), .9 + .1 * Math.sin(2 * Math.PI * 4.4 * t));
|
|
443
|
+
show(B.battL, full >= 0); if (full >= 0) B.battL.setAttribute('transform', `scale(${spring(full, .45, 26).toFixed(3)})`);
|
|
444
|
+
X(B.batt, 222 + off.x, 622 + 3 * Math.sin(2 * Math.PI * 1.1 * t) + off.y, lerp(-16, -5, spring(u, .45, 18)) + 1.6 * Math.sin(2 * Math.PI * .9 * t), s, sy); }
|
|
445
|
+
for (const [j, c] of B.battLbl.items.entries()) { const f = charXf(t, c, { wig: 1.2, bob: 2 }), vis = f && t < (j ? C.scratch : C.charge[2]); show(c.g, !!vis); if (vis) X(c.g, c.x + off.x, c.y + f.y + off.y, c.rot + f.r, f.s); } }
|
|
446
|
+
for (const sp of B.sp1) { const u = t - sp.t0; const v = u >= 0 && t < C.scratch; show(sp.e, v); if (v) X(sp.e, sp.x, sp.y, u * 40 + sp.x, spring(u, .4, 26) * (.8 + .2 * Math.sin(2 * Math.PI * 1.8 * t + sp.x))); }
|
|
447
|
+
{ const u = t - C.aside, v = u >= 0 && t < C.scratch; show(B.asideG, v);
|
|
448
|
+
if (v) { const n = Math.floor(u * 30) + 1, k1 = clamp(n / 4), k2 = clamp((n - 4) / 7);
|
|
449
|
+
B.aclip[0].setAttribute('width', (k1 * (B.aw1 + 40)).toFixed(1)); B.aclip[1].setAttribute('width', (k2 * (B.aw2 + 70)).toFixed(1));
|
|
450
|
+
const s = .92 + .08 * spring(u, .6, 22), w = Math.sin(2 * Math.PI * .7 * t) * .8;
|
|
451
|
+
B.asideG.setAttribute('transform', `translate(${off.x} ${off.y}) rotate(${-4 + w} 300 420) translate(300 420) scale(${s}) translate(-300 -420)`); } }
|
|
452
|
+
|
|
453
|
+
// ??? hop on the beat
|
|
454
|
+
for (const [i, c] of B.qm.items.entries()) {
|
|
455
|
+
const f = charXf(t, c, { wig: 0, bob: 0 }); if (!f || t >= C.wipe) { show(c.g, false); continue; } show(c.g, true);
|
|
456
|
+
const u = t - c.t0, ph = ((t - 2.75 - i * .083) / .5 % 1 + 1) % 1, on = clamp((u - .2) / .15);
|
|
457
|
+
const hop = on * 46 * 4 * ph * (1 - ph), sq = on * Math.exp(-Math.pow(Math.min(ph, 1 - ph) / .07, 2));
|
|
458
|
+
X(c.g, c.x + off.x, c.y - hop + off.y, c.rot + f.r + on * 5 * Math.sin(2 * Math.PI * ph), f.s * (1 + .12 * sq), f.s * (1 - .14 * sq));
|
|
459
|
+
}
|
|
460
|
+
driveHZ(t, B.quiet, { until: C.wipe, z: .82, w: 34, wig: .6, bob: 1, wf: .6 }, off);
|
|
461
|
+
for (const d of B.sweat) {
|
|
462
|
+
const u = t - d.t0, v = u >= 0 && t < C.wipe; show(d.g, v); if (!v) continue;
|
|
463
|
+
const s = spring(u, .5, 24) * d.s, slide = 74 * E.inQuad(clamp((u - .15) / .75));
|
|
464
|
+
d.g.setAttribute('opacity', (1 - clamp((u - .75) / .2)).toFixed(3));
|
|
465
|
+
X(d.g, d.x + off.x, d.y + slide + off.y, 12, s * (1 - .05 * clamp(slide / 74)), s * (1 + .12 * clamp(slide / 74)));
|
|
466
|
+
}
|
|
467
|
+
// candy wipe
|
|
468
|
+
{ const tw = fN * FR, u = (tw - (C.wipe - .23)) / .46, v = u > 0 && u < 1; show(B.wipe, v); // frame-quantised: crisp opaque graphic band, no translucent blur
|
|
469
|
+
if (v) { const c = lerp(2400, -2400, E.inOutSine(u)); B.wipe.setAttribute('transform', 'translate(540 960) rotate(-20)'); B.wband.setAttribute('transform', `translate(${c.toFixed(1)} 0)`);
|
|
470
|
+
B.wpat[0].setAttribute('patternTransform', `rotate(50) translate(${((tw * 30 * 60) % 128).toFixed(1)} 0)`); } }
|
|
471
|
+
// 嘉宾 name tag: slides in after the wipe, gets knocked by the banner slam, pops out to clear the stage before the drop
|
|
472
|
+
{ const v = t >= C.tag[0] && t < C.tagOut + .2; disp(B.tag, v);
|
|
473
|
+
if (v) { const fl = t >= C.warn ? E.outBack(clamp((t - C.warn) / (4 * FR))) : 0, ud = t - C.warn - 4 * FR, sw = ud > 0 ? 6 * Math.exp(-ud * 5) * Math.sin(ud * 17) : 0;
|
|
474
|
+
B.tag.setAttribute('transform', `translate(0 ${(-60 * fl).toFixed(2)}) rotate(${(-12 * fl + sw).toFixed(3)} 110 1180)`);
|
|
475
|
+
const K = { x: 0, y: 0, r: 0 }, tOut = C.tagOut, out = t >= tOut ? clamp((t - tOut) / .17) : 0;
|
|
476
|
+
const oS = out <= 0 ? 1 : out < .3 ? 1 + .12 * E.outQuad(out / .3) : 1.12 * (1 - E.inCubic((out - .3) / .7)), u0 = t - C.tag[0];
|
|
477
|
+
X(B.tagPill, 215 - 260 * (1 - spring(u0, .62, 20)) + K.x, 1085 + K.y + 2 * Math.sin(2 * Math.PI * 1.1 * t + .5), -4 + 1.5 * Math.sin(2 * Math.PI * .9 * t) + K.r * 10, spring(u0, .5, 22) * oS);
|
|
478
|
+
for (const c of B.tagName.items) { const f = charXf(t, c, { wig: 2, bob: 3, t1: tOut + FR }); show(c.g, !!f); if (f) X(c.g, c.x + K.x, c.y + f.y + K.y, c.rot + f.r + K.r * 10, f.s); }
|
|
479
|
+
const ur = t - C.tag[3]; show(B.tagRib, ur >= 0);
|
|
480
|
+
if (ur >= 0) { const k = ur < .1 ? lerp(1.7, 1, E.inQuad(ur / .1)) : 1 - .06 * Math.exp(-(ur - .1) * 16) * Math.cos((ur - .1) * 44);
|
|
481
|
+
B.tagRib.setAttribute('opacity', clamp(ur / .05).toFixed(3));
|
|
482
|
+
X(B.tagRib, 330 + K.x, 1322 + K.y, -6 - (ur < .1 ? 8 * (1 - ur / .1) : 0) + Math.sin(2 * Math.PI * .8 * t) + K.r * 10, k * oS); } } }
|
|
483
|
+
// warning banner
|
|
484
|
+
{ const u = t - C.warn, v = u >= 0 && t < C.drop; show(B.warn, v);
|
|
485
|
+
if (v) { const s = lerp(1.7, 1, spring(u, .5, 24)), r = lerp(-14, -5, spring(u, .45, 20)), jit = t > C.push[0] ? (h1(Math.floor(t * 15)) - .5) * 14 : 0;
|
|
486
|
+
X(B.warn, 540 + jit, 1470 + (t > C.push[0] ? (h1(Math.floor(t * 15) + 99) - .5) * 8 : 0), r, s);
|
|
487
|
+
const bl = C.warn_beeps.concat(C.push).some(b => t >= b && t < b + 2 * FR); B.warnBlink.setAttribute('opacity', bl ? .55 : 0); } }
|
|
488
|
+
// hero: focus lines, burst, 震惊!!, subline
|
|
489
|
+
{ const hero = t >= C.drop && t < TOUT + .17, boil = Math.floor(Math.min(t, C.freeze) * 12) % 3, po = popOut(t, TOUT);
|
|
490
|
+
const fm = fN - Math.round(C.meter * 30), rh = fm >= 0 && fm < 3 ? [[10, -5], [-10, 6], [6, -3]][fm] : [0, 0]; // 3-frame re-hit shake on the 7.00 stab
|
|
491
|
+
const offH = { x: off.x + rh[0], y: off.y + rh[1] }, rb = fm >= 0 ? 1 + .1 * Math.exp(-(t - C.meter) * 12) : 1;
|
|
492
|
+
show(B.focus, hero && t < TOUT); show(B.burst, hero); show(B.burstBack, hero);
|
|
493
|
+
for (const pm of B.puff) { show(pm.g, hero); if (hero) { const u = t - C.drop - FR - pm.i * .5 * FR, k = spring(u, .45, 26), bj = Math.floor(Math.min(t, C.freeze) * 12) + pm.i * 7;
|
|
494
|
+
const d = 34 * (1 - clamp(k)) + 5 * Math.sin(2 * Math.PI * 1.3 * t + pm.i), ar = pm.a * Math.PI / 180;
|
|
495
|
+
X(pm.g, pm.x + off.x + d * Math.cos(ar) + (h1(bj) - .5) * 5, pm.y + off.y + d * Math.sin(ar) + (h1(bj + 3) - .5) * 5, pm.a + (h1(bj + 5) - .5) * 7, Math.max(0, k) * pm.k * po); } }
|
|
496
|
+
if (hero) {
|
|
497
|
+
const u = t - C.drop; B.focus.setAttribute('d', focusD(540, 700, 300 + boil)); B.focus.setAttribute('opacity', (.95 - .25 * clamp(u / .6)).toFixed(3));
|
|
498
|
+
const bs = spring(u + 2 * FR, .42, 24) * po * rb, cx = 540 + offH.x, cy = 1330 + offH.y;
|
|
499
|
+
B.burst.setAttribute('d', burstD(0, 0, 432, 288, 15, 100 + boil)); B.burstBack.setAttribute('d', burstD(0, 0, 452, 304, 15, 200 + boil));
|
|
500
|
+
X(B.burst, cx, cy, -5 + 1.2 * Math.sin(t * 7), bs); X(B.burstBack, cx + 16, cy + 18, -3, bs);
|
|
501
|
+
}
|
|
502
|
+
driveHZ(t, B.shock, { from: C.drop, t1: TOUT, wig: 2.4, bob: 3, wf: 1.6 }, offH);
|
|
503
|
+
driveHZ(t, B.sub, { t1: TOUT, z: .6, w: 28, wig: 1.2, bob: 2 }, off);
|
|
504
|
+
// 发量检测 meter: slams in on the 7.00 stab, needle whips 0 -> 爆表 in 4 frames (outBack), then buzzes against the stop
|
|
505
|
+
{ const um = t - (C.meter - 3 * FR), v = um >= 0 && t < TOUT + .17; disp(B.meter, v); disp(B.bao.root, v);
|
|
506
|
+
if (v) { let s, o = 1; if (t < C.meter) { const k = um / (3 * FR); s = lerp(1.9, 1, E.inQuad(k)); o = clamp(k * 2.5); } else { const w = t - C.meter; s = 1 - .08 * Math.exp(-w * 16) * Math.cos(w * 44); }
|
|
507
|
+
s *= po; B.meter.setAttribute('opacity', o.toFixed(3)); const mk = kick(t, C.meter, 10, 10, 13);
|
|
508
|
+
X(B.meter, 826 + mk.x + off.x * .5, 318 + mk.y + off.y * .5, 7 + (t < C.meter ? 8 * (1 - um / (3 * FR)) : 0) + .8 * Math.sin(t * 2.6), s);
|
|
509
|
+
const wn = clamp((t - C.needle[0]) / (C.needle[1] - C.needle[0])), buzz = t >= C.needle[1] ? 3.5 * Math.sin(2 * Math.PI * 17 * t) * (.4 + .6 * Math.exp(-(t - C.needle[1]) * 5)) : 0;
|
|
510
|
+
B.needle.setAttribute('transform', `translate(0 58) rotate(${(lerp(-88, 96, E.outBack(wn)) + buzz).toFixed(2)})`);
|
|
511
|
+
driveHZ(t, B.bao, { t1: TOUT, wig: 3, bob: 3, wf: 1.8 }, { x: mk.x, y: mk.y }); } }
|
|
512
|
+
}
|
|
513
|
+
// end card
|
|
514
|
+
driveHZ(t, B.jue, { wig: 2.6, bob: 5, wf: 1.0 });
|
|
515
|
+
for (const sp of B.sp2) { const u = t - sp.t0; show(sp.e, u >= 0); if (u >= 0) X(sp.e, sp.x, sp.y, u * 50 + sp.y, spring(u, .4, 26) * (.78 + .22 * Math.sin(2 * Math.PI * 1.6 * t + sp.y))); }
|
|
516
|
+
driveHZ(t, B.bye, { wig: 2, bob: 7, wf: 1.2 });
|
|
517
|
+
{ const u = t - (C.stamp - .13), v = u >= 0; show(B.stamp, v);
|
|
518
|
+
if (v) { let s, o = 1; if (t < C.stamp) { const k = u / .13; s = lerp(2.5, 1, E.inQuad(k)); o = clamp(k * 2.2); } else { const w = t - C.stamp; s = 1 - .09 * Math.exp(-w * 16) * Math.cos(w * 44); }
|
|
519
|
+
B.stamp.setAttribute('opacity', o); X(B.stamp, 812 + K85.x * .5, 1085 + K85.y * .5, -14 + (t < C.stamp ? -10 * (1 - u / .13) : 0) + .8 * Math.sin(t * 2.2), s); } }
|
|
520
|
+
// badge (persistent) with a tiny idle bob + ear twitch
|
|
521
|
+
{ const bx = t => { let cxp = 224, cyp = 142 + 2 * Math.sin(t * 2.4), br = .6 * Math.sin(t * 1.7), bs = 1;
|
|
522
|
+
if (t < 10 * FR) { const a = clamp(t / (3 * FR)), k = E.outBack(clamp((t - 3 * FR) / (7 * FR)));
|
|
523
|
+
bs = lerp(lerp(2.4, 2.0, E.outQuad(a)), 1, k); cxp = lerp(540, 224, k); cyp = lerp(820, 142, k); br = lerp(-6, 0, k); }
|
|
524
|
+
const us = t - C.sting;
|
|
525
|
+
if (us >= 0 && us < .36) { const m = spring(us, .42, 30) * (1 - E.inCubic(clamp((us - .2) / .16)));
|
|
526
|
+
bs = lerp(1, 2.6, m); cxp = lerp(cxp, 540, clamp(m)); cyp = lerp(cyp, 940, clamp(m)); br = lerp(br, -4, clamp(m)); }
|
|
527
|
+
return [cxp - 170 * bs, cyp - 50 * bs, br, bs]; };
|
|
528
|
+
// fast frames: 24 in-page sub-samples across the shutter (frame-quantised, so every harness sample is identical -> one continuous smear)
|
|
529
|
+
const tf = fN * FR, a = bx(tf - .25 * FR), b = bx(tf + .25 * FR), fast = Math.hypot(b[0] - a[0], b[1] - a[1]) + 180 * Math.abs(b[3] - a[3]) > 8;
|
|
530
|
+
B.bcl.forEach((u, i) => { if (!fast && i) { show(u, false); return; } show(u, true);
|
|
531
|
+
const v = fast ? bx(tf + (i / 47 - .5) * .5 * FR) : bx(t); X(u, v[0], v[1], v[2], v[3]); u.setAttribute('opacity', fast ? (1 / (i + 1)).toFixed(4) : '1'); }); }
|
|
532
|
+
// flashes
|
|
533
|
+
let fl = fN === Math.round(C.drop * 30) ? 1 : fN === Math.round(C.freeze * 30) ? .85 : 0;
|
|
534
|
+
for (const p of C.push) if (fN === Math.round(p * 30)) fl = .2;
|
|
535
|
+
$('flash').style.opacity = fl.toFixed(3);
|
|
536
|
+
$('vig').style.opacity = t >= C.freeze ? .0 : 1;
|
|
537
|
+
const fi = Math.round(t * 30); $('grain').style.backgroundPosition = `${Math.floor(h1(fi) * 2048)}px ${Math.floor(h1(fi + 777) * 2048)}px`;
|
|
538
|
+
};
|
|
539
|
+
build().then(() => { window.__ready = true; });
|
|
540
|
+
</script>
|
|
541
|
+
</body></html>
|