kasaframe 0.1.4 → 0.1.6
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/NOTICE +311 -0
- package/README.md +18 -5
- package/docs/AGENTS.md +2 -1
- package/package.json +1 -1
- package/packages/adapters/src/project.ts +2 -0
- package/packages/check/package.json +1 -0
- package/packages/check/src/check.ts +8 -2
- package/packages/check/src/rules/frames.ts +4 -5
- package/packages/cli/src/commands/doctor.ts +15 -2
- package/packages/cli/src/commands/fonts.ts +118 -0
- package/packages/cli/src/commands/make.ts +15 -5
- package/packages/cli/src/commands/render.ts +34 -7
- package/packages/cli/src/commands/update.ts +66 -0
- package/packages/cli/src/fonts.ts +405 -0
- package/packages/cli/src/kf.ts +5 -0
- package/packages/cli/src/mix.ts +66 -4
- package/packages/cli/src/segments.ts +1 -1
- package/packages/cli/src/sfx.ts +429 -0
- package/packages/cli/src/update.ts +250 -0
- package/packages/core/src/frame.ts +7 -4
- package/packages/core/src/index.ts +3 -1
- package/packages/core/src/project.ts +19 -0
- package/packages/core/src/sfx.ts +70 -0
- package/packages/director/src/assemble.ts +7 -4
- package/packages/director/src/index.ts +1 -1
- package/packages/director/src/pattern.ts +2 -0
- package/packages/director/src/scene.ts +14 -5
- package/packages/director/src/transitions.ts +21 -8
- package/packages/motion/src/enter.ts +7 -1
- package/packages/motion/src/impact.ts +5 -2
- package/packages/motion/src/moves/dress.ts +15 -2
- package/packages/motion/src/moves/menu.ts +11 -5
- package/packages/motion/src/transition.ts +3 -1
- package/packages/motion/src/transition3d/index.ts +3 -1
- package/packages/motion/src/transition3d/live.ts +5 -3
- package/packages/patterns/src/bars/rank.ts +6 -7
- package/packages/patterns/src/before-after/shrink.ts +3 -4
- package/packages/patterns/src/before-after/strike.ts +4 -5
- package/packages/patterns/src/code/terminal.ts +25 -16
- package/packages/patterns/src/end/lockup.ts +13 -10
- package/packages/patterns/src/end/slam.ts +7 -5
- package/packages/patterns/src/hook-number/counter.ts +15 -9
- package/packages/patterns/src/hook-number/slam.ts +6 -8
- package/packages/patterns/src/kit.ts +281 -58
- package/packages/patterns/src/limit/gauge.ts +16 -11
- package/packages/patterns/src/quote/karaoke.ts +17 -12
- package/packages/patterns/src/sfx.ts +80 -0
- package/packages/patterns/src/term-reveal/chips.ts +24 -10
- package/packages/patterns/src/term-reveal/expand.ts +17 -13
- package/packages/patterns/src/title/mask.ts +9 -8
- package/packages/patterns/src/title/slam.ts +1 -1
- package/packages/patterns/src/types.ts +1 -0
- package/packages/plan/src/asks.ts +1 -1
- package/packages/plan/src/brief.ts +5 -2
- package/packages/plan/src/themes.ts +8 -2
- package/packages/themes/kit/THEME-MAKE.md +2 -2
- package/packages/themes/kit/fonts/display.json +3517 -0
- package/packages/themes/kit/fonts/sans.json +5155 -0
- package/packages/themes/kit/fonts/serif.json +5229 -0
- package/packages/themes/kit/fonts.json +243 -79
- package/packages/themes/package.json +3 -1
- package/packages/themes/src/fontfile.ts +183 -0
- package/packages/themes/src/fonts.ts +296 -0
- package/packages/themes/src/index.ts +32 -2
- package/packages/themes/src/look.ts +34 -8
- package/packages/themes/src/slots.ts +32 -2
- package/packages/themes/src/types.ts +33 -0
- package/packages/themes/src/vary.ts +35 -34
- package/presets/kawaii-pastel.json +2 -2
- package/sfx/README.md +82 -0
- package/sfx/click/appear.wav +0 -0
- package/sfx/click/burst.wav +0 -0
- package/sfx/click/drop.wav +0 -0
- package/sfx/click/end.wav +0 -0
- package/sfx/click/hop.wav +0 -0
- package/sfx/click/land.wav +0 -0
- package/sfx/click/select.wav +0 -0
- package/sfx/click/stick.wav +0 -0
- package/sfx/click/tick.wav +0 -0
- package/sfx/click/type.wav +0 -0
- package/sfx/click/whoosh.wav +0 -0
- package/sfx/pop/appear.wav +0 -0
- package/sfx/pop/burst.wav +0 -0
- package/sfx/pop/drop.wav +0 -0
- package/sfx/pop/end.wav +0 -0
- package/sfx/pop/hop.wav +0 -0
- package/sfx/pop/land.wav +0 -0
- package/sfx/pop/select.wav +0 -0
- package/sfx/pop/stick.wav +0 -0
- package/sfx/pop/tick.wav +0 -0
- package/sfx/pop/type.wav +0 -0
- package/sfx/pop/whoosh.wav +0 -0
- package/sfx/tags.json +545 -0
- package/sfx/ui/appear.wav +0 -0
- package/sfx/ui/burst.wav +0 -0
- package/sfx/ui/drop.wav +0 -0
- package/sfx/ui/end.wav +0 -0
- package/sfx/ui/hop.wav +0 -0
- package/sfx/ui/land.wav +0 -0
- package/sfx/ui/select.wav +0 -0
- package/sfx/ui/stick.wav +0 -0
- package/sfx/ui/tick.wav +0 -0
- package/sfx/ui/type.wav +0 -0
- package/sfx/ui/whoosh.wav +0 -0
- package/skills/kasaframe/SKILL.md +1 -0
- package/themes/blueprint/sample/style.json +5 -5
- package/themes/blueprint/style.json +5 -5
- package/themes/blueprint/theme.json +3 -1
- package/themes/blueprint/variants/deep-rose-suit.json +1 -1
- package/themes/blueprint/variants/navy-coral-2.json +1 -1
- package/themes/blueprint/variants/navy-coral-suit.json +1 -1
- package/themes/blueprint/variants/navy-orange-2.json +1 -1
- package/themes/blueprint/variants/navy-orange-suit.json +1 -1
- package/themes/cartography/sample/style.json +2 -2
- package/themes/cartography/style.json +2 -2
- package/themes/cartography/theme.json +3 -1
- package/themes/cartography/variants/deep-plum.json +1 -1
- package/themes/cartography/variants/frost-teal.json +1 -1
- package/themes/cartography/variants/navy-green.json +1 -1
- package/themes/circuit-board/sample/style.json +2 -2
- package/themes/circuit-board/style.json +2 -2
- package/themes/circuit-board/theme.json +3 -1
- package/themes/circuit-board/variants/dusk-gold-pretendard.json +1 -1
- package/themes/circuit-board/variants/navy-gold-grain.json +1 -1
- package/themes/circuit-board/variants/wine-gold-pretendard.json +1 -1
- package/themes/clay-toy/sample/style.json +2 -2
- package/themes/clay-toy/style.json +2 -2
- package/themes/clay-toy/theme.json +3 -1
- package/themes/clay-toy/variants/blush-coral-grain.json +1 -1
- package/themes/clay-toy/variants/chalk-teal.json +1 -1
- package/themes/clay-toy/variants/frost-sky.json +1 -1
- package/themes/clay-toy/variants/frost-teal.json +1 -1
- package/themes/clay-toy/variants/lilac-plum-round.json +1 -1
- package/themes/clay-toy/variants/lilac-plum.json +1 -1
- package/themes/clay-toy/variants/sage-indigo.json +1 -1
- package/themes/conveyor-factory/sample/style.json +3 -3
- package/themes/conveyor-factory/style.json +3 -3
- package/themes/conveyor-factory/theme.json +3 -1
- package/themes/conveyor-factory/variants/cocoa-gold.json +1 -1
- package/themes/conveyor-factory/variants/navy-gold.json +1 -1
- package/themes/conveyor-factory/variants/slate-amber-2.json +1 -1
- package/themes/conveyor-factory/variants/slate-amber-suit.json +1 -1
- package/themes/conveyor-factory/variants/slate-gold-bold.json +1 -1
- package/themes/data-journal/theme.json +3 -1
- package/themes/data-journal/variants/deep-coral.json +1 -1
- package/themes/data-journal/variants/navy-lime.json +1 -1
- package/themes/data-journal/variants/wine-indigo.json +1 -1
- package/themes/debug-hud/sample/style.json +1 -1
- package/themes/debug-hud/style.json +1 -1
- package/themes/debug-hud/theme.json +2 -1
- package/themes/debug-hud/variants/cocoa-teal.json +2 -2
- package/themes/debug-hud/variants/deep-teal-scan.json +2 -2
- package/themes/debug-hud/variants/dusk-plum.json +2 -2
- package/themes/debug-hud/variants/forest-lime.json +2 -2
- package/themes/debug-hud/variants/slate-green.json +2 -2
- package/themes/debug-hud/variants/wine-gold.json +2 -2
- package/themes/depth-flight/sample/style.json +1 -1
- package/themes/depth-flight/style.json +1 -1
- package/themes/depth-flight/theme.json +3 -1
- package/themes/depth-flight/variants/cocoa-cyan.json +1 -1
- package/themes/depth-flight/variants/cocoa-violet.json +1 -1
- package/themes/depth-flight/variants/deep-sky.json +1 -1
- package/themes/depth-flight/variants/forest-blue.json +1 -1
- package/themes/depth-flight/variants/navy-sky-grain.json +1 -1
- package/themes/depth-flight/variants/navy-sky.json +1 -1
- package/themes/depth-flight/variants/night-teal.json +1 -1
- package/themes/depth-flight/variants/slate-indigo.json +1 -1
- package/themes/depth-flight/variants/slate-violet.json +1 -1
- package/themes/film-reel/sample/style.json +2 -2
- package/themes/film-reel/style.json +2 -2
- package/themes/film-reel/theme.json +3 -1
- package/themes/film-reel/variants/chalk-pink.json +1 -1
- package/themes/film-reel/variants/lilac-gold.json +1 -1
- package/themes/film-reel/variants/lilac-violet.json +1 -1
- package/themes/glass-light/sample/style.json +1 -1
- package/themes/glass-light/style.json +1 -1
- package/themes/glass-light/theme.json +3 -1
- package/themes/glass-light/variants/blush-pink.json +1 -1
- package/themes/glass-light/variants/blush-plum.json +1 -1
- package/themes/glass-light/variants/cream-violet.json +1 -1
- package/themes/glass-light/variants/frost-sky-suit.json +1 -1
- package/themes/glass-light/variants/frost-sky.json +1 -1
- package/themes/glass-light/variants/sage-green.json +1 -1
- package/themes/ink-wash/sample/style.json +3 -3
- package/themes/ink-wash/style.json +3 -3
- package/themes/ink-wash/theme.json +3 -1
- package/themes/iso-diorama/sample/style.json +1 -1
- package/themes/iso-diorama/style.json +1 -1
- package/themes/iso-diorama/theme.json +3 -1
- package/themes/iso-diorama/variants/chalk-plum.json +1 -1
- package/themes/iso-diorama/variants/cocoa-indigo.json +1 -1
- package/themes/iso-diorama/variants/dusk-blue.json +1 -1
- package/themes/iso-diorama/variants/dusk-coral.json +1 -1
- package/themes/iso-diorama/variants/dusk-jade.json +1 -1
- package/themes/iso-diorama/variants/forest-cyan.json +1 -1
- package/themes/iso-diorama/variants/frost-green.json +1 -1
- package/themes/iso-diorama/variants/frost-teal.json +1 -1
- package/themes/iso-diorama/variants/navy-amber.json +1 -1
- package/themes/isotype/sample/style.json +2 -2
- package/themes/isotype/style.json +2 -2
- package/themes/isotype/theme.json +2 -1
- package/themes/isotype/variants/blush-rose.json +1 -1
- package/themes/isotype/variants/chalk-coral.json +1 -1
- package/themes/isotype/variants/chalk-orange.json +1 -1
- package/themes/isotype/variants/frost-amber.json +1 -1
- package/themes/isotype/variants/frost-coral.json +1 -1
- package/themes/isotype/variants/frost-orange.json +1 -1
- package/themes/isotype/variants/sand-amber.json +1 -1
- package/themes/kawaii-sticker/effects.ts +15 -3
- package/themes/kawaii-sticker/sample/style.json +2 -2
- package/themes/kawaii-sticker/style.json +2 -2
- package/themes/kawaii-sticker/theme.json +4 -1
- package/themes/kawaii-sticker/variants/cream-gold.json +1 -1
- package/themes/kawaii-sticker/variants/dusk-green.json +1 -1
- package/themes/kawaii-sticker/variants/dusk-indigo.json +1 -1
- package/themes/kawaii-sticker/variants/dusk-sky.json +1 -1
- package/themes/kawaii-sticker/variants/dusk-teal.json +1 -1
- package/themes/kawaii-sticker/variants/frost-blue.json +1 -1
- package/themes/kawaii-sticker/variants/frost-plum.json +1 -1
- package/themes/kawaii-sticker/variants/lilac-violet.json +1 -1
- package/themes/kawaii-sticker/variants/navy-gold.json +1 -1
- package/themes/kawaii-sticker/variants/navy-plum.json +1 -1
- package/themes/lab-notebook/sample/style.json +3 -3
- package/themes/lab-notebook/style.json +3 -3
- package/themes/lab-notebook/theme.json +2 -1
- package/themes/lab-notebook/variants/blush-orange.json +1 -1
- package/themes/lab-notebook/variants/chalk-coral.json +1 -1
- package/themes/lab-notebook/variants/chalk-orange.json +1 -1
- package/themes/lab-notebook/variants/chalk-rose.json +1 -1
- package/themes/lab-notebook/variants/lilac-rose.json +1 -1
- package/themes/lab-notebook/variants/sage-rose.json +1 -1
- package/themes/lab-notebook/variants/sand-orange.json +1 -1
- package/themes/lab-notebook/variants/snow-orange.json +1 -1
- package/themes/lab-notebook/variants/snow-rose.json +1 -1
- package/themes/manga-panel/sample/style.json +3 -3
- package/themes/manga-panel/style.json +3 -3
- package/themes/manga-panel/theme.json +3 -1
- package/themes/manga-panel/variants/chalk-cyan-dots.json +1 -1
- package/themes/manga-panel/variants/chalk-rose.json +1 -1
- package/themes/manga-panel/variants/snow-cyan.json +1 -1
- package/themes/manga-panel/variants/snow-magenta-dots.json +1 -1
- package/themes/marble-run/sample/style.json +2 -2
- package/themes/marble-run/style.json +2 -2
- package/themes/marble-run/theme.json +3 -1
- package/themes/marble-run/variants/slate-orange.json +1 -1
- package/themes/neon-sign/sample/style.json +2 -2
- package/themes/neon-sign/style.json +2 -2
- package/themes/neon-sign/theme.json +2 -1
- package/themes/neon-sign/variants/dusk-plum.json +1 -1
- package/themes/neon-sign/variants/forest-magenta.json +1 -1
- package/themes/neon-sign/variants/night-pink.json +1 -1
- package/themes/neon-sign/variants/night-violet.json +1 -1
- package/themes/neon-sign/variants/slate-violet.json +1 -1
- package/themes/newspaper/sample/style.json +2 -2
- package/themes/newspaper/style.json +2 -2
- package/themes/newspaper/theme.json +2 -1
- package/themes/newspaper/variants/blush-amber.json +1 -1
- package/themes/newspaper/variants/chalk-magenta.json +1 -1
- package/themes/newspaper/variants/frost-sky.json +1 -1
- package/themes/newspaper/variants/lilac-green.json +1 -1
- package/themes/newspaper/variants/sage-lime.json +1 -1
- package/themes/og-measure/THEME.md +41 -6
- package/themes/og-measure/effects.ts +236 -115
- package/themes/og-measure/sample/assets/brand/og-logo.svg +11 -11
- package/themes/og-measure/sample/lib/data.ts +6 -0
- package/themes/og-measure/sample/scenes/end.ts +14 -10
- package/themes/og-measure/sample/scenes/gather.ts +4 -1
- package/themes/og-measure/sample/scenes/models.ts +5 -2
- package/themes/og-measure/sample/scenes/one.ts +9 -6
- package/themes/og-measure/sample/scenes/price.ts +8 -3
- package/themes/og-measure/sample/style.json +30 -35
- package/themes/og-measure/slots.ts +54 -30
- package/themes/og-measure/still.png +0 -0
- package/themes/og-measure/style.json +30 -35
- package/themes/og-measure/theme.json +72 -49
- package/themes/og-measure/variants/snow-blue.json +90 -0
- package/themes/orbit-system/sample/style.json +3 -3
- package/themes/orbit-system/style.json +3 -3
- package/themes/orbit-system/theme.json +3 -1
- package/themes/orbit-system/variants/cocoa-amber.json +1 -1
- package/themes/orbit-system/variants/cocoa-cyan.json +1 -1
- package/themes/orbit-system/variants/dusk-magenta.json +1 -1
- package/themes/orbit-system/variants/dusk-violet.json +1 -1
- package/themes/orbit-system/variants/forest-coral.json +1 -1
- package/themes/orbit-system/variants/wine-amber.json +1 -1
- package/themes/orbit-system/variants/wine-magenta.json +1 -1
- package/themes/origami-fold/sample/style.json +1 -1
- package/themes/origami-fold/style.json +1 -1
- package/themes/origami-fold/theme.json +3 -1
- package/themes/origami-fold/variants/deep-amber-sunflower.json +1 -1
- package/themes/origami-fold/variants/deep-orange.json +1 -1
- package/themes/origami-fold/variants/forest-coral.json +1 -1
- package/themes/origami-fold/variants/forest-pink.json +1 -1
- package/themes/origami-fold/variants/frost-amber-paper.json +1 -1
- package/themes/origami-fold/variants/sage-coral-sunflower.json +1 -1
- package/themes/origami-fold/variants/sage-coral.json +1 -1
- package/themes/origami-fold/variants/sage-pink-round.json +1 -1
- package/themes/origami-fold/variants/sage-pink.json +1 -1
- package/themes/paper-cutout/sample/style.json +2 -2
- package/themes/paper-cutout/style.json +2 -2
- package/themes/paper-cutout/theme.json +3 -1
- package/themes/paper-cutout/variants/blush-violet.json +1 -1
- package/themes/paper-cutout/variants/frost-lime.json +1 -1
- package/themes/paper-cutout/variants/lilac-gold.json +1 -1
- package/themes/paper-cutout/variants/sage-cyan.json +1 -1
- package/themes/paper-cutout/variants/sage-green.json +1 -1
- package/themes/paper-cutout/variants/sage-pink.json +1 -1
- package/themes/paper-cutout/variants/sand-blue.json +1 -1
- package/themes/pixel-quest/theme.json +2 -1
- package/themes/receipt/sample/style.json +2 -2
- package/themes/receipt/style.json +2 -2
- package/themes/riso-zine/sample/style.json +2 -2
- package/themes/riso-zine/style.json +2 -2
- package/themes/riso-zine/theme.json +3 -1
- package/themes/riso-zine/variants/chalk-lime.json +1 -1
- package/themes/riso-zine/variants/frost-green.json +1 -1
- package/themes/riso-zine/variants/lilac-plum.json +1 -1
- package/themes/riso-zine/variants/lilac-violet.json +1 -1
- package/themes/server-hall/sample/style.json +2 -2
- package/themes/server-hall/style.json +2 -2
- package/themes/server-hall/theme.json +3 -1
- package/themes/server-hall/variants/night-indigo.json +1 -1
- package/themes/server-hall/variants/wine-plum.json +1 -1
- package/themes/subway-map/sample/style.json +2 -2
- package/themes/subway-map/style.json +2 -2
- package/themes/subway-map/theme.json +3 -1
- package/themes/subway-map/variants/deep-green.json +1 -1
- package/themes/subway-map/variants/deep-teal.json +1 -1
- package/themes/subway-map/variants/frost-jade.json +1 -1
- package/themes/subway-map/variants/frost-teal.json +1 -1
- package/themes/subway-map/variants/slate-green.json +1 -1
- package/themes/subway-map/variants/snow-jade.json +1 -1
- package/themes/swiss-poster/sample/style.json +2 -2
- package/themes/swiss-poster/style.json +2 -2
- package/themes/swiss-poster/theme.json +3 -1
- package/themes/swiss-poster/variants/chalk-plum.json +1 -1
- package/themes/swiss-poster/variants/cocoa-cyan.json +1 -1
- package/themes/swiss-poster/variants/dusk-magenta.json +1 -1
- package/themes/swiss-poster/variants/frost-indigo.json +1 -1
- package/themes/swiss-poster/variants/slate-orange.json +1 -1
- package/themes/water-works/sample/style.json +1 -1
- package/themes/water-works/style.json +1 -1
- package/themes/water-works/theme.json +3 -1
- package/themes/water-works/variants/chalk-cyan.json +1 -1
- package/themes/water-works/variants/frost-indigo.json +1 -1
- package/themes/water-works/variants/sand-amber.json +1 -1
- package/themes/water-works/variants/sand-plum.json +1 -1
- package/themes/whiteboard/sample/style.json +2 -2
- package/themes/whiteboard/style.json +2 -2
- package/themes/whiteboard/theme.json +3 -1
- package/themes/whiteboard/variants/chalk-coral.json +1 -1
- package/themes/whiteboard/variants/cream-lime.json +1 -1
- package/themes/whiteboard/variants/frost-teal.json +1 -1
- package/themes/whiteboard/variants/lilac-indigo.json +1 -1
- package/themes/whiteboard/variants/sage-plum.json +1 -1
- package/themes/whiteboard/variants/snow-cyan.json +1 -1
- package/themes/whiteboard/variants/snow-green.json +1 -1
- package/themes/whiteboard/variants/snow-magenta.json +1 -1
- package/themes/og-measure/sample/assets/brand/og-logo-full.svg +0 -12
- package/themes/og-measure/variants/chalk-orange.json +0 -102
- package/themes/og-measure/variants/cocoa-amber.json +0 -138
- package/themes/og-measure/variants/cocoa-cyan.json +0 -138
- package/themes/og-measure/variants/cocoa-gold.json +0 -129
- package/themes/og-measure/variants/cream-lime.json +0 -137
- package/themes/og-measure/variants/deep-jade.json +0 -100
- package/themes/og-measure/variants/dusk-violet.json +0 -133
- package/themes/og-measure/variants/forest-cyan.json +0 -123
- package/themes/og-measure/variants/frost-amber.json +0 -129
- package/themes/og-measure/variants/frost-cyan.json +0 -133
- package/themes/og-measure/variants/lilac-plum.json +0 -127
- package/themes/og-measure/variants/lilac-violet.json +0 -139
- package/themes/og-measure/variants/sage-green.json +0 -137
- package/themes/og-measure/variants/wine-jade.json +0 -127
- package/themes/og-measure/variants/wine-plum.json +0 -127
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clamp, spring, applyStyle } from "@kasaframe/core";
|
|
2
2
|
import { typeText } from "@kasaframe/motion";
|
|
3
|
-
import { area, beatStops, glider, moving, node, slotsOf } from "../kit.ts";
|
|
3
|
+
import { area, beatStops, dwells, glider, markOf, moving, node, readOver, reread, slotsOf } from "../kit.ts";
|
|
4
4
|
import type { Pattern } from "../types.ts";
|
|
5
5
|
|
|
6
6
|
export interface CodeContent {
|
|
@@ -22,13 +22,13 @@ const rowsOf = (c: CodeContent): Row[] => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* 명령·코드 — 창 판 안에서 명령은 자모 단위로 쳐지고(블록 커서가 끝을 따라간다), 출력·코드 줄은 흘러 찍힌다. 지금 줄 뒤엔
|
|
26
|
-
* 다 서면 짚개가 마지막 줄(결과)
|
|
25
|
+
* 명령·코드 — 창 판 안에서 명령은 자모 단위로 쳐지고(블록 커서가 끝을 따라간다), 출력·코드 줄은 흘러 찍힌다. 지금 줄 뒤엔 짚는 칸이 글과 함께 늘어난다.
|
|
26
|
+
* 다 서면 줄이 둘 넘을 때 짚개가 마지막 줄(결과)부터 짚는다(머무는 테마는 목소리가 다른 줄을 말할 때만 그리로). 치는 빠르기는 박아 둔다(명령 초당 36타·출력 90자) — 장면이 길다고 느리게 치지 않는다.
|
|
27
27
|
*/
|
|
28
28
|
const pattern: Pattern<CodeContent> = {
|
|
29
29
|
id: "code.terminal",
|
|
30
30
|
type: "code",
|
|
31
|
-
does: "창 판 안에서 명령이 쳐지고 출력이 흘러 찍히며 지금 줄이 짚이고, 다 서면 짚개가 결과
|
|
31
|
+
does: "창 판 안에서 명령이 쳐지고 출력이 흘러 찍히며 지금 줄이 짚이고, 다 서면 짚개가 결과 줄부터 짚는다",
|
|
32
32
|
energy: ["mid"],
|
|
33
33
|
family: "type",
|
|
34
34
|
camera: ["none"],
|
|
@@ -72,7 +72,9 @@ const pattern: Pattern<CodeContent> = {
|
|
|
72
72
|
const text = node(line, "display:inline");
|
|
73
73
|
return { r, line, prompt, text };
|
|
74
74
|
});
|
|
75
|
-
const
|
|
75
|
+
const mark = markOf(kit, ctx);
|
|
76
|
+
// 블록 커서는 지금 줄 칸 위에 선다 — 테마 짚음 칸이 옅으면 칸 위 글색(onAccent)이 바탕에 묻혀 강조색으로
|
|
77
|
+
const cursor = node(body, `position:absolute;left:0;top:0;width:0.6em;height:1.2em;background:${mark ? "var(--kf-accent)" : "var(--kf-on-accent)"};visibility:hidden`);
|
|
76
78
|
|
|
77
79
|
// 시각 — 명령은 초당 36타로 쳐지고, 출력·코드 줄은 초당 90자로 흘러 찍힌다. 줄 사이는 0.04초 — 박을 기다리면 그 사이가 멈춘 화면이다
|
|
78
80
|
const cps = (r: Row) => (r.typed ? 36 : 90);
|
|
@@ -84,11 +86,16 @@ const pattern: Pattern<CodeContent> = {
|
|
|
84
86
|
}
|
|
85
87
|
const doneAt = at;
|
|
86
88
|
const result = lines[lines.length - 1];
|
|
87
|
-
const point = glider(body, [result
|
|
88
|
-
//
|
|
89
|
-
const
|
|
89
|
+
const point = glider(body, [result, ...lines.slice(0, -1)].map((l) => ({ el: l.line, text: l.r.text })), { kit, ctx, from: doneAt, pad: 0.15 });
|
|
90
|
+
// 한 줄뿐이고 훑는 테마면 짚개 대신 다 친 그 줄을 박마다 다시 짚는다
|
|
91
|
+
const again = lines.length < 2 && !dwells(kit, ctx) ? readOver(result.line, `${result.r.typed ? "$ " : ""}${result.r.text}`, ctx) : null;
|
|
92
|
+
const againStops = again ? beatStops(kit.hits, doneAt, ctx.dur) : [];
|
|
93
|
+
// 지금 줄 — 치거나 찍히는 줄 뒤에 짚는 칸이 붙어 글과 함께 늘어난다(작은 글 치기만으로는 화면이 바뀐 것으로 안 읽힌다). 칸 모양·줄 옮김은 테마 짚음
|
|
94
|
+
const nowBar = node(body, `position:absolute;left:0;top:0;z-index:-1;visibility:hidden${mark ? "" : ";background:var(--kf-accent)"}`);
|
|
95
|
+
const nowMark = mark?.(nowBar) ?? null;
|
|
96
|
+
const nowInk = nowMark ? nowMark.ink : "var(--kf-on-accent)";
|
|
97
|
+
const lineBox = (l: HTMLElement, extra = 0) => ({ x: -px * 0.25, y: l.offsetTop - px * 0.1, w: l.offsetWidth + px * 0.5 + extra, h: l.offsetHeight + px * 0.2 });
|
|
90
98
|
body.style.isolation = "isolate";
|
|
91
|
-
const stops = beatStops(kit.hits, doneAt, ctx.dur);
|
|
92
99
|
const lands = lines.map((l, i) => slots.land(l.line, { ctx, at: starts[i], seed: `${kit.seed}:l${i}` }));
|
|
93
100
|
|
|
94
101
|
return (t: number) => {
|
|
@@ -111,21 +118,23 @@ const pattern: Pattern<CodeContent> = {
|
|
|
111
118
|
nowBar.style.visibility = live ? "visible" : "hidden";
|
|
112
119
|
lines.forEach((l) => {
|
|
113
120
|
const on = l === live;
|
|
114
|
-
l.text.style.color = on ?
|
|
115
|
-
if (l.prompt) l.prompt.style.color = on ?
|
|
121
|
+
l.text.style.color = on && nowInk ? nowInk : "";
|
|
122
|
+
if (l.prompt) l.prompt.style.color = on && nowInk ? nowInk : "var(--kf-accent-text, var(--kf-accent))";
|
|
116
123
|
});
|
|
117
124
|
if (live) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
nowBar.style.
|
|
121
|
-
nowBar.style.
|
|
125
|
+
const box = lineBox(live.line, live.r.typed && cur ? px * 0.7 : 0);
|
|
126
|
+
const b = nowMark ? nowMark.at(k > 0 ? lineBox(lines[k - 1].line) : null, box, clamp((t - starts[k]) / 0.3)) : box;
|
|
127
|
+
nowBar.style.transform = `translate(${b.x.toFixed(1)}px, ${b.y.toFixed(1)}px)`;
|
|
128
|
+
nowBar.style.width = `${b.w.toFixed(1)}px`;
|
|
129
|
+
nowBar.style.height = `${b.h.toFixed(1)}px`;
|
|
122
130
|
}
|
|
123
131
|
// 블록 커서는 치는 줄의 끝을 따라간다 — 다 치면 결과 줄 끝에서 짚개에 자리를 내준다
|
|
124
132
|
const c2 = cur as { line: HTMLElement; chars: number } | null;
|
|
125
133
|
cursor.style.visibility = c2 && t < doneAt ? "visible" : "hidden";
|
|
126
134
|
// 접힌 줄은 몇째 줄 몇째 칸인지로 센다(고정폭이라 한 줄 = wrap 칸)
|
|
127
135
|
if (c2) cursor.style.transform = `translate(${((c2.chars % wrap) * 0.6).toFixed(2)}em, ${(c2.line.offsetTop / px + Math.floor(c2.chars / wrap) * 1.45 + 0.12).toFixed(3)}em)`;
|
|
128
|
-
point(t
|
|
136
|
+
point(t);
|
|
137
|
+
again?.(reread(t, againStops));
|
|
129
138
|
};
|
|
130
139
|
},
|
|
131
140
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { applyStyle, clamp, combine, spring } from "@kasaframe/core";
|
|
2
2
|
import { fitSize, textEm } from "@kasaframe/motion/moves";
|
|
3
|
-
import { area, beatStops, fitOnce, glider, moving, node, riseName, slotsOf } from "../kit.ts";
|
|
3
|
+
import { area, beatStops, dwells, fitOnce, followSpoken, glider, moving, node, reread, riseName, sayTimes, slotsOf } from "../kit.ts";
|
|
4
4
|
import type { Pattern } from "../types.ts";
|
|
5
5
|
|
|
6
6
|
export interface EndContent {
|
|
@@ -12,12 +12,12 @@ export interface EndContent {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* 끝 카드 — 로고가 앉고 이름이 글자마다
|
|
15
|
+
* 끝 카드 — 로고가 앉고 이름이 글자마다 서고 한 줄·주소가 찍힌다. 한 줄·주소가 있으면 짚개가 이름부터 짚는다(머무는 테마는 목소리가 한 줄·주소를 말할 때만 그리로).
|
|
16
16
|
*/
|
|
17
17
|
const pattern: Pattern<EndContent> = {
|
|
18
18
|
id: "end.lockup",
|
|
19
19
|
type: "end",
|
|
20
|
-
does: "로고가 앉고 이름이 서고 한 줄·주소가
|
|
20
|
+
does: "로고가 앉고 이름이 서고 한 줄·주소가 찍히면, 짚개가 이름부터 짚는다",
|
|
21
21
|
energy: ["low", "mid"],
|
|
22
22
|
family: "mask",
|
|
23
23
|
camera: ["none"],
|
|
@@ -57,14 +57,17 @@ const pattern: Pattern<EndContent> = {
|
|
|
57
57
|
const logoAt = 0;
|
|
58
58
|
const nameAt = logo ? 0.15 : kit.first ? -0.2 : 0;
|
|
59
59
|
const nameEnd = nameAt + each * (count - 1) + 0.3;
|
|
60
|
-
|
|
60
|
+
// 머무는 짚개 테마는 한 줄·주소를 목소리가 그것을 말할 때 찍는다(못 들으면 이름이 선 뒤부터 장면 끝 무렵까지 고르게). 찍힐 때마다(없으면
|
|
61
|
+
// 이름이 서면) 카메라가 그쪽으로 다가간다 — 끝 카드가 일찍 다 서고 남은 시간이 비지 않게. 훑는 테마는 이름이 서자마자 잇달아 찍는다
|
|
61
62
|
const lineDur = line ? clamp([...c.line!].length * 0.03, 0.25, 0.6) : 0;
|
|
62
|
-
const urlAt = lineAt + lineDur;
|
|
63
63
|
const urlDur = url ? clamp([...c.url!].length * 0.03, 0.25, 0.6) : 0;
|
|
64
|
-
|
|
65
|
-
const
|
|
64
|
+
const [lineAt, urlWant] = dwells(kit, ctx) ? sayTimes(kit, [c.line, c.url], nameEnd, Math.max(nameEnd + 0.3, ctx.dur - 0.9)) : [nameEnd, nameEnd + lineDur];
|
|
65
|
+
const urlAt = Math.max(urlWant, lineAt + lineDur);
|
|
66
|
+
followSpoken(kit, ctx, line || url ? [...(line ? [{ at: lineAt, el: line }] : []), ...(url ? [{ at: urlAt, el: url }] : [])] : [{ at: nameEnd, el: name }]);
|
|
67
|
+
// 짚개는 이름이 서면 이름·한 줄·주소를 짚는다(짚기 방식은 테마 짚음). 한 줄·주소가 없고 훑는 테마면 이름 글자를 박마다 다시 짚는다
|
|
68
|
+
const point = glider(host, [{ el: name, text: c.title }, ...(line ? [{ el: line, text: c.line }] : []), ...(url ? [{ el: url, text: c.url }] : [])], { kit, ctx, from: nameEnd - 0.15 });
|
|
69
|
+
const again = !line && !url && !dwells(kit, ctx) ? beatStops(kit.hits, nameEnd - 0.15, ctx.dur) : null;
|
|
66
70
|
const fit = fitOnce(name, w * 0.86, h * (vertical ? 0.18 : 0.3), c.title);
|
|
67
|
-
const stops = beatStops(kit.hits, nameEnd - 0.15, ctx.dur);
|
|
68
71
|
|
|
69
72
|
const writeLine = line ? slots.write(line, { ctx, text: c.line!, at: lineAt, dur: lineDur, seed: `${kit.seed}:line` }) : null;
|
|
70
73
|
const writeUrl = url ? slots.write(url, { ctx, text: c.url!, at: urlAt, dur: urlDur, seed: `${kit.seed}:url` }) : null;
|
|
@@ -74,8 +77,8 @@ const pattern: Pattern<EndContent> = {
|
|
|
74
77
|
moving("end.lockup", ctx);
|
|
75
78
|
if (logo && logoLand) applyStyle(logo, combine({ scale: spring(t - logoAt, { from: 0.6, to: 1, stiffness: 280, damping: 16 }) }, logoLand(t)));
|
|
76
79
|
fit();
|
|
77
|
-
paintName(t, { riseAt: nameAt, each, fill: 0 });
|
|
78
|
-
point(t
|
|
80
|
+
paintName(t, { riseAt: nameAt, each, fill: 0, up: again ? reread(t, again) : undefined });
|
|
81
|
+
point(t);
|
|
79
82
|
writeLine?.(t);
|
|
80
83
|
writeUrl?.(t);
|
|
81
84
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { applyStyle, clamp, combine, spring } from "@kasaframe/core";
|
|
2
2
|
import { fitSize, textEm } from "@kasaframe/motion/moves";
|
|
3
|
-
import { area, beatStops, cameraOk, fitOnce, glider, moving, node, sceneDrop, slam, slotsOf } from "../kit.ts";
|
|
3
|
+
import { area, beatStops, cameraOk, dwells, fitOnce, glider, moving, node, readOver, reread, sceneDrop, slam, slotsOf } from "../kit.ts";
|
|
4
4
|
import type { EndContent } from "./lockup.ts";
|
|
5
5
|
import type { Pattern } from "../types.ts";
|
|
6
6
|
|
|
@@ -65,9 +65,10 @@ const pattern: Pattern<EndContent> = {
|
|
|
65
65
|
const writeLine = lineEl ? slots.write(lineEl, { ctx, text: c.line!, at: lineAt, dur: 0.35, seed: `${kit.seed}:line` }) : null;
|
|
66
66
|
const writeUrl = urlEl ? slots.write(urlEl, { ctx, text: c.url!, at: urlAt, dur: 0.3, seed: `${kit.seed}:url` }) : null;
|
|
67
67
|
const landed = slots.land(name, { ctx, at, seed: `${kit.seed}:land` });
|
|
68
|
-
//
|
|
69
|
-
const point = glider(host, [stage, ...(lineEl ? [lineEl] : []), ...(urlEl ? [urlEl] : [])], {
|
|
70
|
-
const
|
|
68
|
+
// 앉으면 짚개가 이름·한 줄·주소를 짚는다(짚기 방식은 테마 짚음). 한 줄·주소가 없고 훑는 테마면 이름 글을 박마다 다시 짚는다
|
|
69
|
+
const point = glider(host, [{ el: stage, text: c.title }, ...(lineEl ? [{ el: lineEl, text: c.line }] : []), ...(urlEl ? [{ el: urlEl, text: c.url }] : [])], { kit, ctx, from: at + 0.2 });
|
|
70
|
+
const again = line || dwells(kit, ctx) ? null : readOver(name, c.title, ctx);
|
|
71
|
+
const againStops = again ? beatStops(kit.hits, at + 0.2, ctx.dur) : [];
|
|
71
72
|
|
|
72
73
|
return (t: number) => {
|
|
73
74
|
moving("end.slam", ctx);
|
|
@@ -78,7 +79,8 @@ const pattern: Pattern<EndContent> = {
|
|
|
78
79
|
// 쾅 전엔 외곽선 이름을 왼쪽부터 짚어 자리를 알린다 — 앉은 뒤엔 꽉 찬 이름을 마지막 프레임까지 짚는다
|
|
79
80
|
ghost.style.opacity = t < at ? "0.16" : "0";
|
|
80
81
|
ghost.style.clipPath = t < at ? `inset(0 ${((1 - clamp(t / Math.max(0.1, at - 0.16))) * 100).toFixed(2)}% 0 0)` : "";
|
|
81
|
-
point(t
|
|
82
|
+
point(t);
|
|
83
|
+
again?.(reread(t, againStops));
|
|
82
84
|
if (line) line.style.visibility = t >= lineAt ? "visible" : "hidden";
|
|
83
85
|
writeLine?.(t);
|
|
84
86
|
writeUrl?.(t);
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { applyStyle, clamp } from "@kasaframe/core";
|
|
2
2
|
import { textEm } from "@kasaframe/motion/moves";
|
|
3
|
-
import { area,
|
|
3
|
+
import { area, decimalsOf, dwells, fitOnce, followSpoken, glider, moving, node, odometer, sayTimes, slotsOf, timesSign } from "../kit.ts";
|
|
4
4
|
import type { HookNumber } from "./roll.ts";
|
|
5
|
+
import { rollCues } from "../sfx.ts";
|
|
5
6
|
import type { Pattern } from "../types.ts";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* 계수기 — 숫자 자리마다 판이 서고 주행계 띠가 굴러 값에 앉는다(끝자리 띠가 연속으로 구르고 윗자리는 올림 때만).
|
|
9
|
-
*
|
|
9
|
+
* 계수기 — 숫자 자리마다 판이 서고 주행계 띠가 굴러 값에 앉는다(끝자리 띠가 연속으로 구르고 윗자리는 올림 때만). 목소리가 그 값을 말할 때(못 들으면 장면 끝 무렵) 앉는다.
|
|
10
|
+
* 앉으면 짚개가 숫자부터 짚는다(머무는 테마는 목소리가 라벨·단위를 말할 때만 그리로). 롤(roll)이 「값이 바뀐다」라면 이쪽은 「센다」.
|
|
10
11
|
*/
|
|
11
12
|
const pattern: Pattern<HookNumber> = {
|
|
12
13
|
id: "hook-number.counter",
|
|
13
14
|
type: "hook-number",
|
|
14
|
-
does: "숫자 자리마다 판이 서고 주행계 띠가 굴러 값에
|
|
15
|
+
does: "숫자 자리마다 판이 서고 주행계 띠가 굴러 값에 앉으면, 짚개가 숫자부터 짚는다",
|
|
15
16
|
energy: ["low", "mid"],
|
|
16
17
|
family: "flap",
|
|
17
18
|
camera: ["none"],
|
|
@@ -69,11 +70,15 @@ const pattern: Pattern<HookNumber> = {
|
|
|
69
70
|
// 라벨 폭은 글꼴마다 다르다(고정폭 테마는 빈칸까지 한 칸) — 글자 수 어림 대신 그 글꼴로 재서 안전 영역 폭 92% 안에
|
|
70
71
|
const fitLabel = fitOnce(label, w * 0.92, labelPx, c.label);
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
// 머무는 짚개 테마는 라벨을 목소리가 그것을 말할 때 세우고, 숫자는 그 값을 말할 때까지(못 들으면 장면 끝 무렵까지) 고른 빠르기로 센다 —
|
|
74
|
+
// 처음 2초에 다 서고 남은 시간이 비지 않게. 앉으면 카메라가 숫자 쪽으로 다가간다. 훑는 테마는 2.4초 안에 앉고 남은 시간을 짚개가 진다
|
|
75
|
+
const spread = dwells(kit, ctx);
|
|
76
|
+
const [labelAt, valueAt] = spread ? sayTimes(kit, [c.label, c.value.toFixed(dec)], 0, Math.max(1.2, ctx.dur - 0.9)) : [0, Math.min(2.4, ctx.dur - 0.6)];
|
|
77
|
+
const land = clamp(valueAt, Math.min(1.2, ctx.dur - 0.6), ctx.dur - 0.6);
|
|
78
|
+
followSpoken(kit, ctx, [{ at: land, el: board }]);
|
|
73
79
|
// 배수 기호 하나를 칸으로 짚으면 색 네모 안 × — 닫기 단추로 읽힌다
|
|
74
|
-
const point = glider(host, [board, label, ...(unitEl && !times ? [unitEl] : [])], {
|
|
75
|
-
const
|
|
76
|
-
const writeLabel = slots.write(label, { ctx, text: c.label, at: 0, dur: 0.35, seed: `${kit.seed}:l` });
|
|
80
|
+
const point = glider(host, [{ el: board, text: c.value.toFixed(dec) }, { el: label, text: c.label }, ...(unitEl && !times ? [{ el: unitEl, text: unit }] : [])], { kit, ctx, from: land + 0.15 });
|
|
81
|
+
const writeLabel = slots.write(label, { ctx, text: c.label, at: Math.min(labelAt, land - 0.2), dur: 0.35, seed: `${kit.seed}:l` });
|
|
77
82
|
const landed = slots.land(board, { ctx, at: land, seed: `${kit.seed}:land` });
|
|
78
83
|
// 출처는 앉은 뒤에 찍고 장면 끝 0.35초 전에 다 찍는다 — 테마 글 찍기가 마지막 글자를 앉힐 틈(끝 프레임에 덜 찍힌 글자가 안 남게)
|
|
79
84
|
const srcDur = clamp([...srcText].length * 0.035, 0.3, 0.9);
|
|
@@ -87,13 +92,14 @@ const pattern: Pattern<HookNumber> = {
|
|
|
87
92
|
writeSource?.(t);
|
|
88
93
|
// 고른 빠르기로 센다 — 감속하면 끝자리 띠가 서서 그 사이가 멈춘 화면이 된다
|
|
89
94
|
const p = clamp((t - 0.1) / (land - 0.1));
|
|
95
|
+
rollCues(t, { at: 0.1, dur: land - 0.1, p: (u) => u });
|
|
90
96
|
const v = from + (c.value - from) * p;
|
|
91
97
|
if (odo) odo(p >= 1 ? c.value : v);
|
|
92
98
|
num.style.visibility = odo && t < land ? "visible" : "hidden";
|
|
93
99
|
plain.style.visibility = !odo || t >= land ? "visible" : "hidden";
|
|
94
100
|
if (!odo) plain.textContent = (p >= 1 ? c.value : v).toFixed(dec).padStart(template.length, " ");
|
|
95
101
|
applyStyle(board, landed(t));
|
|
96
|
-
point(t
|
|
102
|
+
point(t);
|
|
97
103
|
};
|
|
98
104
|
},
|
|
99
105
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { applyStyle, clamp, combine } from "@kasaframe/core";
|
|
2
2
|
import { textEm } from "@kasaframe/motion/moves";
|
|
3
|
-
import { area,
|
|
3
|
+
import { area, cameraOk, decimalsOf, factRoll, fitOnce, glider, moving, node, sceneDrop, slam, slotsOf } from "../kit.ts";
|
|
4
4
|
import type { HookNumber } from "./roll.ts";
|
|
5
5
|
import type { Pattern } from "../types.ts";
|
|
6
6
|
|
|
@@ -61,13 +61,11 @@ const pattern: Pattern<HookNumber> = {
|
|
|
61
61
|
if (di === null && kit.stage && cameraOk(ctx)) kit.stage.camera.impact(at, { amount: 0.04 });
|
|
62
62
|
const writeLabel = slots.write(label, { ctx, text: c.label, at: 0, dur: labelDur, seed: `${kit.seed}:l` });
|
|
63
63
|
const landed = slots.land(row, { ctx, at, seed: `${kit.seed}:land` });
|
|
64
|
-
// 짚개 — 쾅 전엔 라벨
|
|
65
|
-
const before = glider(host, [labelBox, ghostRow], {
|
|
66
|
-
const after = glider(host, [numBox, labelBox], {
|
|
67
|
-
const preStops = beatStops(kit.hits, labelDur, at - 0.2);
|
|
64
|
+
// 짚개 — 쾅 전엔 라벨(무엇의 숫자인가)과 외곽선 자리, 쾅 뒤엔 숫자와 라벨. 짚기 방식(박마다 훑기·요점에 머묾)은 테마 짚음이 고른다
|
|
65
|
+
const before = glider(host, [{ el: labelBox, text: c.label }, { el: ghostRow }], { kit, ctx, from: labelDur, to: at - 0.2, until: at - 0.16 });
|
|
66
|
+
const after = glider(host, [{ el: numBox, text }, { el: labelBox, text: c.label }], { kit, ctx, from: at + 0.25 });
|
|
68
67
|
// 라벨은 그 글꼴로 재서 안전 영역 폭 92% 안에
|
|
69
68
|
const fitLabel = fitOnce(labelBox, w * 0.92, labelPx, c.label);
|
|
70
|
-
const postStops = beatStops(kit.hits, at + 0.25, ctx.dur);
|
|
71
69
|
|
|
72
70
|
return (t: number) => {
|
|
73
71
|
moving("hook-number.slam", ctx);
|
|
@@ -81,8 +79,8 @@ const pattern: Pattern<HookNumber> = {
|
|
|
81
79
|
ghostRow.style.left = `${row.offsetLeft}px`;
|
|
82
80
|
ghostRow.style.top = `${row.offsetTop}px`;
|
|
83
81
|
}
|
|
84
|
-
before(t
|
|
85
|
-
after(t
|
|
82
|
+
before(t);
|
|
83
|
+
after(t);
|
|
86
84
|
if (s) applyStyle(host, s.shake);
|
|
87
85
|
};
|
|
88
86
|
},
|