kasaframe 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/NOTICE +13 -0
  2. package/README.md +2 -2
  3. package/docs/AGENTS.md +1 -0
  4. package/package.json +1 -1
  5. package/packages/adapters/src/project.ts +2 -0
  6. package/packages/check/package.json +1 -0
  7. package/packages/check/src/check.ts +8 -2
  8. package/packages/check/src/rules/frames.ts +4 -5
  9. package/packages/cli/src/commands/direct.ts +24 -4
  10. package/packages/cli/src/commands/make.ts +15 -5
  11. package/packages/cli/src/commands/render.ts +34 -7
  12. package/packages/cli/src/mix.ts +66 -4
  13. package/packages/cli/src/segments.ts +1 -1
  14. package/packages/cli/src/sfx.ts +429 -0
  15. package/packages/core/src/frame.ts +7 -4
  16. package/packages/core/src/index.ts +3 -1
  17. package/packages/core/src/project.ts +19 -0
  18. package/packages/core/src/sfx.ts +70 -0
  19. package/packages/director/src/assemble.ts +15 -6
  20. package/packages/director/src/fallback.ts +14 -2
  21. package/packages/director/src/index.ts +1 -1
  22. package/packages/director/src/pattern.ts +2 -0
  23. package/packages/director/src/patterns/fill/cells.ts +5 -2
  24. package/packages/director/src/scene.ts +17 -5
  25. package/packages/director/src/transitions.ts +21 -8
  26. package/packages/motion/src/enter.ts +7 -1
  27. package/packages/motion/src/impact.ts +5 -2
  28. package/packages/motion/src/moves/dress.ts +15 -2
  29. package/packages/motion/src/moves/menu.ts +11 -5
  30. package/packages/motion/src/transition.ts +3 -1
  31. package/packages/motion/src/transition3d/index.ts +3 -1
  32. package/packages/motion/src/transition3d/live.ts +5 -3
  33. package/packages/patterns/src/bars/rank.ts +6 -7
  34. package/packages/patterns/src/before-after/shrink.ts +3 -4
  35. package/packages/patterns/src/before-after/strike.ts +4 -5
  36. package/packages/patterns/src/code/terminal.ts +25 -16
  37. package/packages/patterns/src/end/lockup.ts +13 -10
  38. package/packages/patterns/src/end/slam.ts +14 -8
  39. package/packages/patterns/src/hook-number/counter.ts +15 -9
  40. package/packages/patterns/src/hook-number/slam.ts +6 -8
  41. package/packages/patterns/src/kit.ts +364 -59
  42. package/packages/patterns/src/limit/gauge.ts +19 -13
  43. package/packages/patterns/src/quote/karaoke.ts +17 -12
  44. package/packages/patterns/src/sfx.ts +80 -0
  45. package/packages/patterns/src/steps/path.ts +15 -7
  46. package/packages/patterns/src/term-reveal/chips.ts +24 -10
  47. package/packages/patterns/src/term-reveal/expand.ts +17 -13
  48. package/packages/patterns/src/timeline/axis.ts +79 -25
  49. package/packages/patterns/src/title/mask.ts +15 -10
  50. package/packages/patterns/src/title/slam.ts +1 -1
  51. package/packages/patterns/src/types.ts +1 -0
  52. package/packages/plan/src/brief.ts +5 -2
  53. package/packages/themes/src/index.ts +22 -0
  54. package/packages/themes/src/slots.ts +32 -2
  55. package/packages/themes/src/types.ts +28 -0
  56. package/sfx/README.md +82 -0
  57. package/sfx/click/appear.wav +0 -0
  58. package/sfx/click/burst.wav +0 -0
  59. package/sfx/click/drop.wav +0 -0
  60. package/sfx/click/end.wav +0 -0
  61. package/sfx/click/hop.wav +0 -0
  62. package/sfx/click/land.wav +0 -0
  63. package/sfx/click/select.wav +0 -0
  64. package/sfx/click/stick.wav +0 -0
  65. package/sfx/click/tick.wav +0 -0
  66. package/sfx/click/type.wav +0 -0
  67. package/sfx/click/whoosh.wav +0 -0
  68. package/sfx/pop/appear.wav +0 -0
  69. package/sfx/pop/burst.wav +0 -0
  70. package/sfx/pop/drop.wav +0 -0
  71. package/sfx/pop/end.wav +0 -0
  72. package/sfx/pop/hop.wav +0 -0
  73. package/sfx/pop/land.wav +0 -0
  74. package/sfx/pop/select.wav +0 -0
  75. package/sfx/pop/stick.wav +0 -0
  76. package/sfx/pop/tick.wav +0 -0
  77. package/sfx/pop/type.wav +0 -0
  78. package/sfx/pop/whoosh.wav +0 -0
  79. package/sfx/tags.json +545 -0
  80. package/sfx/ui/appear.wav +0 -0
  81. package/sfx/ui/burst.wav +0 -0
  82. package/sfx/ui/drop.wav +0 -0
  83. package/sfx/ui/end.wav +0 -0
  84. package/sfx/ui/hop.wav +0 -0
  85. package/sfx/ui/land.wav +0 -0
  86. package/sfx/ui/select.wav +0 -0
  87. package/sfx/ui/stick.wav +0 -0
  88. package/sfx/ui/tick.wav +0 -0
  89. package/sfx/ui/type.wav +0 -0
  90. package/sfx/ui/whoosh.wav +0 -0
  91. package/themes/kawaii-sticker/effects.ts +15 -3
  92. package/themes/kawaii-sticker/theme.json +1 -0
  93. package/themes/og-measure/THEME.md +13 -2
  94. package/themes/og-measure/effects.ts +76 -59
  95. package/themes/og-measure/sample/scenes/end.ts +2 -2
  96. package/themes/og-measure/sample/scenes/gather.ts +2 -10
  97. package/themes/og-measure/sample/scenes/models.ts +2 -10
  98. package/themes/og-measure/sample/scenes/one.ts +2 -1
  99. package/themes/og-measure/sample/scenes/price.ts +4 -16
  100. package/themes/og-measure/slots.ts +29 -0
  101. package/themes/og-measure/still.png +0 -0
  102. package/themes/og-measure/style.json +3 -0
  103. package/themes/og-measure/theme.json +15 -1
  104. package/themes/og-measure/variants/snow-blue.json +3 -0
package/sfx/tags.json ADDED
@@ -0,0 +1,545 @@
1
+ {
2
+ "sets": {
3
+ "pop": {
4
+ "label": "뽁·통",
5
+ "desc": "물방울 뽁·나무 통·둥근 쿵에 또렷한 톡 어택 — 스티커·캐릭터·발랄한 세계"
6
+ },
7
+ "click": {
8
+ "label": "딸깍·째깍",
9
+ "desc": "역할마다 아주 작은 스위치·시계 소리만 — 계측·데이터·차분한 세계"
10
+ },
11
+ "ui": {
12
+ "label": "기본",
13
+ "desc": "가벼운 UI 소리 — 퉁김·휙·주먹 쿵에 또렷한 어택. 결을 안 고른 세계"
14
+ }
15
+ },
16
+ "packs": {
17
+ "ui": {
18
+ "name": "Kenney UI SFX Set",
19
+ "url": "https://kenney.nl/assets/ui-audio",
20
+ "license": "CC0 1.0 (License.txt)"
21
+ },
22
+ "interface": {
23
+ "name": "Kenney Interface Sounds (1.0)",
24
+ "url": "https://kenney.nl/assets/interface-sounds",
25
+ "license": "CC0 1.0 (License.txt)"
26
+ },
27
+ "impact": {
28
+ "name": "Kenney Impact Sounds (1.0)",
29
+ "url": "https://kenney.nl/assets/impact-sounds",
30
+ "license": "CC0 1.0 (License.txt)"
31
+ },
32
+ "digital": {
33
+ "name": "Kenney Digital Audio",
34
+ "url": "https://kenney.nl/assets/digital-audio",
35
+ "license": "CC0 1.0 (License.txt)"
36
+ },
37
+ "rpg": {
38
+ "name": "Kenney RPG Audio",
39
+ "url": "https://kenney.nl/assets/rpg-audio",
40
+ "license": "CC0 1.0 (License.txt)"
41
+ },
42
+ "casino": {
43
+ "name": "Kenney Casino Audio (1.1)",
44
+ "url": "https://kenney.nl/assets/casino-audio",
45
+ "license": "CC0 1.0 (License.txt)"
46
+ }
47
+ },
48
+ "files": {
49
+ "pop/appear.wav": {
50
+ "set": "pop",
51
+ "role": "appear",
52
+ "dur": 0.152,
53
+ "lead": 0,
54
+ "level": -19.3,
55
+ "source": {
56
+ "pack": "Kenney Interface Sounds (1.0)",
57
+ "file": "drop_004.ogg",
58
+ "url": "https://kenney.nl/assets/interface-sounds"
59
+ },
60
+ "layer": {
61
+ "pack": "Kenney Interface Sounds (1.0)",
62
+ "file": "select_001.ogg",
63
+ "url": "https://kenney.nl/assets/interface-sounds",
64
+ "db": -6
65
+ },
66
+ "license": "CC0 1.0 (License.txt)"
67
+ },
68
+ "pop/stick.wav": {
69
+ "set": "pop",
70
+ "role": "stick",
71
+ "dur": 0.147,
72
+ "lead": 0.03,
73
+ "level": -20.2,
74
+ "source": {
75
+ "pack": "Kenney Interface Sounds (1.0)",
76
+ "file": "drop_002.ogg",
77
+ "url": "https://kenney.nl/assets/interface-sounds"
78
+ },
79
+ "layer": {
80
+ "pack": "Kenney Interface Sounds (1.0)",
81
+ "file": "tick_004.ogg",
82
+ "url": "https://kenney.nl/assets/interface-sounds",
83
+ "db": -4
84
+ },
85
+ "license": "CC0 1.0 (License.txt)"
86
+ },
87
+ "pop/land.wav": {
88
+ "set": "pop",
89
+ "role": "land",
90
+ "dur": 0.123,
91
+ "lead": 0,
92
+ "level": -20.7,
93
+ "source": {
94
+ "pack": "Kenney Impact Sounds (1.0)",
95
+ "file": "impactWood_light_000.ogg",
96
+ "url": "https://kenney.nl/assets/impact-sounds"
97
+ },
98
+ "layer": {
99
+ "pack": "Kenney Casino Audio (1.1)",
100
+ "file": "chip-lay-1.ogg",
101
+ "url": "https://kenney.nl/assets/casino-audio",
102
+ "db": -4
103
+ },
104
+ "license": "CC0 1.0 (License.txt)"
105
+ },
106
+ "pop/hop.wav": {
107
+ "set": "pop",
108
+ "role": "hop",
109
+ "dur": 0.3,
110
+ "lead": 0.015,
111
+ "level": -12.5,
112
+ "source": {
113
+ "pack": "Kenney Digital Audio",
114
+ "file": "phaseJump1.ogg",
115
+ "url": "https://kenney.nl/assets/digital-audio"
116
+ },
117
+ "layer": {
118
+ "pack": "Kenney UI SFX Set",
119
+ "file": "click5.ogg",
120
+ "url": "https://kenney.nl/assets/ui-audio",
121
+ "db": -6
122
+ },
123
+ "license": "CC0 1.0 (License.txt)"
124
+ },
125
+ "pop/whoosh.wav": {
126
+ "set": "pop",
127
+ "role": "whoosh",
128
+ "dur": 0.255,
129
+ "lead": 0.24,
130
+ "level": -7.3,
131
+ "source": {
132
+ "pack": "Kenney Interface Sounds (1.0)",
133
+ "file": "maximize_002.ogg",
134
+ "url": "https://kenney.nl/assets/interface-sounds"
135
+ },
136
+ "license": "CC0 1.0 (License.txt)"
137
+ },
138
+ "pop/tick.wav": {
139
+ "set": "pop",
140
+ "role": "tick",
141
+ "dur": 0.02,
142
+ "lead": 0,
143
+ "level": -24,
144
+ "source": {
145
+ "pack": "Kenney Interface Sounds (1.0)",
146
+ "file": "tick_002.ogg",
147
+ "url": "https://kenney.nl/assets/interface-sounds"
148
+ },
149
+ "license": "CC0 1.0 (License.txt)"
150
+ },
151
+ "pop/select.wav": {
152
+ "set": "pop",
153
+ "role": "select",
154
+ "dur": 0.04,
155
+ "lead": 0,
156
+ "level": -21.6,
157
+ "source": {
158
+ "pack": "Kenney Interface Sounds (1.0)",
159
+ "file": "select_001.ogg",
160
+ "url": "https://kenney.nl/assets/interface-sounds"
161
+ },
162
+ "license": "CC0 1.0 (License.txt)"
163
+ },
164
+ "pop/type.wav": {
165
+ "set": "pop",
166
+ "role": "type",
167
+ "dur": 0.035,
168
+ "lead": 0.01,
169
+ "level": -21.5,
170
+ "source": {
171
+ "pack": "Kenney UI SFX Set",
172
+ "file": "click5.ogg",
173
+ "url": "https://kenney.nl/assets/ui-audio"
174
+ },
175
+ "license": "CC0 1.0 (License.txt)"
176
+ },
177
+ "pop/drop.wav": {
178
+ "set": "pop",
179
+ "role": "drop",
180
+ "dur": 0.516,
181
+ "lead": 0,
182
+ "level": -14.3,
183
+ "source": {
184
+ "pack": "Kenney Impact Sounds (1.0)",
185
+ "file": "impactSoft_heavy_000.ogg",
186
+ "url": "https://kenney.nl/assets/impact-sounds"
187
+ },
188
+ "layer": {
189
+ "pack": "Kenney Impact Sounds (1.0)",
190
+ "file": "impactMetal_light_000.ogg",
191
+ "url": "https://kenney.nl/assets/impact-sounds",
192
+ "db": -3
193
+ },
194
+ "license": "CC0 1.0 (License.txt)"
195
+ },
196
+ "pop/burst.wav": {
197
+ "set": "pop",
198
+ "role": "burst",
199
+ "dur": 0.194,
200
+ "lead": 0.08,
201
+ "level": -16.7,
202
+ "source": {
203
+ "pack": "Kenney Digital Audio",
204
+ "file": "powerUp2.ogg",
205
+ "url": "https://kenney.nl/assets/digital-audio"
206
+ },
207
+ "layer": {
208
+ "pack": "Kenney Casino Audio (1.1)",
209
+ "file": "chips-collide-1.ogg",
210
+ "url": "https://kenney.nl/assets/casino-audio",
211
+ "db": -4
212
+ },
213
+ "license": "CC0 1.0 (License.txt)"
214
+ },
215
+ "pop/end.wav": {
216
+ "set": "pop",
217
+ "role": "end",
218
+ "dur": 0.322,
219
+ "lead": 0,
220
+ "level": -10.6,
221
+ "source": {
222
+ "pack": "Kenney Interface Sounds (1.0)",
223
+ "file": "confirmation_003.ogg",
224
+ "url": "https://kenney.nl/assets/interface-sounds"
225
+ },
226
+ "license": "CC0 1.0 (License.txt)"
227
+ },
228
+ "click/appear.wav": {
229
+ "set": "click",
230
+ "role": "appear",
231
+ "dur": 0.091,
232
+ "lead": 0.015,
233
+ "level": -23.2,
234
+ "source": {
235
+ "pack": "Kenney UI SFX Set",
236
+ "file": "click1.ogg",
237
+ "url": "https://kenney.nl/assets/ui-audio"
238
+ },
239
+ "license": "CC0 1.0 (License.txt)"
240
+ },
241
+ "click/stick.wav": {
242
+ "set": "click",
243
+ "role": "stick",
244
+ "dur": 0.007,
245
+ "lead": 0,
246
+ "level": -24.1,
247
+ "source": {
248
+ "pack": "Kenney Interface Sounds (1.0)",
249
+ "file": "click_003.ogg",
250
+ "url": "https://kenney.nl/assets/interface-sounds"
251
+ },
252
+ "license": "CC0 1.0 (License.txt)"
253
+ },
254
+ "click/land.wav": {
255
+ "set": "click",
256
+ "role": "land",
257
+ "dur": 0.143,
258
+ "lead": 0.105,
259
+ "level": -20.4,
260
+ "source": {
261
+ "pack": "Kenney Interface Sounds (1.0)",
262
+ "file": "switch_001.ogg",
263
+ "url": "https://kenney.nl/assets/interface-sounds"
264
+ },
265
+ "license": "CC0 1.0 (License.txt)"
266
+ },
267
+ "click/hop.wav": {
268
+ "set": "click",
269
+ "role": "hop",
270
+ "dur": 0.063,
271
+ "lead": 0.005,
272
+ "level": -13,
273
+ "source": {
274
+ "pack": "Kenney Interface Sounds (1.0)",
275
+ "file": "toggle_004.ogg",
276
+ "url": "https://kenney.nl/assets/interface-sounds"
277
+ },
278
+ "license": "CC0 1.0 (License.txt)"
279
+ },
280
+ "click/whoosh.wav": {
281
+ "set": "click",
282
+ "role": "whoosh",
283
+ "dur": 0.22,
284
+ "lead": 0.1,
285
+ "level": -20.3,
286
+ "source": {
287
+ "pack": "Kenney Interface Sounds (1.0)",
288
+ "file": "scroll_004.ogg",
289
+ "url": "https://kenney.nl/assets/interface-sounds"
290
+ },
291
+ "license": "CC0 1.0 (License.txt)"
292
+ },
293
+ "click/tick.wav": {
294
+ "set": "click",
295
+ "role": "tick",
296
+ "dur": 0.021,
297
+ "lead": 0,
298
+ "level": -27.1,
299
+ "source": {
300
+ "pack": "Kenney Interface Sounds (1.0)",
301
+ "file": "tick_001.ogg",
302
+ "url": "https://kenney.nl/assets/interface-sounds"
303
+ },
304
+ "license": "CC0 1.0 (License.txt)"
305
+ },
306
+ "click/select.wav": {
307
+ "set": "click",
308
+ "role": "select",
309
+ "dur": 0.04,
310
+ "lead": 0,
311
+ "level": -21.6,
312
+ "source": {
313
+ "pack": "Kenney Interface Sounds (1.0)",
314
+ "file": "select_001.ogg",
315
+ "url": "https://kenney.nl/assets/interface-sounds"
316
+ },
317
+ "license": "CC0 1.0 (License.txt)"
318
+ },
319
+ "click/type.wav": {
320
+ "set": "click",
321
+ "role": "type",
322
+ "dur": 0.05,
323
+ "lead": 0.005,
324
+ "level": -24.1,
325
+ "source": {
326
+ "pack": "Kenney UI SFX Set",
327
+ "file": "switch12.ogg",
328
+ "url": "https://kenney.nl/assets/ui-audio"
329
+ },
330
+ "license": "CC0 1.0 (License.txt)"
331
+ },
332
+ "click/drop.wav": {
333
+ "set": "click",
334
+ "role": "drop",
335
+ "dur": 0.206,
336
+ "lead": 0.03,
337
+ "level": -18.9,
338
+ "source": {
339
+ "pack": "Kenney RPG Audio",
340
+ "file": "metalLatch.ogg",
341
+ "url": "https://kenney.nl/assets/rpg-audio"
342
+ },
343
+ "license": "CC0 1.0 (License.txt)"
344
+ },
345
+ "click/burst.wav": {
346
+ "set": "click",
347
+ "role": "burst",
348
+ "dur": 0.125,
349
+ "lead": 0.005,
350
+ "level": -23.1,
351
+ "source": {
352
+ "pack": "Kenney Casino Audio (1.1)",
353
+ "file": "chip-lay-1.ogg",
354
+ "url": "https://kenney.nl/assets/casino-audio"
355
+ },
356
+ "license": "CC0 1.0 (License.txt)"
357
+ },
358
+ "click/end.wav": {
359
+ "set": "click",
360
+ "role": "end",
361
+ "dur": 0.11,
362
+ "lead": 0.005,
363
+ "level": -10.8,
364
+ "source": {
365
+ "pack": "Kenney Interface Sounds (1.0)",
366
+ "file": "toggle_002.ogg",
367
+ "url": "https://kenney.nl/assets/interface-sounds"
368
+ },
369
+ "license": "CC0 1.0 (License.txt)"
370
+ },
371
+ "ui/appear.wav": {
372
+ "set": "ui",
373
+ "role": "appear",
374
+ "dur": 0.126,
375
+ "lead": 0.03,
376
+ "level": -23.6,
377
+ "source": {
378
+ "pack": "Kenney Interface Sounds (1.0)",
379
+ "file": "pluck_001.ogg",
380
+ "url": "https://kenney.nl/assets/interface-sounds"
381
+ },
382
+ "layer": {
383
+ "pack": "Kenney Interface Sounds (1.0)",
384
+ "file": "tick_004.ogg",
385
+ "url": "https://kenney.nl/assets/interface-sounds",
386
+ "db": -6
387
+ },
388
+ "license": "CC0 1.0 (License.txt)"
389
+ },
390
+ "ui/stick.wav": {
391
+ "set": "ui",
392
+ "role": "stick",
393
+ "dur": 0.151,
394
+ "lead": 0.03,
395
+ "level": -22.4,
396
+ "source": {
397
+ "pack": "Kenney Interface Sounds (1.0)",
398
+ "file": "drop_001.ogg",
399
+ "url": "https://kenney.nl/assets/interface-sounds"
400
+ },
401
+ "layer": {
402
+ "pack": "Kenney Interface Sounds (1.0)",
403
+ "file": "tick_004.ogg",
404
+ "url": "https://kenney.nl/assets/interface-sounds",
405
+ "db": -6
406
+ },
407
+ "license": "CC0 1.0 (License.txt)"
408
+ },
409
+ "ui/land.wav": {
410
+ "set": "ui",
411
+ "role": "land",
412
+ "dur": 0.152,
413
+ "lead": 0,
414
+ "level": -21.5,
415
+ "source": {
416
+ "pack": "Kenney Impact Sounds (1.0)",
417
+ "file": "impactGeneric_light_000.ogg",
418
+ "url": "https://kenney.nl/assets/impact-sounds"
419
+ },
420
+ "layer": {
421
+ "pack": "Kenney Casino Audio (1.1)",
422
+ "file": "chip-lay-1.ogg",
423
+ "url": "https://kenney.nl/assets/casino-audio",
424
+ "db": -4
425
+ },
426
+ "license": "CC0 1.0 (License.txt)"
427
+ },
428
+ "ui/hop.wav": {
429
+ "set": "ui",
430
+ "role": "hop",
431
+ "dur": 0.141,
432
+ "lead": 0.01,
433
+ "level": -20.5,
434
+ "source": {
435
+ "pack": "Kenney Interface Sounds (1.0)",
436
+ "file": "pluck_002.ogg",
437
+ "url": "https://kenney.nl/assets/interface-sounds"
438
+ },
439
+ "layer": {
440
+ "pack": "Kenney UI SFX Set",
441
+ "file": "click5.ogg",
442
+ "url": "https://kenney.nl/assets/ui-audio",
443
+ "db": -6
444
+ },
445
+ "license": "CC0 1.0 (License.txt)"
446
+ },
447
+ "ui/whoosh.wav": {
448
+ "set": "ui",
449
+ "role": "whoosh",
450
+ "dur": 0.255,
451
+ "lead": 0.24,
452
+ "level": -9.9,
453
+ "source": {
454
+ "pack": "Kenney Interface Sounds (1.0)",
455
+ "file": "maximize_001.ogg",
456
+ "url": "https://kenney.nl/assets/interface-sounds"
457
+ },
458
+ "license": "CC0 1.0 (License.txt)"
459
+ },
460
+ "ui/tick.wav": {
461
+ "set": "ui",
462
+ "role": "tick",
463
+ "dur": 0.007,
464
+ "lead": 0,
465
+ "level": -24.1,
466
+ "source": {
467
+ "pack": "Kenney Interface Sounds (1.0)",
468
+ "file": "click_003.ogg",
469
+ "url": "https://kenney.nl/assets/interface-sounds"
470
+ },
471
+ "license": "CC0 1.0 (License.txt)"
472
+ },
473
+ "ui/select.wav": {
474
+ "set": "ui",
475
+ "role": "select",
476
+ "dur": 0.227,
477
+ "lead": 0.01,
478
+ "level": -13.2,
479
+ "source": {
480
+ "pack": "Kenney Interface Sounds (1.0)",
481
+ "file": "select_003.ogg",
482
+ "url": "https://kenney.nl/assets/interface-sounds"
483
+ },
484
+ "license": "CC0 1.0 (License.txt)"
485
+ },
486
+ "ui/type.wav": {
487
+ "set": "ui",
488
+ "role": "type",
489
+ "dur": 0.035,
490
+ "lead": 0.01,
491
+ "level": -21.5,
492
+ "source": {
493
+ "pack": "Kenney UI SFX Set",
494
+ "file": "click5.ogg",
495
+ "url": "https://kenney.nl/assets/ui-audio"
496
+ },
497
+ "license": "CC0 1.0 (License.txt)"
498
+ },
499
+ "ui/drop.wav": {
500
+ "set": "ui",
501
+ "role": "drop",
502
+ "dur": 0.453,
503
+ "lead": 0.03,
504
+ "level": -14.2,
505
+ "source": {
506
+ "pack": "Kenney Impact Sounds (1.0)",
507
+ "file": "impactPunch_heavy_000.ogg",
508
+ "url": "https://kenney.nl/assets/impact-sounds"
509
+ },
510
+ "layer": {
511
+ "pack": "Kenney Impact Sounds (1.0)",
512
+ "file": "impactMetal_light_000.ogg",
513
+ "url": "https://kenney.nl/assets/impact-sounds",
514
+ "db": -3
515
+ },
516
+ "license": "CC0 1.0 (License.txt)"
517
+ },
518
+ "ui/burst.wav": {
519
+ "set": "ui",
520
+ "role": "burst",
521
+ "dur": 0.16,
522
+ "lead": 0.005,
523
+ "level": -24,
524
+ "source": {
525
+ "pack": "Kenney Casino Audio (1.1)",
526
+ "file": "chips-collide-1.ogg",
527
+ "url": "https://kenney.nl/assets/casino-audio"
528
+ },
529
+ "license": "CC0 1.0 (License.txt)"
530
+ },
531
+ "ui/end.wav": {
532
+ "set": "ui",
533
+ "role": "end",
534
+ "dur": 0.143,
535
+ "lead": 0.105,
536
+ "level": -20.4,
537
+ "source": {
538
+ "pack": "Kenney Interface Sounds (1.0)",
539
+ "file": "switch_001.ogg",
540
+ "url": "https://kenney.nl/assets/interface-sounds"
541
+ },
542
+ "license": "CC0 1.0 (License.txt)"
543
+ }
544
+ }
545
+ }
Binary file
Binary file
Binary file
package/sfx/ui/end.wav ADDED
Binary file
package/sfx/ui/hop.wav ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- import { applyStyle, clamp, combine, emit, ease, progress, rand, safeTime, type Beats, type MotionRules, type Style } from "@kasaframe/core";
1
+ import { applyStyle, clamp, combine, cue, emit, ease, progress, rand, safeTime, type Beats, type MotionRules, type Style } from "@kasaframe/core";
2
2
  import { dropBurst } from "@kasaframe/motion";
3
3
 
4
4
  // 비유: 오려 붙인 스티커 앨범. 무엇이든 흰 테두리를 두른 스티커가 되어 톡 붙고, 모서리가 살짝 들리고, 떼어진다.
@@ -42,11 +42,13 @@ function shadowOf(lift: number, k: number): string {
42
42
  }
43
43
 
44
44
  /** 톡 붙기 — 들린 채 내려와 눌리며(납작) 붙고, 짧게 출렁인 뒤 멈춘다. at 전에는 안 보인다 */
45
- export function stickOn(t: number, o: { at: number; dur?: number; rotate?: number; fall?: number; seed?: string | number }): Lifted {
45
+ export function stickOn(t: number, o: { at: number; dur?: number; rotate?: number; fall?: number; seed?: string | number; minor?: boolean }): Lifted {
46
46
  t = safeTime(t);
47
47
  const dur = o.dur ?? 0.36;
48
48
  const u = (t - o.at) / dur;
49
49
  if (u < 0) return { opacity: 0, lift: 1 };
50
+ // 눌려 붙는 순간(내려오기 끝)에 톡
51
+ cue("stick", t - o.at - 0.45 * dur, { source: `stickOn:${o.seed ?? "stick"}@${o.at.toFixed(3)}`, minor: o.minor });
50
52
  const tilt = (rand(o.seed ?? "stick", 1) - 0.5) * 22;
51
53
  if (u < 0.45) {
52
54
  const p = ease.inQuad(u / 0.45);
@@ -68,6 +70,7 @@ export function peelOff(t: number, o: { at?: number; dur?: number; dir?: 1 | -1
68
70
  t = safeTime(t);
69
71
  if (o.at === undefined || t < o.at) return nil;
70
72
  const dur = o.dur ?? 0.6;
73
+ cue("whoosh", t - o.at, { source: `peelOff@${o.at.toFixed(3)}`, weight: 0.7, minor: true });
71
74
  const u = (t - o.at) / dur;
72
75
  const dir = o.dir ?? 1;
73
76
  const curl = ease.outCubic(clamp(u / 0.3));
@@ -98,6 +101,7 @@ export function cornerLift(t: number, o: { seed?: string | number; amount?: numb
98
101
  function hop(t: number, at: number): Lifted {
99
102
  const u = (t - at) / 0.34;
100
103
  if (u < 0 || u > 1) return nil;
104
+ cue("hop", t - at, { source: `hop@${at.toFixed(3)}`, weight: 0.8, minor: true });
101
105
  const up = Math.sin(Math.PI * Math.min(1, u / 0.7));
102
106
  const land = u > 0.7 ? Math.exp(-(u - 0.7) * 10) * Math.cos((u - 0.7) * 40) : 0;
103
107
  return { y: -70 * up, scale: 1 + 0.14 * up, rotate: 8 * up * (rand(at, 1) - 0.5) * 2, scaleX: 1 + 0.1 * land, scaleY: 1 - 0.1 * land, lift: up };
@@ -158,6 +162,7 @@ export function shotCam(t: number, o: { shots: Shot[]; whip?: number; drift?: nu
158
162
  let i = 0;
159
163
  for (let k = 0; k < shots.length; k++) if (shots[k].at <= t) i = k;
160
164
  let f = frame(i, t);
165
+ if (i > 0) cue("whoosh", t - shots[i].at, { source: `shotCam@${shots[i].at.toFixed(3)}`, scene: o.scene });
161
166
  if (i > 0 && t < shots[i].at + whip) {
162
167
  const p = ease.outQuart(progress(t, shots[i].at, whip));
163
168
  const a = frame(i - 1, shots[i].at);
@@ -222,6 +227,9 @@ function shineLayer(doc: Document, mask?: string): HTMLElement {
222
227
  return s;
223
228
  }
224
229
 
230
+ /** 이 폭(무대 px) 넘는 스티커가 주인공 — 붙는 소리를 기본으로 낸다 */
231
+ const HERO_W = 400;
232
+
225
233
  export interface StickerOpts {
226
234
  /** 투명 배경 그림(PNG·WebP). 없으면 text 로 이름표 스티커 */
227
235
  src?: string;
@@ -261,8 +269,10 @@ export function sticker(el: HTMLElement, o: StickerOpts): (t: number) => void {
261
269
  const shine = o.shine?.length ? shineLayer(el.ownerDocument, o.src) : null;
262
270
  if (shine) p.mov.append(shine);
263
271
  const seed = o.seed ?? o.src ?? o.text ?? "sticker";
272
+ // 주인공 스티커(아이콘·제품·이름)만 톡 소리를 기본으로 낸다 — 이름표·작은 조각까지 다 내면 곡에 묻히고 시끄럽다
273
+ const minor = o.w < HERO_W;
264
274
  return (t: number) => {
265
- const on = o.at === undefined ? nil : stickOn(t, { at: o.at, rotate: 0, seed });
275
+ const on = o.at === undefined ? nil : stickOn(t, { at: o.at, rotate: 0, seed, minor });
266
276
  const idle = cornerLift(t + (o.phase ?? 0), { seed });
267
277
  const off = peelOff(t, { at: o.peelAt, dir: o.peelDir });
268
278
  const jumps = (o.hops ?? []).map((h) => hop(t, h));
@@ -335,6 +345,7 @@ export function washiTape(
335
345
  return `${x + dx}px ${yy}%`;
336
346
  });
337
347
  return (t: number) => {
348
+ cue("whoosh", t - o.at, { source: `washiTape@${o.at.toFixed(3)}`, weight: 0.6, minor: true });
338
349
  const p = ease.outCubic(progress(t, o.at, o.dur ?? 0.24));
339
350
  const shown = Math.max(0, o.len * p);
340
351
  if (shown <= 0) {
@@ -367,6 +378,7 @@ export function stickerBurst(
367
378
  });
368
379
  return (t: number) => {
369
380
  const s = safeTime(t) - o.at;
381
+ cue("burst", s, { source: `stickerBurst@${o.at.toFixed(3)}` });
370
382
  for (const b of bits) {
371
383
  if (s < 0 || s > 1.4) {
372
384
  b.img.style.opacity = "0";
@@ -82,6 +82,7 @@
82
82
  ],
83
83
  "dims": "2D"
84
84
  },
85
+ "sfx": { "set": "pop", "db": 0, "perSec": 1 },
85
86
  "effects": [
86
87
  {
87
88
  "name": "sticker",