kasaframe 0.0.0-stage → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +148 -0
- package/README.md +92 -2
- package/app/package.json +12 -0
- package/app/server/engine.ts +533 -0
- package/app/server/main.ts +209 -0
- package/app/web/env.d.ts +2 -0
- package/app/web/icons.ts +31 -0
- package/app/web/index.html +21 -0
- package/app/web/main.ts +1195 -0
- package/app/web/style.css +463 -0
- package/bin/hooks.mjs +64 -0
- package/bin/kf.mjs +32 -0
- package/docs/AGENTS.md +286 -0
- package/music/README.md +37 -0
- package/package.json +44 -4
- package/packages/adapters/package.json +36 -0
- package/packages/adapters/src/css.ts +11 -0
- package/packages/adapters/src/gsap.ts +26 -0
- package/packages/adapters/src/index.ts +9 -0
- package/packages/adapters/src/lottie.ts +22 -0
- package/packages/adapters/src/media.ts +59 -0
- package/packages/adapters/src/page.ts +229 -0
- package/packages/adapters/src/project.ts +214 -0
- package/packages/adapters/src/react.ts +36 -0
- package/packages/adapters/src/svelte.ts +22 -0
- package/packages/adapters/src/three.ts +18 -0
- package/packages/adapters/src/vue.ts +27 -0
- package/packages/check/package.json +19 -0
- package/packages/check/src/check.ts +280 -0
- package/packages/check/src/cli.ts +70 -0
- package/packages/check/src/image.ts +146 -0
- package/packages/check/src/index.ts +9 -0
- package/packages/check/src/ocr.swift +37 -0
- package/packages/check/src/probe.ts +328 -0
- package/packages/check/src/report.ts +44 -0
- package/packages/check/src/rules/assets.ts +45 -0
- package/packages/check/src/rules/beats.ts +212 -0
- package/packages/check/src/rules/camera.ts +217 -0
- package/packages/check/src/rules/captions.ts +49 -0
- package/packages/check/src/rules/flash.ts +235 -0
- package/packages/check/src/rules/frames.ts +136 -0
- package/packages/check/src/rules/layout.ts +281 -0
- package/packages/check/src/rules/page.ts +87 -0
- package/packages/check/src/rules/runs.ts +20 -0
- package/packages/check/src/rules/text.ts +326 -0
- package/packages/check/src/scan.ts +240 -0
- package/packages/check/src/serve.ts +67 -0
- package/packages/check/src/types.ts +80 -0
- package/packages/check/src/video.ts +137 -0
- package/packages/cli/package.json +30 -0
- package/packages/cli/src/blur.ts +80 -0
- package/packages/cli/src/browser.ts +203 -0
- package/packages/cli/src/command.ts +44 -0
- package/packages/cli/src/commands/app.ts +25 -0
- package/packages/cli/src/commands/beats.ts +36 -0
- package/packages/cli/src/commands/bench.ts +123 -0
- package/packages/cli/src/commands/blender.ts +293 -0
- package/packages/cli/src/commands/check.ts +25 -0
- package/packages/cli/src/commands/direct.ts +210 -0
- package/packages/cli/src/commands/doctor.ts +30 -0
- package/packages/cli/src/commands/gen.ts +173 -0
- package/packages/cli/src/commands/look.ts +46 -0
- package/packages/cli/src/commands/lyrics.ts +157 -0
- package/packages/cli/src/commands/make.ts +1121 -0
- package/packages/cli/src/commands/music.ts +78 -0
- package/packages/cli/src/commands/narrate.ts +238 -0
- package/packages/cli/src/commands/new.ts +185 -0
- package/packages/cli/src/commands/preview.ts +43 -0
- package/packages/cli/src/commands/render.ts +250 -0
- package/packages/cli/src/commands/series.ts +110 -0
- package/packages/cli/src/commands/setup.ts +102 -0
- package/packages/cli/src/commands/sheet.ts +114 -0
- package/packages/cli/src/commands/skill.ts +43 -0
- package/packages/cli/src/commands/still.ts +40 -0
- package/packages/cli/src/commands/theme.ts +172 -0
- package/packages/cli/src/commands/transitions.ts +40 -0
- package/packages/cli/src/deps.ts +122 -0
- package/packages/cli/src/ffmpeg.ts +81 -0
- package/packages/cli/src/index.ts +8 -0
- package/packages/cli/src/kf.ts +64 -0
- package/packages/cli/src/lock.ts +72 -0
- package/packages/cli/src/mix.ts +131 -0
- package/packages/cli/src/out.ts +13 -0
- package/packages/cli/src/pool.ts +34 -0
- package/packages/cli/src/segments.ts +402 -0
- package/packages/cli/src/serve.ts +124 -0
- package/packages/clock/package.json +14 -0
- package/packages/clock/src/index.ts +25 -0
- package/packages/clock/src/install.ts +351 -0
- package/packages/clock/src/types.ts +45 -0
- package/packages/core/package.json +9 -0
- package/packages/core/src/beats.ts +283 -0
- package/packages/core/src/ease.ts +87 -0
- package/packages/core/src/frame.ts +99 -0
- package/packages/core/src/index.ts +27 -0
- package/packages/core/src/project.ts +157 -0
- package/packages/core/src/rand.ts +56 -0
- package/packages/core/src/spring.ts +52 -0
- package/packages/core/src/style.ts +100 -0
- package/packages/core/src/time.ts +88 -0
- package/packages/director/package.json +23 -0
- package/packages/director/src/assemble.ts +361 -0
- package/packages/director/src/brief.ts +122 -0
- package/packages/director/src/catalog.ts +49 -0
- package/packages/director/src/content.ts +343 -0
- package/packages/director/src/fallback.ts +58 -0
- package/packages/director/src/index.ts +13 -0
- package/packages/director/src/pattern.ts +90 -0
- package/packages/director/src/patterns/fill/cells.ts +115 -0
- package/packages/director/src/patterns/formula/stack.ts +93 -0
- package/packages/director/src/patterns/util.ts +58 -0
- package/packages/director/src/scene.ts +62 -0
- package/packages/director/src/select.ts +163 -0
- package/packages/director/src/transitions.ts +115 -0
- package/packages/gen/PROVIDERS.md +90 -0
- package/packages/gen/package.json +9 -0
- package/packages/gen/src/ask.ts +132 -0
- package/packages/gen/src/audio.ts +91 -0
- package/packages/gen/src/blender.ts +54 -0
- package/packages/gen/src/capabilities.ts +151 -0
- package/packages/gen/src/generate.ts +206 -0
- package/packages/gen/src/image/codex.ts +117 -0
- package/packages/gen/src/image/og.ts +133 -0
- package/packages/gen/src/index.ts +26 -0
- package/packages/gen/src/keys.ts +86 -0
- package/packages/gen/src/media.ts +150 -0
- package/packages/gen/src/music/elevenlabs.ts +41 -0
- package/packages/gen/src/music/index.ts +120 -0
- package/packages/gen/src/music/library.ts +73 -0
- package/packages/gen/src/music/lyria.ts +52 -0
- package/packages/gen/src/music/types.ts +28 -0
- package/packages/gen/src/plan.ts +106 -0
- package/packages/gen/src/registry.ts +54 -0
- package/packages/gen/src/seam.ts +103 -0
- package/packages/gen/src/tts/dashscope.ts +64 -0
- package/packages/gen/src/tts/elevenlabs.ts +84 -0
- package/packages/gen/src/tts/gemini.ts +73 -0
- package/packages/gen/src/tts/index.ts +241 -0
- package/packages/gen/src/tts/local.ts +42 -0
- package/packages/gen/src/tts/types.ts +44 -0
- package/packages/gen/src/types.ts +90 -0
- package/packages/gen/src/video/fal.ts +140 -0
- package/packages/gen/src/video/h3.ts +112 -0
- package/packages/gen/src/video/http.ts +44 -0
- package/packages/gen/src/video/ltx.ts +60 -0
- package/packages/gen/src/video/minimax.ts +55 -0
- package/packages/gen/src/video/veo.ts +71 -0
- package/packages/jizura/package.json +16 -0
- package/packages/jizura/src/deny.ts +73 -0
- package/packages/jizura/src/index.ts +7 -0
- package/packages/jizura/src/install.ts +269 -0
- package/packages/jizura/src/layer.ts +325 -0
- package/packages/jizura/src/lyrics.ts +81 -0
- package/packages/jizura/src/pin.ts +8 -0
- package/packages/jizura/src/vendor.ts +140 -0
- package/packages/jizura/src/vite.ts +63 -0
- package/packages/jizura/vendor/JIZURA_LICENSE.txt +21 -0
- package/packages/jizura/vendor/NOTICE +43 -0
- package/packages/jizura/vendor/engine.json +47 -0
- package/packages/jizura/vendor/fonts/BlackHanSans-Regular.woff2 +0 -0
- package/packages/jizura/vendor/fonts/DotGothic16-Regular.woff2 +0 -0
- package/packages/jizura/vendor/fonts/GowunBatang-Bold.woff2 +0 -0
- package/packages/jizura/vendor/fonts/IBMPlexMono-Medium.ttf +0 -0
- package/packages/jizura/vendor/fonts/IBMPlexMono-SemiBold.ttf +0 -0
- package/packages/jizura/vendor/fonts/NotoSansKR-VF.woff2 +0 -0
- package/packages/jizura/vendor/fonts/NotoSerifKR-VF.woff2 +0 -0
- package/packages/jizura/vendor/fonts/OFL-blackhansans.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-dotgothic16.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-gowunbatang.txt +94 -0
- package/packages/jizura/vendor/fonts/OFL-ibmplexmono.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-notosanskr.txt +93 -0
- package/packages/jizura/vendor/fonts/OFL-notoserifkr.txt +94 -0
- package/packages/jizura/vendor/fonts/fonts.json +52 -0
- package/packages/jizura/vendor/jizura_engine.js +35024 -0
- package/packages/motion/README.md +153 -0
- package/packages/motion/package.json +30 -0
- package/packages/motion/src/camera.ts +97 -0
- package/packages/motion/src/captions.ts +487 -0
- package/packages/motion/src/enter.ts +128 -0
- package/packages/motion/src/hangul.ts +129 -0
- package/packages/motion/src/impact.ts +100 -0
- package/packages/motion/src/index.ts +17 -0
- package/packages/motion/src/moves/brushWipe.ts +103 -0
- package/packages/motion/src/moves/cloneArray.ts +111 -0
- package/packages/motion/src/moves/curtains.ts +81 -0
- package/packages/motion/src/moves/dress.ts +191 -0
- package/packages/motion/src/moves/echoStack.ts +70 -0
- package/packages/motion/src/moves/fit.ts +70 -0
- package/packages/motion/src/moves/flood.ts +61 -0
- package/packages/motion/src/moves/ghostStack.ts +88 -0
- package/packages/motion/src/moves/gridFloor.ts +100 -0
- package/packages/motion/src/moves/imageSwarm.ts +113 -0
- package/packages/motion/src/moves/index.ts +38 -0
- package/packages/motion/src/moves/irisBlades.ts +113 -0
- package/packages/motion/src/moves/karaokeLine.ts +108 -0
- package/packages/motion/src/moves/ledBoard.ts +94 -0
- package/packages/motion/src/moves/liquidTab.ts +72 -0
- package/packages/motion/src/moves/markerWrite.ts +63 -0
- package/packages/motion/src/moves/menu.ts +138 -0
- package/packages/motion/src/moves/morphBox.ts +96 -0
- package/packages/motion/src/moves/neonSign.ts +78 -0
- package/packages/motion/src/moves/panelPop.ts +78 -0
- package/packages/motion/src/moves/paperTear.ts +75 -0
- package/packages/motion/src/moves/path.ts +64 -0
- package/packages/motion/src/moves/pathText.ts +107 -0
- package/packages/motion/src/moves/pointSphere.ts +109 -0
- package/packages/motion/src/moves/ransomLetters.ts +73 -0
- package/packages/motion/src/moves/shapeMorph.ts +143 -0
- package/packages/motion/src/moves/slamWords.ts +96 -0
- package/packages/motion/src/moves/sparkTrail.ts +130 -0
- package/packages/motion/src/moves/speedLines.ts +91 -0
- package/packages/motion/src/moves/splitFlap.ts +149 -0
- package/packages/motion/src/moves/stepWords.ts +128 -0
- package/packages/motion/src/moves/strikeOut.ts +98 -0
- package/packages/motion/src/moves/sunburst.ts +58 -0
- package/packages/motion/src/moves/tickerRows.ts +91 -0
- package/packages/motion/src/moves/tokenPicker.ts +115 -0
- package/packages/motion/src/moves/truchet.ts +85 -0
- package/packages/motion/src/moves/wordWall.ts +78 -0
- package/packages/motion/src/moves/worldRoll.ts +32 -0
- package/packages/motion/src/particles.ts +102 -0
- package/packages/motion/src/react/index.tsx +21 -0
- package/packages/motion/src/react/parts.tsx +431 -0
- package/packages/motion/src/react/time.tsx +97 -0
- package/packages/motion/src/text.ts +103 -0
- package/packages/motion/src/transition.ts +82 -0
- package/packages/motion/src/transition3d/cards.ts +65 -0
- package/packages/motion/src/transition3d/chain.ts +84 -0
- package/packages/motion/src/transition3d/dive.ts +181 -0
- package/packages/motion/src/transition3d/fold.ts +110 -0
- package/packages/motion/src/transition3d/gl.ts +219 -0
- package/packages/motion/src/transition3d/index.ts +235 -0
- package/packages/motion/src/transition3d/live.ts +70 -0
- package/packages/motion/src/transition3d/portal.ts +115 -0
- package/packages/motion/src/transition3d/react.tsx +29 -0
- package/packages/motion/src/transition3d/rig.ts +600 -0
- package/packages/motion/src/transition3d/shatter.ts +104 -0
- package/packages/motion/src/transition3d/space.ts +173 -0
- package/packages/motion/src/transition3d/whip.ts +78 -0
- package/packages/motion/src/transition3d/world.ts +737 -0
- package/packages/motion/src/transition3d/zoomOut.ts +114 -0
- package/packages/motion/src/transitions2d/catalog.ts +127 -0
- package/packages/motion/src/transitions2d/css.d.ts +2 -0
- package/packages/motion/src/transitions2d/cult-ui/LICENSE.md +9 -0
- package/packages/motion/src/transitions2d/cult-ui/RollingNumber.tsx +43 -0
- package/packages/motion/src/transitions2d/gl-transitions/LICENSE +25 -0
- package/packages/motion/src/transitions2d/gl-transitions/shaders.ts +1931 -0
- package/packages/motion/src/transitions2d/index.ts +2 -0
- package/packages/motion/src/transitions2d/kokonutui/LICENSE +21 -0
- package/packages/motion/src/transitions2d/kokonutui/MatrixText.css +16 -0
- package/packages/motion/src/transitions2d/kokonutui/MatrixText.tsx +94 -0
- package/packages/motion/src/transitions2d/magicui/HyperText.css +15 -0
- package/packages/motion/src/transitions2d/magicui/HyperText.tsx +115 -0
- package/packages/motion/src/transitions2d/magicui/LICENSE.md +21 -0
- package/packages/motion/src/transitions2d/magicui/MorphingText.css +25 -0
- package/packages/motion/src/transitions2d/magicui/MorphingText.tsx +130 -0
- package/packages/motion/src/transitions2d/magicui/WordRotate.tsx +42 -0
- package/packages/motion/src/transitions2d/react.ts +13 -0
- package/packages/motion/src/transitions2d/skiper-ui/ClipDiv.css +39 -0
- package/packages/motion/src/transitions2d/skiper-ui/ClipDiv.tsx +32 -0
- package/packages/motion/src/transitions2d/smoothui/LICENSE +21 -0
- package/packages/motion/src/transitions2d/smoothui/SharedAxisY.tsx +50 -0
- package/packages/motion/src/transitions2d/smoothui/TextMorph.tsx +90 -0
- package/packages/motion/src/transitions2d/smoothui/shaders.ts +223 -0
- package/packages/motion/src/transitions2d/unlumen/LICENSE +21 -0
- package/packages/motion/src/transitions2d/unlumen/ScrambleText.tsx +114 -0
- package/packages/motion/src/transitions2d/vengeance-ui/LICENSE +21 -0
- package/packages/motion/src/transitions2d/vengeance-ui/MorphText.css +69 -0
- package/packages/motion/src/transitions2d/vengeance-ui/MorphText.tsx +45 -0
- package/packages/motion/src/type.ts +131 -0
- package/packages/motion/src/ui.ts +172 -0
- package/packages/patterns/package.json +15 -0
- package/packages/patterns/src/bars/rank.ts +119 -0
- package/packages/patterns/src/before-after/shrink.ts +127 -0
- package/packages/patterns/src/before-after/strike.ts +125 -0
- package/packages/patterns/src/code/terminal.ts +133 -0
- package/packages/patterns/src/compare/bars.ts +142 -0
- package/packages/patterns/src/compare/duel.ts +103 -0
- package/packages/patterns/src/end/lockup.ts +85 -0
- package/packages/patterns/src/end/slam.ts +91 -0
- package/packages/patterns/src/flow/graph.ts +250 -0
- package/packages/patterns/src/hook-number/counter.ts +101 -0
- package/packages/patterns/src/hook-number/roll.ts +179 -0
- package/packages/patterns/src/hook-number/slam.ts +91 -0
- package/packages/patterns/src/index.ts +38 -0
- package/packages/patterns/src/kit.ts +449 -0
- package/packages/patterns/src/limit/gauge.ts +117 -0
- package/packages/patterns/src/list/cards.ts +131 -0
- package/packages/patterns/src/list/cycle.ts +22 -0
- package/packages/patterns/src/media/panels.ts +100 -0
- package/packages/patterns/src/objects.ts +234 -0
- package/packages/patterns/src/quote/karaoke.ts +126 -0
- package/packages/patterns/src/quote/slam.ts +22 -0
- package/packages/patterns/src/screen/focus.ts +85 -0
- package/packages/patterns/src/steps/path.ts +137 -0
- package/packages/patterns/src/steps/stack.ts +111 -0
- package/packages/patterns/src/term-reveal/chips.ts +92 -0
- package/packages/patterns/src/term-reveal/expand.ts +127 -0
- package/packages/patterns/src/timeline/axis.ts +144 -0
- package/packages/patterns/src/title/mask.ts +85 -0
- package/packages/patterns/src/title/slam.ts +23 -0
- package/packages/patterns/src/toggle-sim/switch.ts +92 -0
- package/packages/patterns/src/trend/columns.ts +108 -0
- package/packages/patterns/src/trend/draw.ts +140 -0
- package/packages/patterns/src/types.ts +67 -0
- package/packages/patterns/src/words/moves.ts +42 -0
- package/packages/patterns/src/words/slam.ts +4 -0
- package/packages/plan/package.json +15 -0
- package/packages/plan/src/asks.ts +256 -0
- package/packages/plan/src/brief.ts +383 -0
- package/packages/plan/src/captions.ts +78 -0
- package/packages/plan/src/detect.ts +93 -0
- package/packages/plan/src/index.ts +27 -0
- package/packages/plan/src/layout.ts +176 -0
- package/packages/plan/src/llm.ts +172 -0
- package/packages/plan/src/look.ts +222 -0
- package/packages/plan/src/plan.ts +179 -0
- package/packages/plan/src/request.ts +55 -0
- package/packages/plan/src/series.ts +76 -0
- package/packages/plan/src/studio.ts +53 -0
- package/packages/plan/src/templates.ts +42 -0
- package/packages/plan/src/themes.ts +48 -0
- package/packages/plan/src/types.ts +157 -0
- package/packages/studio/package.json +12 -0
- package/packages/studio/src/index.ts +1 -0
- package/packages/studio/src/plugin.ts +236 -0
- package/packages/studio/src/ui/main.ts +503 -0
- package/packages/studio/src/ui/studio.css +165 -0
- package/packages/studio/src/ui/timeline.ts +317 -0
- package/packages/themes/kit/THEME-MAKE.md +68 -0
- package/packages/themes/kit/THEME.md +30 -0
- package/packages/themes/kit/briefs/og-intro-15s/brief.json +16 -0
- package/packages/themes/kit/briefs/og-intro-15s/facts.ts +29 -0
- package/packages/themes/kit/briefs/og-intro-15s/logo.svg +12 -0
- package/packages/themes/kit/effects.ts +5 -0
- package/packages/themes/kit/sample/index.html +11 -0
- package/packages/themes/kit/sample/main.ts +9 -0
- package/packages/themes/kit/sample/scenes/scene.ts +15 -0
- package/packages/themes/package.json +19 -0
- package/packages/themes/src/factory.ts +296 -0
- package/packages/themes/src/fx.ts +14 -0
- package/packages/themes/src/index.ts +114 -0
- package/packages/themes/src/slotkit.ts +79 -0
- package/packages/themes/src/slots.ts +46 -0
- package/packages/themes/src/stage3d.ts +197 -0
- package/packages/themes/src/types.ts +58 -0
- package/presets/kawaii-pastel.json +94 -0
- package/presets/neutral-dark.json +82 -0
- package/presets/og.json +98 -0
- package/series/og-shorts.json +14 -0
- package/skills/kasaframe/SKILL.md +33 -0
- package/templates/_shared/project/index.html +11 -0
- package/templates/_shared/project/lib/react.ts +22 -0
- package/templates/_shared/project/lib/stage.ts +292 -0
- package/templates/_shared/project/main.ts +9 -0
- package/templates/_shared/scenes/default.ts +21 -0
- package/templates/_shared/scenes/drop.ts +33 -0
- package/templates/_shared/scenes/end.ts +26 -0
- package/templates/_shared/scenes/hook.ts +18 -0
- package/templates/_shared/scenes/seam.ts +41 -0
- package/templates/_shared/scenes/step.ts +49 -0
- package/templates/ad/preview.png +0 -0
- package/templates/ad/template.json +151 -0
- package/templates/demo/preview.png +0 -0
- package/templates/demo/template.json +141 -0
- package/templates/explainer/preview.png +0 -0
- package/templates/explainer/template.json +193 -0
- package/templates/launch/preview.png +0 -0
- package/templates/launch/template.json +163 -0
- package/templates/mv/preview.png +0 -0
- package/templates/mv/scenes/default.ts +98 -0
- package/templates/mv/template.json +178 -0
- package/templates/promo/preview.png +0 -0
- package/templates/promo/template.json +185 -0
- package/templates/shorts/preview.png +0 -0
- package/templates/shorts/scenes/hook.ts +37 -0
- package/templates/shorts/template.json +196 -0
- package/templates/square/preview.png +0 -0
- package/templates/square/template.json +133 -0
- package/themes/debug-hud/THEME.md +39 -0
- package/themes/debug-hud/effects.ts +389 -0
- package/themes/debug-hud/sample/assets/og/logo.svg +12 -0
- package/themes/debug-hud/sample/beats.json +1 -0
- package/themes/debug-hud/sample/index.html +11 -0
- package/themes/debug-hud/sample/kf.json +59 -0
- package/themes/debug-hud/sample/lib/hudkit.ts +49 -0
- package/themes/debug-hud/sample/lib/og.ts +29 -0
- package/themes/debug-hud/sample/main.ts +9 -0
- package/themes/debug-hud/sample/scenes/end.ts +62 -0
- package/themes/debug-hud/sample/scenes/gather.ts +67 -0
- package/themes/debug-hud/sample/scenes/models.ts +70 -0
- package/themes/debug-hud/sample/scenes/price.ts +79 -0
- package/themes/debug-hud/sample/style.json +91 -0
- package/themes/debug-hud/slots.ts +99 -0
- package/themes/debug-hud/still.png +0 -0
- package/themes/debug-hud/style.json +91 -0
- package/themes/debug-hud/theme.json +68 -0
- package/themes/og-measure/THEME.md +47 -0
- package/themes/og-measure/effects.ts +432 -0
- package/themes/og-measure/sample/assets/brand/og-logo-full.svg +12 -0
- package/themes/og-measure/sample/assets/brand/og-logo.svg +12 -0
- package/themes/og-measure/sample/assets/data/measure.json +353 -0
- package/themes/og-measure/sample/beats.json +1 -0
- package/themes/og-measure/sample/index.html +11 -0
- package/themes/og-measure/sample/kf.json +66 -0
- package/themes/og-measure/sample/lib/data.ts +62 -0
- package/themes/og-measure/sample/main.ts +9 -0
- package/themes/og-measure/sample/measure.ts +78 -0
- package/themes/og-measure/sample/scenes/end.ts +47 -0
- package/themes/og-measure/sample/scenes/gather.ts +51 -0
- package/themes/og-measure/sample/scenes/models.ts +34 -0
- package/themes/og-measure/sample/scenes/one.ts +39 -0
- package/themes/og-measure/sample/scenes/price.ts +56 -0
- package/themes/og-measure/sample/style.json +97 -0
- package/themes/og-measure/slots.ts +88 -0
- package/themes/og-measure/still.png +0 -0
- package/themes/og-measure/style.json +97 -0
- package/themes/og-measure/theme.json +79 -0
- package/themes/riso-zine/THEME.md +43 -0
- package/themes/riso-zine/effects.ts +321 -0
- package/themes/riso-zine/sample/assets/og/logo.svg +12 -0
- package/themes/riso-zine/sample/beats.json +1 -0
- package/themes/riso-zine/sample/index.html +11 -0
- package/themes/riso-zine/sample/kf.json +59 -0
- package/themes/riso-zine/sample/lib/og.ts +29 -0
- package/themes/riso-zine/sample/lib/shot.ts +86 -0
- package/themes/riso-zine/sample/lib/zine.ts +42 -0
- package/themes/riso-zine/sample/main.ts +9 -0
- package/themes/riso-zine/sample/scenes/end.ts +61 -0
- package/themes/riso-zine/sample/scenes/gather.ts +62 -0
- package/themes/riso-zine/sample/scenes/models.ts +52 -0
- package/themes/riso-zine/sample/scenes/price.ts +82 -0
- package/themes/riso-zine/sample/style.json +99 -0
- package/themes/riso-zine/slots.ts +81 -0
- package/themes/riso-zine/still.png +0 -0
- package/themes/riso-zine/style.json +99 -0
- package/themes/riso-zine/theme.json +75 -0
- package/tools/beats/beats.py +372 -0
- package/tools/beats/requirements.txt +3 -0
- package/tools/lyrics/align.py +164 -0
- package/tools/lyrics/requirements.txt +9 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { SceneCtx } from "@kasaframe/core";
|
|
2
|
+
import { paperGrain } from "../../effects.ts";
|
|
3
|
+
import { OG } from "../lib/og.ts";
|
|
4
|
+
import { sheets, type Word } from "../lib/shot.ts";
|
|
5
|
+
import { blobs, layer } from "../lib/zine.ts";
|
|
6
|
+
|
|
7
|
+
// 회사 아홉이 흩어진 자리 [x, y, 크기] — 화면을 고르게 덮게 손으로 놓았다
|
|
8
|
+
const SPOT: [number, number, number][] = [
|
|
9
|
+
[100, 90, 170], [900, 140, 130], [1240, 330, 160],
|
|
10
|
+
[180, 420, 160], [720, 470, 190], [1450, 640, 150],
|
|
11
|
+
[120, 760, 130], [640, 800, 130], [1300, 880, 110],
|
|
12
|
+
];
|
|
13
|
+
const WAVE = [0, 1, 2, 0, 1, 2, 0, 1, 2];
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
build(root: HTMLElement, ctx: SceneCtx) {
|
|
17
|
+
const paper = paperGrain(layer(root), { ctx });
|
|
18
|
+
const art = layer(root);
|
|
19
|
+
const names: Word[] = OG.providers.map(([name], i) => ({ text: name, x: SPOT[i][0], y: SPOT[i][1], size: SPOT[i][2] }));
|
|
20
|
+
const cells = OG.providers.map(([name, n], i) => {
|
|
21
|
+
const x = 120 + (i % 3) * 600;
|
|
22
|
+
const y = 80 + Math.floor(i / 3) * 310;
|
|
23
|
+
return { name, n, x, y };
|
|
24
|
+
});
|
|
25
|
+
const pages = sheets(art, ctx, [
|
|
26
|
+
{
|
|
27
|
+
// 박마다 셋씩 흩어져 찍히고 넷째 박에 핑크로 한 번 더
|
|
28
|
+
plates: [
|
|
29
|
+
...[0, 1, 2].map((k) => ({ beat: k, ink: "blue" as const, words: names.filter((_, i) => WAVE[i] === k) })),
|
|
30
|
+
{ beat: 3, ink: "pink", words: names, px: 7 },
|
|
31
|
+
],
|
|
32
|
+
tones: [{ beat: 1, x: 0, y: 0, w: 1920, h: 1080, ink: "pink", angle: 75, pitch: 20, value: blobs([[0.2, 0.25, 0.22], [0.75, 0.3, 0.18], [0.45, 0.6, 0.2], [0.85, 0.75, 0.2], [0.15, 0.82, 0.16]]) }],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
// 회사별 모델 수 — 줄마다 한 박, 넷째 박에 숫자만 핑크로 겹친다
|
|
36
|
+
plates: [
|
|
37
|
+
...[0, 1, 2].map((r) => ({
|
|
38
|
+
beat: r,
|
|
39
|
+
ink: "blue" as const,
|
|
40
|
+
words: cells.slice(r * 3, r * 3 + 3).flatMap((c) => [
|
|
41
|
+
{ text: String(c.n), x: c.x, y: c.y, size: 210 },
|
|
42
|
+
{ text: c.name, x: c.x + 4, y: c.y + 200, size: 48, font: "sans" as const, weight: 800 },
|
|
43
|
+
]),
|
|
44
|
+
})),
|
|
45
|
+
{ beat: 3, ink: "pink", words: cells.map((c) => ({ text: String(c.n), x: c.x, y: c.y, size: 210 })), px: 8 },
|
|
46
|
+
],
|
|
47
|
+
tones: [{ beat: 0, x: 0, y: 0, w: 1920, h: 1080, ink: "pink", angle: 75, pitch: 14, reveal: "sweep", dir: "down", dur: 1.0, value: (u, v) => {
|
|
48
|
+
const c = cells[Math.min(2, Math.floor(v * 3.48)) * 3 + Math.min(2, Math.floor(u * 3.2))];
|
|
49
|
+
const lu = u * 1920 - c.x;
|
|
50
|
+
const lv = v * 1080 - c.y;
|
|
51
|
+
return lv > 190 && lv < 260 && lu > 0 && lu < (480 * c.n) / 41 ? 0.6 : 0;
|
|
52
|
+
} }],
|
|
53
|
+
},
|
|
54
|
+
]);
|
|
55
|
+
const mottle = paperGrain(layer(root), { ctx, mode: "mottle" });
|
|
56
|
+
return (t: number) => {
|
|
57
|
+
paper(t);
|
|
58
|
+
for (const p of pages) p(t);
|
|
59
|
+
mottle(t);
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SceneCtx } from "@kasaframe/core";
|
|
2
|
+
import { paperGrain } from "../../effects.ts";
|
|
3
|
+
import { OG } from "../lib/og.ts";
|
|
4
|
+
import { sheets } from "../lib/shot.ts";
|
|
5
|
+
import { layer, rings } from "../lib/zine.ts";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
build(root: HTMLElement, ctx: SceneCtx) {
|
|
9
|
+
const paper = paperGrain(layer(root), { ctx, seed: "models" });
|
|
10
|
+
const art = layer(root);
|
|
11
|
+
const FULL = { x: 0, y: 0, w: 1920, h: 1080 };
|
|
12
|
+
const pages = sheets(art, ctx, [
|
|
13
|
+
{
|
|
14
|
+
// 한 주소 — 블루 주소, 핑크 띠, 엔드포인트, 핑크 /v1
|
|
15
|
+
plates: [
|
|
16
|
+
{ beat: 0, ink: "blue", words: [{ text: "apis.opengateway.ai", size: 150, y: 110 }, { text: "/v1", size: 420, y: 300 }] },
|
|
17
|
+
{ beat: 2, ink: "blue", words: OG.endpoints.map((e, i) => ({ text: `POST /v1${e}`, x: 140 + (i % 2) * 860, y: 790 + Math.floor(i / 2) * 80, size: 50, font: "mono" as const, weight: 600 })) },
|
|
18
|
+
{ beat: 3, ink: "pink", words: [{ text: "/v1", size: 420, y: 300 }], px: 9 },
|
|
19
|
+
],
|
|
20
|
+
tones: [{ beat: 1, x: 0, y: 300, w: 1920, h: 440, ink: "pink", angle: 75, pitch: 16, reveal: "sweep", dir: "right", dur: 0.3, value: (u) => ((u * 22) % 1 < 0.5 ? 0.55 : 0.08) }],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
// 같은 주소에 모델만 박마다 바뀐다 — 앞 판은 걷고 새 판을 찍는다
|
|
24
|
+
plates: [
|
|
25
|
+
{ beat: 0, ink: "blue", words: [{ text: "POST /v1/chat/completions", size: 52, y: 90, font: "mono", weight: 600 }] },
|
|
26
|
+
...OG.ids.slice(0, 4).map((id, k) => {
|
|
27
|
+
const [who, model] = id.split("/");
|
|
28
|
+
return { beat: k, until: k + 1, ink: "blue" as const, words: [{ text: who, size: 300, y: 220 }, { text: model, size: 96, y: 620 }] };
|
|
29
|
+
}),
|
|
30
|
+
...OG.ids.slice(0, 4).map((id, k) => ({ beat: k, until: k + 1, ink: "pink" as const, px: 8, words: [{ text: id.split("/")[0], size: 300, y: 220 }] })),
|
|
31
|
+
],
|
|
32
|
+
tones: [{ beat: 0, ...FULL, ink: "pink", angle: 75, pitch: 22, value: rings(0.5, 10) }],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
// OpenAI·Anthropic 두 형식 — 두 판이 겹쳐 보라, 드롭 앞 망점이 아래서 차오른다
|
|
36
|
+
plates: [
|
|
37
|
+
{ beat: 0, ink: "blue", words: [{ text: "OpenAI", size: 280, x: 130, y: 120 }] },
|
|
38
|
+
{ beat: 1, ink: "pink", words: [{ text: "Anthropic", size: 260, x: 220, y: 430 }] },
|
|
39
|
+
{ beat: 1, ink: "blue", words: [{ text: "Anthropic", size: 260, x: 220, y: 430 }], px: 6 },
|
|
40
|
+
{ beat: 2, ink: "blue", words: [{ text: "/chat/completions /messages", size: 56, y: 800, font: "mono", weight: 600 }] },
|
|
41
|
+
],
|
|
42
|
+
tones: [{ beat: 3, x: 0, y: 560, w: 1920, h: 480, ink: "pink", angle: 75, pitch: 16, value: (_, v) => 0.06 + 0.85 * v ** 1.4 }],
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
const mottle = paperGrain(layer(root), { ctx, mode: "mottle", seed: "models-m" });
|
|
46
|
+
return (t: number) => {
|
|
47
|
+
paper(t);
|
|
48
|
+
for (const p of pages) p(t);
|
|
49
|
+
mottle(t);
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { applyStyle, type SceneCtx } from "@kasaframe/core";
|
|
2
|
+
import { dropPlate, paperGrain } from "../../effects.ts";
|
|
3
|
+
import { OG } from "../lib/og.ts";
|
|
4
|
+
import { sheets } from "../lib/shot.ts";
|
|
5
|
+
import { layer, rings } from "../lib/zine.ts";
|
|
6
|
+
|
|
7
|
+
// 하루 시계 — 00시가 위, 시계 방향. 00–10시 창은 진하게
|
|
8
|
+
const DIAL = { x: 120, y: 100, w: 880, h: 880 };
|
|
9
|
+
const dial = (u: number, v: number) => {
|
|
10
|
+
const dx = u - 0.5;
|
|
11
|
+
const dy = v - 0.5;
|
|
12
|
+
const d = Math.hypot(dx, dy);
|
|
13
|
+
if (d < 0.3 || d > 0.47) return 0;
|
|
14
|
+
const hour = Math.floor((((Math.atan2(dx, -dy) / (Math.PI * 2)) + 1) % 1) * 24);
|
|
15
|
+
return hour >= OG.night.from && hour < OG.night.to ? 0.9 : 0.22;
|
|
16
|
+
};
|
|
17
|
+
const hourAt = (h: number, r: number): [number, number] => {
|
|
18
|
+
const a = (h / 24) * Math.PI * 2;
|
|
19
|
+
return [DIAL.x + DIAL.w / 2 + Math.sin(a) * r, DIAL.y + DIAL.h / 2 - Math.cos(a) * r];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
build(root: HTMLElement, ctx: SceneCtx) {
|
|
24
|
+
const paper = paperGrain(layer(root), { ctx, seed: "price" });
|
|
25
|
+
const cam = layer(root);
|
|
26
|
+
const FULL = { x: 0, y: 0, w: 1920, h: 1080 };
|
|
27
|
+
const [ds, glm] = [OG.deepseek, OG.glm];
|
|
28
|
+
// 드롭 구간이라 망점이 박마다 부푼다(beatPulse drops-only)
|
|
29
|
+
const pages = sheets(
|
|
30
|
+
cam,
|
|
31
|
+
ctx,
|
|
32
|
+
[
|
|
33
|
+
{
|
|
34
|
+
plates: [
|
|
35
|
+
{ beat: 0, ink: "blue", words: [{ text: String(OG.models), size: 760, y: 20 }] },
|
|
36
|
+
{ beat: 1, ink: "pink", words: [{ text: String(OG.models), size: 760, y: 20 }], px: 10 },
|
|
37
|
+
{ beat: 2, ink: "blue", words: [{ text: "한 주소", size: 150, y: 760 }] },
|
|
38
|
+
{ beat: 3, ink: "blue", words: [{ text: OG.host, size: 46, y: 950, font: "mono", weight: 600 }] },
|
|
39
|
+
],
|
|
40
|
+
tones: [{ beat: 0, ...FULL, ink: "pink", angle: 75, pitch: 22, value: rings(0.5, 12) }],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
plates: [
|
|
44
|
+
{
|
|
45
|
+
beat: 0,
|
|
46
|
+
ink: "blue",
|
|
47
|
+
words: [0, 6, 12, 18].map((h) => {
|
|
48
|
+
const [x, y] = hourAt(h, 470 * 0.88);
|
|
49
|
+
return { text: String(h).padStart(2, "0"), x: x - 40, y: y - 30, size: 60, font: "mono" as const, weight: 700 };
|
|
50
|
+
}),
|
|
51
|
+
},
|
|
52
|
+
{ beat: 2, ink: "blue", words: [{ text: "00:00-10:00", size: 120, x: 1060, y: 160 }, { text: OG.night.tz, size: 90, x: 1060, y: 300 }] },
|
|
53
|
+
{ beat: 3, ink: "blue", words: [{ text: ds.off, size: 300, x: 1060, y: 520 }] },
|
|
54
|
+
{ beat: 3, ink: "pink", words: [{ text: ds.off, size: 300, x: 1060, y: 520 }], px: 9 },
|
|
55
|
+
],
|
|
56
|
+
tones: [{ beat: 1, ...DIAL, ink: "pink", angle: 75, pitch: 14, value: dial }],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
plates: [
|
|
60
|
+
{ beat: 0, ink: "blue", words: [{ text: ds.id, size: 52, x: 120, y: 80, font: "mono", weight: 600 }, { text: "입력", size: 80, x: 120, y: 250, font: "sans", weight: 800 }, { text: ds.input[0], size: 150, x: 330, y: 220 }] },
|
|
61
|
+
{ beat: 1, ink: "blue", words: [{ text: ds.input[1], size: 300, x: 960, y: 150 }] },
|
|
62
|
+
{ beat: 2, ink: "blue", words: [{ text: "출력", size: 80, x: 120, y: 640, font: "sans", weight: 800 }, { text: ds.output[0], size: 150, x: 330, y: 610 }, { text: ds.output[1], size: 300, x: 960, y: 540 }] },
|
|
63
|
+
{ beat: 3, ink: "pink", words: [{ text: ds.input[1], size: 300, x: 960, y: 150 }, { text: ds.output[1], size: 300, x: 960, y: 540 }], px: 8 },
|
|
64
|
+
{ beat: 3, ink: "blue", words: [{ text: `${glm.id} ${glm.off}`, size: 48, x: 120, y: 950, font: "mono", weight: 600 }] },
|
|
65
|
+
],
|
|
66
|
+
// 정가 위에 핑크 줄 — 지운 값
|
|
67
|
+
tones: [{ beat: 1, x: 320, y: 290, w: 560, h: 30, ink: "pink", angle: 75, pitch: 8, reveal: "sweep", dir: "right", dur: 0.15, value: () => 0.9 }, { beat: 2, x: 320, y: 680, w: 560, h: 30, ink: "pink", angle: 75, pitch: 8, reveal: "sweep", dir: "right", dur: 0.15, value: () => 0.9 }],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
{ pulse: true },
|
|
71
|
+
);
|
|
72
|
+
const plate = dropPlate(layer(root), { ctx, drop: 0, origin: [960, 400] });
|
|
73
|
+
const mottle = paperGrain(layer(root), { ctx, mode: "mottle", seed: "price-m" });
|
|
74
|
+
return (t: number) => {
|
|
75
|
+
paper(t);
|
|
76
|
+
for (const p of pages) p(t);
|
|
77
|
+
const s = plate(t);
|
|
78
|
+
applyStyle(cam, s.shake);
|
|
79
|
+
mottle(t);
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "riso-zine",
|
|
3
|
+
"label": "리소 잡지 — 잉크 판을 한 장씩 찍는다",
|
|
4
|
+
"scheme": "light",
|
|
5
|
+
"colors": {
|
|
6
|
+
"bg": "#F2EDE4",
|
|
7
|
+
"surface": "#FAF7F1",
|
|
8
|
+
"raised": "#E9E2D4",
|
|
9
|
+
"line": "#CFC5B3",
|
|
10
|
+
"ink": "#3255A4",
|
|
11
|
+
"inkSoft": "#3255A4",
|
|
12
|
+
"dim": "#5B74B0",
|
|
13
|
+
"accent": "#FF48B0",
|
|
14
|
+
"accentSoft": "#FFB3DA",
|
|
15
|
+
"accentText": "#3255A4",
|
|
16
|
+
"onAccent": "#F2EDE4",
|
|
17
|
+
"success": "#3255A4",
|
|
18
|
+
"danger": "#FF48B0",
|
|
19
|
+
"warning": "#FF48B0",
|
|
20
|
+
"blue": "#3255A4",
|
|
21
|
+
"pink": "#FF48B0",
|
|
22
|
+
"paper": "#F2EDE4"
|
|
23
|
+
},
|
|
24
|
+
"fonts": {
|
|
25
|
+
"sans": "\"Pretendard Variable\", Pretendard, \"Noto Sans KR\", \"Apple SD Gothic Neo\", sans-serif",
|
|
26
|
+
"display": "\"Black Han Sans\", \"Pretendard Variable\", Pretendard, \"Noto Sans KR\", \"Apple SD Gothic Neo\", sans-serif",
|
|
27
|
+
"mono": "\"JetBrains Mono\", ui-monospace, \"SF Mono\", \"Pretendard Variable\", \"Noto Sans KR\", \"Apple SD Gothic Neo\", monospace",
|
|
28
|
+
"faces": [
|
|
29
|
+
{
|
|
30
|
+
"family": "Black Han Sans",
|
|
31
|
+
"src": "https://cdn.jsdelivr.net/gh/google/fonts@main/ofl/blackhansans/BlackHanSans-Regular.ttf",
|
|
32
|
+
"weight": "400"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"family": "Pretendard Variable",
|
|
36
|
+
"src": "https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2",
|
|
37
|
+
"weight": "45 920"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"family": "JetBrains Mono",
|
|
41
|
+
"src": "https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5/files/jetbrains-mono-latin-wght-normal.woff2",
|
|
42
|
+
"weight": "100 800"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"type": {
|
|
47
|
+
"hero": 220,
|
|
48
|
+
"title": 110,
|
|
49
|
+
"body": 44,
|
|
50
|
+
"caption": 32,
|
|
51
|
+
"weightDisplay": 400,
|
|
52
|
+
"weightBody": 600,
|
|
53
|
+
"tracking": "-0.01em"
|
|
54
|
+
},
|
|
55
|
+
"radius": {
|
|
56
|
+
"sm": 0,
|
|
57
|
+
"md": 0,
|
|
58
|
+
"lg": 0,
|
|
59
|
+
"pill": 999
|
|
60
|
+
},
|
|
61
|
+
"shadow": {
|
|
62
|
+
"soft": "none",
|
|
63
|
+
"lift": "none"
|
|
64
|
+
},
|
|
65
|
+
"motion": {
|
|
66
|
+
"beatPulse": "drops-only",
|
|
67
|
+
"shake": {
|
|
68
|
+
"on": [
|
|
69
|
+
"drop"
|
|
70
|
+
],
|
|
71
|
+
"maxPerPhrase": 1,
|
|
72
|
+
"maxPx": 10
|
|
73
|
+
},
|
|
74
|
+
"cameraMove": "off",
|
|
75
|
+
"repeatSameMove": false,
|
|
76
|
+
"maxFreezeSec": 0.5,
|
|
77
|
+
"enter": "fade",
|
|
78
|
+
"ease": "linear",
|
|
79
|
+
"durations": {
|
|
80
|
+
"fast": 0.083,
|
|
81
|
+
"base": 0.25,
|
|
82
|
+
"slow": 0.5
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"theme": {
|
|
86
|
+
"inks": [
|
|
87
|
+
"#F2EDE4 신문 종이",
|
|
88
|
+
"#3255A4 미디엄 블루 판",
|
|
89
|
+
"#FF48B0 형광 핑크 판 — 겹치면 곱하기로 보라"
|
|
90
|
+
],
|
|
91
|
+
"texture": "종이결(섬유·얼룩)이 초당 8번 바뀌며 끓는다. 판마다 2–4px 어긋남, 망점(각도 블루 15° 핑크 75°), 잉크는 곱하기로 겹친다. 그라데이션은 망점으로만",
|
|
92
|
+
"movement": "초당 12장으로 끊어 움직인다(on twos). 판은 박에서 찍히고, 찍히는 순간 한 장 어긋났다가 제자리 근처로 앉는다. 미끄러지는 보간·흐림 없음"
|
|
93
|
+
},
|
|
94
|
+
"notes": [
|
|
95
|
+
"리소그래프 잉크 이름: Medium Blue #3255A4 · Fluorescent Pink #FF48B0.",
|
|
96
|
+
"핑크 한 판으로 작은 글을 쓰지 않는다(종이 위 2.6:1). 글은 블루 판, 큰 글은 두 판을 겹쳐 보라 테두리가 생기게.",
|
|
97
|
+
"카메라 이동 없음 — 종이는 책상에 놓여 있다."
|
|
98
|
+
]
|
|
99
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { clamp, randRange, spring, type Style } from "@kasaframe/core";
|
|
2
|
+
import type { ThemeSlots } from "@kasaframe/themes/slots";
|
|
3
|
+
import { layer, letters, partial, shownCount, strokePath, traceCanvas } from "@kasaframe/themes/slotkit";
|
|
4
|
+
import { dropPlate, misregister, paperGrain, printFrames } from "./effects.ts";
|
|
5
|
+
|
|
6
|
+
// 장면 문법 패턴이 테마 이름 없이 부르는 자리 — 잉크 판을 한 장씩 찍는 결로. 움직임은 printFrames 로 초당 12장에 끊는다
|
|
7
|
+
export const slots: ThemeSlots = {
|
|
8
|
+
surface(el, { ctx, seed }) {
|
|
9
|
+
return paperGrain(el, { ctx, seed });
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
// 판 두 장 — 블루 테두리 판이 먼저, 핑크 면 판이 한 장 늦게 어긋나 찍힌다. 둘 다 곱하기라 겹친 곳이 보라
|
|
13
|
+
panel(el, { at, seed, tone }) {
|
|
14
|
+
const box = layer(el, "inset:0", true);
|
|
15
|
+
const face = layer(box, `inset:0;mix-blend-mode:multiply;background:${tone === "accent" ? "var(--kf-accent)" : "color-mix(in srgb, var(--kf-accent) 22%, transparent)"}`);
|
|
16
|
+
const edge = layer(box, "inset:0;mix-blend-mode:multiply;border:6px solid var(--kf-ink)");
|
|
17
|
+
const late = at + 1 / 12;
|
|
18
|
+
return (t) => {
|
|
19
|
+
box.style.visibility = t >= at ? "visible" : "hidden";
|
|
20
|
+
edge.style.transform = toTransform(misregister(t, { seed: `${seed}:edge`, px: 3, at }));
|
|
21
|
+
face.style.visibility = t >= late ? "visible" : "hidden";
|
|
22
|
+
face.style.transform = toTransform(misregister(t, { seed: `${seed}:face`, px: 7, at: late }));
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// 판이 크게 어긋나 찍혔다가 두 장 만에 제자리 — 배율도 초당 12장으로 끊어 내려앉는다
|
|
27
|
+
land(_el, { at, seed }) {
|
|
28
|
+
return (t): Style => {
|
|
29
|
+
if (t < at) return {};
|
|
30
|
+
const q = printFrames(t - at);
|
|
31
|
+
if (q > 0.5) return {};
|
|
32
|
+
const m = misregister(t, { seed, px: 10, at, boil: 0 });
|
|
33
|
+
const k = 1 - clamp(q / 0.5);
|
|
34
|
+
return { x: (m.x ?? 0) * k, y: (m.y ?? 0) * k, scale: spring(q, { from: 1.12, to: 1, stiffness: 300, damping: 18 }) };
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// 글자가 한 장씩 찍히고, 핑크 판 그림자가 어긋나 비친다(앉은 뒤에도 인쇄 결로 끓는다)
|
|
39
|
+
write(el, { text, at, dur, seed }) {
|
|
40
|
+
const spans = letters(el, text);
|
|
41
|
+
return (t) => {
|
|
42
|
+
const n = shownCount(spans.length, printFrames(t), at, dur);
|
|
43
|
+
spans.forEach((s, i) => (s.style.visibility = i < n ? "visible" : "hidden"));
|
|
44
|
+
const m = misregister(t, { seed, px: 3, at });
|
|
45
|
+
el.style.textShadow = `${(m.x ?? 0).toFixed(1)}px ${(m.y ?? 0).toFixed(1)}px 0 color-mix(in srgb, var(--kf-accent) 75%, transparent)`;
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// 블루 선이 드럼처럼 끊어 그어지고, 핑크 판 선이 어긋나 뒤따른다
|
|
50
|
+
trace(el, { points, at, dur, seed, tone }) {
|
|
51
|
+
const { g, clear } = traceCanvas(el, points);
|
|
52
|
+
const blue = getComputedStyle(el).getPropertyValue("--kf-ink").trim() || "#3255A4";
|
|
53
|
+
const pink = getComputedStyle(el).getPropertyValue("--kf-accent").trim() || "#FF48B0";
|
|
54
|
+
const dx = randRange(seed, 0, -5, 5);
|
|
55
|
+
const dy = randRange(seed, 1, -5, 5);
|
|
56
|
+
return (t) => {
|
|
57
|
+
clear();
|
|
58
|
+
const p = clamp(printFrames(t - at) / Math.max(0.05, dur));
|
|
59
|
+
if (p <= 0) return;
|
|
60
|
+
g.lineCap = "round";
|
|
61
|
+
g.lineJoin = "round";
|
|
62
|
+
g.globalCompositeOperation = "multiply";
|
|
63
|
+
g.lineWidth = 10;
|
|
64
|
+
g.strokeStyle = tone === "accent" ? pink : blue;
|
|
65
|
+
strokePath(g, partial(points, p));
|
|
66
|
+
g.save();
|
|
67
|
+
g.translate(dx, dy);
|
|
68
|
+
g.strokeStyle = tone === "accent" ? blue : pink;
|
|
69
|
+
g.globalAlpha = 0.7;
|
|
70
|
+
strokePath(g, partial(points, clamp(p - 0.08)));
|
|
71
|
+
g.restore();
|
|
72
|
+
g.globalAlpha = 1;
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
drop(el, { ctx, drop }) {
|
|
77
|
+
return dropPlate(el, { ctx, drop });
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const toTransform = (s: Style): string => `translate(${(s.x ?? 0).toFixed(2)}px, ${(s.y ?? 0).toFixed(2)}px)`;
|
|
Binary file
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "riso-zine",
|
|
3
|
+
"label": "리소 잡지 — 잉크 판을 한 장씩 찍는다",
|
|
4
|
+
"scheme": "light",
|
|
5
|
+
"colors": {
|
|
6
|
+
"bg": "#F2EDE4",
|
|
7
|
+
"surface": "#FAF7F1",
|
|
8
|
+
"raised": "#E9E2D4",
|
|
9
|
+
"line": "#CFC5B3",
|
|
10
|
+
"ink": "#3255A4",
|
|
11
|
+
"inkSoft": "#3255A4",
|
|
12
|
+
"dim": "#5B74B0",
|
|
13
|
+
"accent": "#FF48B0",
|
|
14
|
+
"accentSoft": "#FFB3DA",
|
|
15
|
+
"accentText": "#3255A4",
|
|
16
|
+
"onAccent": "#F2EDE4",
|
|
17
|
+
"success": "#3255A4",
|
|
18
|
+
"danger": "#FF48B0",
|
|
19
|
+
"warning": "#FF48B0",
|
|
20
|
+
"blue": "#3255A4",
|
|
21
|
+
"pink": "#FF48B0",
|
|
22
|
+
"paper": "#F2EDE4"
|
|
23
|
+
},
|
|
24
|
+
"fonts": {
|
|
25
|
+
"sans": "\"Pretendard Variable\", Pretendard, \"Noto Sans KR\", \"Apple SD Gothic Neo\", sans-serif",
|
|
26
|
+
"display": "\"Black Han Sans\", \"Pretendard Variable\", Pretendard, \"Noto Sans KR\", \"Apple SD Gothic Neo\", sans-serif",
|
|
27
|
+
"mono": "\"JetBrains Mono\", ui-monospace, \"SF Mono\", \"Pretendard Variable\", \"Noto Sans KR\", \"Apple SD Gothic Neo\", monospace",
|
|
28
|
+
"faces": [
|
|
29
|
+
{
|
|
30
|
+
"family": "Black Han Sans",
|
|
31
|
+
"src": "https://cdn.jsdelivr.net/gh/google/fonts@main/ofl/blackhansans/BlackHanSans-Regular.ttf",
|
|
32
|
+
"weight": "400"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"family": "Pretendard Variable",
|
|
36
|
+
"src": "https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2",
|
|
37
|
+
"weight": "45 920"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"family": "JetBrains Mono",
|
|
41
|
+
"src": "https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5/files/jetbrains-mono-latin-wght-normal.woff2",
|
|
42
|
+
"weight": "100 800"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"type": {
|
|
47
|
+
"hero": 220,
|
|
48
|
+
"title": 110,
|
|
49
|
+
"body": 44,
|
|
50
|
+
"caption": 32,
|
|
51
|
+
"weightDisplay": 400,
|
|
52
|
+
"weightBody": 600,
|
|
53
|
+
"tracking": "-0.01em"
|
|
54
|
+
},
|
|
55
|
+
"radius": {
|
|
56
|
+
"sm": 0,
|
|
57
|
+
"md": 0,
|
|
58
|
+
"lg": 0,
|
|
59
|
+
"pill": 999
|
|
60
|
+
},
|
|
61
|
+
"shadow": {
|
|
62
|
+
"soft": "none",
|
|
63
|
+
"lift": "none"
|
|
64
|
+
},
|
|
65
|
+
"motion": {
|
|
66
|
+
"beatPulse": "drops-only",
|
|
67
|
+
"shake": {
|
|
68
|
+
"on": [
|
|
69
|
+
"drop"
|
|
70
|
+
],
|
|
71
|
+
"maxPerPhrase": 1,
|
|
72
|
+
"maxPx": 10
|
|
73
|
+
},
|
|
74
|
+
"cameraMove": "off",
|
|
75
|
+
"repeatSameMove": false,
|
|
76
|
+
"maxFreezeSec": 0.5,
|
|
77
|
+
"enter": "fade",
|
|
78
|
+
"ease": "linear",
|
|
79
|
+
"durations": {
|
|
80
|
+
"fast": 0.083,
|
|
81
|
+
"base": 0.25,
|
|
82
|
+
"slow": 0.5
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"theme": {
|
|
86
|
+
"inks": [
|
|
87
|
+
"#F2EDE4 신문 종이",
|
|
88
|
+
"#3255A4 미디엄 블루 판",
|
|
89
|
+
"#FF48B0 형광 핑크 판 — 겹치면 곱하기로 보라"
|
|
90
|
+
],
|
|
91
|
+
"texture": "종이결(섬유·얼룩)이 초당 8번 바뀌며 끓는다. 판마다 2–4px 어긋남, 망점(각도 블루 15° 핑크 75°), 잉크는 곱하기로 겹친다. 그라데이션은 망점으로만",
|
|
92
|
+
"movement": "초당 12장으로 끊어 움직인다(on twos). 판은 박에서 찍히고, 찍히는 순간 한 장 어긋났다가 제자리 근처로 앉는다. 미끄러지는 보간·흐림 없음"
|
|
93
|
+
},
|
|
94
|
+
"notes": [
|
|
95
|
+
"리소그래프 잉크 이름: Medium Blue #3255A4 · Fluorescent Pink #FF48B0.",
|
|
96
|
+
"핑크 한 판으로 작은 글을 쓰지 않는다(종이 위 2.6:1). 글은 블루 판, 큰 글은 두 판을 겹쳐 보라 테두리가 생기게.",
|
|
97
|
+
"카메라 이동 없음 — 종이는 책상에 놓여 있다."
|
|
98
|
+
]
|
|
99
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "riso-zine",
|
|
3
|
+
"name": "리소 잡지",
|
|
4
|
+
"metaphor": "잉크 판을 한 장씩 찍어 화면을 인쇄한다",
|
|
5
|
+
"status": "approved",
|
|
6
|
+
"approvedAt": "2026-10-08",
|
|
7
|
+
"purposes": [
|
|
8
|
+
"promo",
|
|
9
|
+
"mv",
|
|
10
|
+
"square",
|
|
11
|
+
"shorts",
|
|
12
|
+
"launch"
|
|
13
|
+
],
|
|
14
|
+
"aspect": [
|
|
15
|
+
"16:9",
|
|
16
|
+
"1:1",
|
|
17
|
+
"9:16"
|
|
18
|
+
],
|
|
19
|
+
"effects": [
|
|
20
|
+
{
|
|
21
|
+
"name": "printFrames",
|
|
22
|
+
"kind": "value",
|
|
23
|
+
"does": "t 를 초당 12장으로 끊는다 — 손으로 짠 움직임도 이걸 거쳐 인쇄물처럼 끊긴다",
|
|
24
|
+
"use": "const tq = printFrames(t)"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "misregister",
|
|
28
|
+
"kind": "value",
|
|
29
|
+
"does": "판 어긋남 — 시드로 정한 ±px 에 머물고 찍히는 두 장은 더 어긋났다 앉는다, 초당 12번 끓는다",
|
|
30
|
+
"use": "applyStyle(el, misregister(t, { seed: \"title-pink\", px: 6, at: 1.4 }))"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "plateStamp",
|
|
34
|
+
"kind": "layer",
|
|
35
|
+
"does": "같은 그림을 잉크 판 여러 장으로 찍는다 — 곱하기로 겹쳐 블루+핑크가 보라, 어긋난 가장자리에 두 색",
|
|
36
|
+
"use": "const title = plateStamp(el, { ctx, plates: [{ ink: \"blue\", at: 0 }, { ink: \"pink\", at: 1.4, px: 7 }], build: (p) => { p.textContent = \"170\" } })"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "halftone",
|
|
40
|
+
"kind": "layer",
|
|
41
|
+
"does": "망점 판 — 값이 클수록 점이 크다, grow 로 자라거나 sweep 으로 드럼이 지나간 줄부터 찍힌다, 드롭 구간에선 박마다 부푼다",
|
|
42
|
+
"use": "const dots = halftone(el, { ctx, x, y, w, h, ink: \"pink\", angle: 75, value: (u, v) => 1 - v, at: 1.4 })"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "paperGrain",
|
|
46
|
+
"kind": "layer",
|
|
47
|
+
"does": "종이결 — paper 는 바탕·섬유·티끌, mottle 은 잉크 위 흰 반점. 초당 12번 끓어 멈춘 화면이 안 생긴다",
|
|
48
|
+
"use": "const paper = paperGrain(el, { ctx }); const mottle = paperGrain(top, { ctx, mode: \"mottle\" })"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "sheetDrift",
|
|
52
|
+
"kind": "value",
|
|
53
|
+
"does": "종이 밀림 — 판면이 드럼에 물려 한 방향으로 끌려가며 조금 돈다(초당 12장), 다 찍힌 판면도 쉬지 않는다",
|
|
54
|
+
"use": "applyStyle(sheet, sheetDrift(t, { from: bar, seed: \"p3\", dur: 1.41 }))"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "drumPass",
|
|
58
|
+
"kind": "value",
|
|
59
|
+
"does": "드럼이 종이 위를 지나가며 판이 찍힌다 — 지나간 쪽만 보이는 clip(초당 24장)",
|
|
60
|
+
"use": "plateStamp(el, { …, style: (t) => drumPass(t, { at: 2.8, dir: \"right\" }) })"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "sheetFeed",
|
|
64
|
+
"kind": "layer",
|
|
65
|
+
"does": "장면 끝에 새 종이가 들어와 앞 장을 덮는다 — 다음 장면은 빈 종이에서 판을 찍기 시작",
|
|
66
|
+
"use": "const feed = sheetFeed(el, { ctx, at: ctx.dur - 0.42, from: \"bottom\" })"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "dropPlate",
|
|
70
|
+
"kind": "layer",
|
|
71
|
+
"does": "드롭 — 핑크 판이 통째로 찍혔다 걷히고 망점 고리가 퍼진다, 흔들림을 돌려준다",
|
|
72
|
+
"use": "const s = plate(t); applyStyle(content, s.shake) // plate = dropPlate(el, { ctx, drop: 0 })"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|