create-aura3d 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
- package/templates/cartoon-channel/README.md +38 -0
- package/templates/cartoon-channel/aura.assets.json +1364 -0
- package/templates/cartoon-channel/package.json +3 -2
- package/templates/cartoon-channel/public/aura-assets/luma.047f5e5f.glb +0 -0
- package/templates/cartoon-channel/public/aura-assets/luma.thumb.svg +1 -0
- package/templates/cartoon-channel/public/aura-assets/miko.047f5e5f.glb +0 -0
- package/templates/cartoon-channel/public/aura-assets/miko.thumb.svg +1 -0
- package/templates/cartoon-channel/public/aura-assets/moon-garden-feature-frame.png +0 -0
- package/templates/cartoon-channel/src/aura-assets.ts +5 -11
- package/templates/cartoon-channel/src/concept-episode-2-5d.css +159 -0
- package/templates/cartoon-channel/src/concept-episode-2-5d.ts +155 -0
- package/templates/cartoon-channel/src/image-puppet-episode.css +290 -0
- package/templates/cartoon-channel/src/image-puppet-episode.ts +139 -0
- package/templates/cartoon-channel/src/main.ts +89 -71
- package/templates/cartoon-channel/src/puppet-episode-2d.css +526 -0
- package/templates/cartoon-channel/src/puppet-episode-2d.ts +189 -0
- package/templates/cartoon-channel/src/render-plan.ts +1 -1
- package/templates/cartoon-channel/src/sample-episode-visual.css +457 -0
- package/templates/cartoon-channel/src/sample-episode-visual.ts +185 -0
- package/templates/cartoon-channel/test-results/.last-run.json +4 -0
- package/templates/cartoon-channel/tests/concept-2-5d-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/concept-2-5d.spec.ts +30 -0
- package/templates/cartoon-channel/tests/image-puppet-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/image-puppet.spec.ts +29 -0
- package/templates/cartoon-channel/tests/puppet-2d-animation.spec.ts +18 -0
- package/templates/cartoon-channel/tests/puppet-2d.spec.ts +26 -0
- package/templates/cartoon-channel/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
- package/templates/cartoon-channel/tests/sample-episode-visual.spec.ts +45 -0
- package/templates/cartoon-channel/tests/storyboard-playback.spec.ts +1 -1
- package/templates/cartoon-studio/README.md +82 -0
- package/templates/cartoon-studio/aura.assets.json +157 -0
- package/templates/cartoon-studio/index.html +13 -0
- package/templates/cartoon-studio/package.json +32 -0
- package/templates/cartoon-studio/playwright.config.ts +13 -0
- package/templates/cartoon-studio/public/aura-assets/luma.047f5e5f.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/luma.humanoid-fixture.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/luma.thumb.svg +1 -0
- package/templates/cartoon-studio/public/aura-assets/miko.047f5e5f.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/miko.thumb.svg +1 -0
- package/templates/cartoon-studio/public/aura-assets/moonGarden.gltf +183 -0
- package/templates/cartoon-studio/scripts/episode.ts +276 -0
- package/templates/cartoon-studio/src/aura-assets.ts +61 -0
- package/templates/cartoon-studio/src/characters.ts +65 -0
- package/templates/cartoon-studio/src/contract.ts +1 -0
- package/templates/cartoon-studio/src/episode-renderer.ts +605 -0
- package/templates/cartoon-studio/src/episode.ts +306 -0
- package/templates/cartoon-studio/src/main.ts +333 -0
- package/templates/cartoon-studio/src/render-plan.ts +567 -0
- package/templates/cartoon-studio/src/review.ts +99 -0
- package/templates/cartoon-studio/src/sets.ts +14 -0
- package/templates/cartoon-studio/src/studio.ts +101 -0
- package/templates/cartoon-studio/test-results/.last-run.json +4 -0
- package/templates/cartoon-studio/tests/episode-render.spec.ts +44 -0
- package/templates/cartoon-studio/tests/motion-quality.spec.ts +45 -0
- package/templates/cartoon-studio/tests/route-health.spec.ts +7 -0
- package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +99 -0
- package/templates/cartoon-studio/tests/visual-review.spec.ts +21 -0
- package/templates/cartoon-studio/tsconfig.json +12 -0
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/episode-builder/README.md +46 -0
- package/templates/episode-builder/index.html +13 -0
- package/templates/episode-builder/package.json +21 -0
- package/templates/episode-builder/playwright.config.ts +13 -0
- package/templates/episode-builder/src/aura-assets.ts +14 -0
- package/templates/episode-builder/src/builder.ts +78 -0
- package/templates/episode-builder/src/characters.ts +28 -0
- package/templates/episode-builder/src/contract.ts +1 -0
- package/templates/episode-builder/src/episode.ts +300 -0
- package/templates/episode-builder/src/main.ts +265 -0
- package/templates/episode-builder/src/render-plan.ts +405 -0
- package/templates/episode-builder/src/sets.ts +14 -0
- package/templates/episode-builder/tests/route-health.spec.ts +7 -0
- package/templates/episode-builder/tests/storyboard-playback.spec.ts +98 -0
- package/templates/episode-builder/tsconfig.json +12 -0
- package/templates/fighting-game/package.json +1 -1
- package/templates/fighting-game/src/game/stage.ts +18 -4
- package/templates/fighting-game/src/main.ts +3 -2
- package/templates/mini-game/package.json +1 -1
- package/templates/product-viewer/package.json +1 -1
- package/templates/product-viewer/tests/screenshot.spec.ts +8 -16
- package/templates/prompt-cartoon-channel/package.json +1 -1
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
body[data-cartoon-view="puppet-2d"] {
|
|
2
|
+
background:
|
|
3
|
+
radial-gradient(circle at 50% 20%, rgba(115, 225, 255, 0.14), transparent 34%),
|
|
4
|
+
linear-gradient(180deg, #06101d 0%, #102820 58%, #07100f 100%);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body[data-cartoon-view="puppet-2d"] #caption-overlay {
|
|
8
|
+
display: none !important;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
body[data-cartoon-view="puppet-2d"] #app {
|
|
12
|
+
opacity: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.puppet-episode {
|
|
16
|
+
--source-frame: url("/aura-assets/moon-garden-feature-frame.png");
|
|
17
|
+
position: fixed;
|
|
18
|
+
inset: 0;
|
|
19
|
+
display: grid;
|
|
20
|
+
place-items: center;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
padding: 28px;
|
|
23
|
+
background:
|
|
24
|
+
radial-gradient(circle at 50% 32%, rgba(255, 226, 150, 0.11), transparent 28%),
|
|
25
|
+
linear-gradient(180deg, rgba(7, 19, 28, 0.64), rgba(1, 8, 10, 0.9));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.puppet-episode__frame {
|
|
29
|
+
position: relative;
|
|
30
|
+
width: min(1320px, calc(100vw - 56px));
|
|
31
|
+
aspect-ratio: 16 / 9;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
border: 1px solid rgba(255, 232, 170, 0.28);
|
|
34
|
+
border-radius: 22px;
|
|
35
|
+
background: #06100f;
|
|
36
|
+
box-shadow:
|
|
37
|
+
0 36px 94px rgba(0, 0, 0, 0.58),
|
|
38
|
+
0 0 90px rgba(64, 255, 191, 0.12);
|
|
39
|
+
isolation: isolate;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.puppet-episode__backdrop,
|
|
43
|
+
.puppet-episode__foreground {
|
|
44
|
+
position: absolute;
|
|
45
|
+
inset: 0;
|
|
46
|
+
background-image: var(--source-frame);
|
|
47
|
+
background-repeat: no-repeat;
|
|
48
|
+
background-position: 50% 50%;
|
|
49
|
+
background-size: cover;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.puppet-episode__backdrop {
|
|
53
|
+
z-index: 1;
|
|
54
|
+
filter: saturate(0.92) brightness(0.76) blur(0.4px);
|
|
55
|
+
transform: scale(1.02);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.puppet-episode__foreground {
|
|
59
|
+
z-index: 8;
|
|
60
|
+
mask-image: linear-gradient(180deg, transparent 0 67%, rgba(0, 0, 0, 0.4) 76%, black 100%);
|
|
61
|
+
opacity: 0.72;
|
|
62
|
+
pointer-events: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.puppet-episode__moon-pulse {
|
|
66
|
+
position: absolute;
|
|
67
|
+
z-index: 2;
|
|
68
|
+
left: 48%;
|
|
69
|
+
top: 8%;
|
|
70
|
+
width: 27%;
|
|
71
|
+
aspect-ratio: 1;
|
|
72
|
+
border: 3px solid rgba(172, 250, 255, 0.78);
|
|
73
|
+
border-radius: 999px;
|
|
74
|
+
box-shadow:
|
|
75
|
+
0 0 28px rgba(103, 232, 255, 0.52),
|
|
76
|
+
inset 0 0 38px rgba(103, 232, 255, 0.26);
|
|
77
|
+
animation: moonPulse 2.4s ease-in-out infinite;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.puppet-episode__glow {
|
|
81
|
+
position: absolute;
|
|
82
|
+
z-index: 9;
|
|
83
|
+
width: 11%;
|
|
84
|
+
aspect-ratio: 1.45;
|
|
85
|
+
border-radius: 999px;
|
|
86
|
+
background: radial-gradient(ellipse, rgba(157, 233, 255, 0.65), transparent 62%);
|
|
87
|
+
filter: blur(7px);
|
|
88
|
+
opacity: 0.58;
|
|
89
|
+
animation: flowerGlow 1.8s ease-in-out infinite alternate;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.puppet-episode__glow--left {
|
|
93
|
+
left: 8%;
|
|
94
|
+
bottom: 7%;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.puppet-episode__glow--right {
|
|
98
|
+
right: 9%;
|
|
99
|
+
bottom: 9%;
|
|
100
|
+
animation-delay: 0.45s;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.puppet-robot,
|
|
104
|
+
.puppet-wheelbarrow {
|
|
105
|
+
position: absolute;
|
|
106
|
+
z-index: 6;
|
|
107
|
+
filter: drop-shadow(0 26px 24px rgba(0, 0, 0, 0.38));
|
|
108
|
+
transform-origin: 50% 92%;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.puppet-robot {
|
|
112
|
+
--accent: #45d7ff;
|
|
113
|
+
--rim: rgba(245, 255, 255, 0.74);
|
|
114
|
+
width: 160px;
|
|
115
|
+
height: 220px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.puppet-robot--miko {
|
|
119
|
+
left: 31%;
|
|
120
|
+
bottom: 18%;
|
|
121
|
+
transform: rotate(-7deg);
|
|
122
|
+
animation: mikoBody 1.35s ease-in-out infinite;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.puppet-robot--luma {
|
|
126
|
+
--accent: #ffc63b;
|
|
127
|
+
--rim: rgba(255, 250, 214, 0.78);
|
|
128
|
+
left: 57%;
|
|
129
|
+
bottom: 23%;
|
|
130
|
+
transform: rotate(3deg);
|
|
131
|
+
animation: lumaBody 1.8s ease-in-out infinite;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.puppet-robot__shadow {
|
|
135
|
+
position: absolute;
|
|
136
|
+
left: 12%;
|
|
137
|
+
right: 8%;
|
|
138
|
+
bottom: 0;
|
|
139
|
+
height: 18px;
|
|
140
|
+
border-radius: 999px;
|
|
141
|
+
background: rgba(0, 0, 0, 0.28);
|
|
142
|
+
filter: blur(5px);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.puppet-robot__body,
|
|
146
|
+
.puppet-robot__head,
|
|
147
|
+
.puppet-robot__leg,
|
|
148
|
+
.puppet-robot__arm {
|
|
149
|
+
position: absolute;
|
|
150
|
+
background:
|
|
151
|
+
radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.72), transparent 13%),
|
|
152
|
+
linear-gradient(145deg, color-mix(in srgb, var(--accent) 94%, white 18%), color-mix(in srgb, var(--accent) 82%, black 12%));
|
|
153
|
+
border: 2px solid var(--rim);
|
|
154
|
+
box-shadow:
|
|
155
|
+
inset -8px -9px 16px rgba(0, 0, 0, 0.13),
|
|
156
|
+
0 0 22px color-mix(in srgb, var(--accent) 42%, transparent);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.puppet-robot__body {
|
|
160
|
+
left: 45px;
|
|
161
|
+
top: 86px;
|
|
162
|
+
width: 64px;
|
|
163
|
+
height: 76px;
|
|
164
|
+
border-radius: 36% 36% 42% 42%;
|
|
165
|
+
transform-origin: 50% 18%;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.puppet-robot__head {
|
|
169
|
+
left: 30px;
|
|
170
|
+
top: 20px;
|
|
171
|
+
width: 94px;
|
|
172
|
+
height: 74px;
|
|
173
|
+
border-radius: 42% 42% 38% 38%;
|
|
174
|
+
animation: headNod 1.35s ease-in-out infinite;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.puppet-robot--luma .puppet-robot__head {
|
|
178
|
+
animation-duration: 1.8s;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.puppet-robot__antenna {
|
|
182
|
+
position: absolute;
|
|
183
|
+
left: 47%;
|
|
184
|
+
top: -24px;
|
|
185
|
+
width: 10px;
|
|
186
|
+
height: 32px;
|
|
187
|
+
border-radius: 999px;
|
|
188
|
+
background: var(--accent);
|
|
189
|
+
box-shadow: 0 -8px 14px var(--accent);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.puppet-robot__eye {
|
|
193
|
+
position: absolute;
|
|
194
|
+
top: 32px;
|
|
195
|
+
width: 17px;
|
|
196
|
+
height: 20px;
|
|
197
|
+
border-radius: 999px;
|
|
198
|
+
background: #f8fff2;
|
|
199
|
+
box-shadow: 0 0 14px #f8fff2;
|
|
200
|
+
animation: blink 3.6s steps(1) infinite;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.puppet-robot__eye--left {
|
|
204
|
+
left: 29px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.puppet-robot__eye--right {
|
|
208
|
+
right: 27px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.puppet-robot__smile {
|
|
212
|
+
position: absolute;
|
|
213
|
+
left: 40px;
|
|
214
|
+
top: 51px;
|
|
215
|
+
width: 24px;
|
|
216
|
+
height: 12px;
|
|
217
|
+
border-bottom: 3px solid #f8fff2;
|
|
218
|
+
border-radius: 0 0 999px 999px;
|
|
219
|
+
opacity: 0.92;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.puppet-robot__leg {
|
|
223
|
+
top: 150px;
|
|
224
|
+
width: 25px;
|
|
225
|
+
height: 58px;
|
|
226
|
+
border-radius: 999px 999px 12px 12px;
|
|
227
|
+
transform-origin: 50% 8%;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.puppet-robot__leg--front {
|
|
231
|
+
left: 82px;
|
|
232
|
+
transform: rotate(-9deg);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.puppet-robot__leg--back {
|
|
236
|
+
left: 49px;
|
|
237
|
+
transform: rotate(13deg);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.puppet-robot--miko .puppet-robot__leg--front {
|
|
241
|
+
animation: mikoFrontLeg 1.35s ease-in-out infinite;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.puppet-robot--miko .puppet-robot__leg--back {
|
|
245
|
+
animation: mikoBackLeg 1.35s ease-in-out infinite;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.puppet-robot__arm {
|
|
249
|
+
top: 92px;
|
|
250
|
+
width: 24px;
|
|
251
|
+
height: 76px;
|
|
252
|
+
border-radius: 999px;
|
|
253
|
+
transform-origin: 50% 8%;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.puppet-robot__arm--front {
|
|
257
|
+
left: 99px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.puppet-robot__arm--back {
|
|
261
|
+
left: 31px;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.puppet-robot--miko .puppet-robot__arm--front {
|
|
265
|
+
animation: broomArmFront 0.88s ease-in-out infinite;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.puppet-robot--miko .puppet-robot__arm--back {
|
|
269
|
+
animation: broomArmBack 0.88s ease-in-out infinite;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.puppet-robot--luma .puppet-robot__arm--front {
|
|
273
|
+
animation: pushArmFront 1.15s ease-in-out infinite;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.puppet-robot--luma .puppet-robot__arm--back {
|
|
277
|
+
animation: pushArmBack 1.15s ease-in-out infinite;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.puppet-tool {
|
|
281
|
+
position: absolute;
|
|
282
|
+
z-index: 2;
|
|
283
|
+
transform-origin: 50% 10%;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.puppet-tool--broom {
|
|
287
|
+
left: 99px;
|
|
288
|
+
top: 132px;
|
|
289
|
+
width: 9px;
|
|
290
|
+
height: 128px;
|
|
291
|
+
border-radius: 999px;
|
|
292
|
+
background: #e4b978;
|
|
293
|
+
animation: broomSweep 0.88s ease-in-out infinite;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.puppet-tool--broom::after {
|
|
297
|
+
content: "";
|
|
298
|
+
position: absolute;
|
|
299
|
+
left: -21px;
|
|
300
|
+
bottom: -7px;
|
|
301
|
+
width: 54px;
|
|
302
|
+
height: 30px;
|
|
303
|
+
border-radius: 6px 6px 18px 18px;
|
|
304
|
+
background:
|
|
305
|
+
repeating-linear-gradient(90deg, #c78938 0 4px, #f0c771 4px 8px);
|
|
306
|
+
transform: rotate(8deg);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.puppet-tool--rake {
|
|
310
|
+
left: 34px;
|
|
311
|
+
top: 128px;
|
|
312
|
+
width: 8px;
|
|
313
|
+
height: 132px;
|
|
314
|
+
border-radius: 999px;
|
|
315
|
+
background: #d9a45b;
|
|
316
|
+
transform: rotate(-40deg);
|
|
317
|
+
animation: rakePush 1.15s ease-in-out infinite;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.puppet-tool--rake::after {
|
|
321
|
+
content: "";
|
|
322
|
+
position: absolute;
|
|
323
|
+
left: -20px;
|
|
324
|
+
bottom: -9px;
|
|
325
|
+
width: 48px;
|
|
326
|
+
height: 12px;
|
|
327
|
+
border-radius: 999px;
|
|
328
|
+
background: #f0c771;
|
|
329
|
+
box-shadow:
|
|
330
|
+
-12px 8px 0 -4px #f0c771,
|
|
331
|
+
0 8px 0 -4px #f0c771,
|
|
332
|
+
12px 8px 0 -4px #f0c771;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.puppet-wheelbarrow {
|
|
336
|
+
left: 49.5%;
|
|
337
|
+
bottom: 20.5%;
|
|
338
|
+
width: 190px;
|
|
339
|
+
height: 120px;
|
|
340
|
+
animation: wheelbarrowRoll 1.15s ease-in-out infinite;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.puppet-wheelbarrow__bin {
|
|
344
|
+
position: absolute;
|
|
345
|
+
left: 22px;
|
|
346
|
+
top: 28px;
|
|
347
|
+
width: 128px;
|
|
348
|
+
height: 70px;
|
|
349
|
+
border: 2px solid rgba(214, 240, 255, 0.72);
|
|
350
|
+
border-radius: 16px 16px 24px 24px;
|
|
351
|
+
background:
|
|
352
|
+
radial-gradient(circle at 52% 58%, rgba(78, 222, 255, 0.7), transparent 12%),
|
|
353
|
+
linear-gradient(180deg, #8a9fb1, #4c6675);
|
|
354
|
+
box-shadow: inset -10px -10px 20px rgba(0, 0, 0, 0.18);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.puppet-wheelbarrow__wheel {
|
|
358
|
+
position: absolute;
|
|
359
|
+
left: 118px;
|
|
360
|
+
bottom: 4px;
|
|
361
|
+
width: 30px;
|
|
362
|
+
height: 30px;
|
|
363
|
+
border: 5px solid #19313c;
|
|
364
|
+
border-top-color: #6ce8ff;
|
|
365
|
+
border-radius: 999px;
|
|
366
|
+
background: #07131a;
|
|
367
|
+
animation: wheelSpin 0.62s linear infinite;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.puppet-wheelbarrow__handles {
|
|
371
|
+
position: absolute;
|
|
372
|
+
left: 8px;
|
|
373
|
+
top: 42px;
|
|
374
|
+
width: 170px;
|
|
375
|
+
height: 12px;
|
|
376
|
+
border-top: 6px solid #d9a45b;
|
|
377
|
+
transform: rotate(11deg);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.puppet-episode__hud,
|
|
381
|
+
.puppet-episode__caption {
|
|
382
|
+
position: absolute;
|
|
383
|
+
z-index: 12;
|
|
384
|
+
left: 28px;
|
|
385
|
+
right: 28px;
|
|
386
|
+
display: flex;
|
|
387
|
+
align-items: center;
|
|
388
|
+
gap: 14px;
|
|
389
|
+
color: #f8fff2;
|
|
390
|
+
text-shadow: 0 2px 14px rgba(0, 0, 0, 0.72);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.puppet-episode__hud {
|
|
394
|
+
top: 24px;
|
|
395
|
+
justify-content: space-between;
|
|
396
|
+
font: 700 13px/1.2 ui-sans-serif, system-ui, sans-serif;
|
|
397
|
+
letter-spacing: 0.08em;
|
|
398
|
+
text-transform: uppercase;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.puppet-episode__hud span,
|
|
402
|
+
.puppet-episode__hud strong {
|
|
403
|
+
padding: 8px 12px;
|
|
404
|
+
border: 1px solid rgba(248, 255, 242, 0.18);
|
|
405
|
+
border-radius: 999px;
|
|
406
|
+
background: rgba(1, 10, 10, 0.58);
|
|
407
|
+
backdrop-filter: blur(8px);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.puppet-episode__caption {
|
|
411
|
+
bottom: 42px;
|
|
412
|
+
justify-content: center;
|
|
413
|
+
text-align: center;
|
|
414
|
+
font: 800 clamp(18px, 2.2vw, 30px) / 1.24 ui-rounded, "Trebuchet MS", system-ui, sans-serif;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.puppet-episode__caption::before {
|
|
418
|
+
content: "";
|
|
419
|
+
position: absolute;
|
|
420
|
+
inset: -14px auto auto 50%;
|
|
421
|
+
width: min(880px, calc(100vw - 120px));
|
|
422
|
+
height: calc(100% + 28px);
|
|
423
|
+
transform: translateX(-50%);
|
|
424
|
+
border-radius: 18px;
|
|
425
|
+
background: linear-gradient(180deg, rgba(1, 10, 10, 0.14), rgba(1, 10, 10, 0.68));
|
|
426
|
+
z-index: -1;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.puppet-episode__timeline {
|
|
430
|
+
position: absolute;
|
|
431
|
+
z-index: 13;
|
|
432
|
+
left: 28px;
|
|
433
|
+
right: 28px;
|
|
434
|
+
bottom: 20px;
|
|
435
|
+
height: 4px;
|
|
436
|
+
overflow: hidden;
|
|
437
|
+
border-radius: 999px;
|
|
438
|
+
background: rgba(248, 255, 242, 0.16);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.puppet-episode__timeline-fill {
|
|
442
|
+
display: block;
|
|
443
|
+
width: var(--progress, 0%);
|
|
444
|
+
height: 100%;
|
|
445
|
+
border-radius: inherit;
|
|
446
|
+
background: linear-gradient(90deg, #ffdd87, #65ffc6);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@keyframes moonPulse {
|
|
450
|
+
0%, 100% { transform: scale(0.98); opacity: 0.58; }
|
|
451
|
+
50% { transform: scale(1.04); opacity: 0.9; }
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
@keyframes flowerGlow {
|
|
455
|
+
from { opacity: 0.38; transform: scale(0.94); }
|
|
456
|
+
to { opacity: 0.78; transform: scale(1.08); }
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
@keyframes blink {
|
|
460
|
+
0%, 89%, 100% { transform: scaleY(1); }
|
|
461
|
+
90%, 94% { transform: scaleY(0.12); }
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
@keyframes headNod {
|
|
465
|
+
0%, 100% { transform: translateY(0) rotate(-2deg); }
|
|
466
|
+
50% { transform: translateY(5px) rotate(4deg); }
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@keyframes mikoBody {
|
|
470
|
+
0%, 100% { transform: translateY(0) rotate(-8deg); }
|
|
471
|
+
50% { transform: translateY(6px) rotate(-3deg); }
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
@keyframes lumaBody {
|
|
475
|
+
0%, 100% { transform: translateX(0) rotate(3deg); }
|
|
476
|
+
50% { transform: translateX(-8px) rotate(0deg); }
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
@keyframes mikoFrontLeg {
|
|
480
|
+
0%, 100% { transform: rotate(-14deg); }
|
|
481
|
+
50% { transform: rotate(1deg); }
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
@keyframes mikoBackLeg {
|
|
485
|
+
0%, 100% { transform: rotate(18deg); }
|
|
486
|
+
50% { transform: rotate(7deg); }
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
@keyframes broomArmFront {
|
|
490
|
+
0%, 100% { transform: rotate(-58deg); }
|
|
491
|
+
50% { transform: rotate(-28deg); }
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
@keyframes broomArmBack {
|
|
495
|
+
0%, 100% { transform: rotate(42deg); }
|
|
496
|
+
50% { transform: rotate(18deg); }
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
@keyframes broomSweep {
|
|
500
|
+
0%, 100% { transform: rotate(-49deg) translateY(0); }
|
|
501
|
+
50% { transform: rotate(-18deg) translateY(6px); }
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
@keyframes pushArmFront {
|
|
505
|
+
0%, 100% { transform: rotate(64deg); }
|
|
506
|
+
50% { transform: rotate(36deg); }
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
@keyframes pushArmBack {
|
|
510
|
+
0%, 100% { transform: rotate(38deg); }
|
|
511
|
+
50% { transform: rotate(18deg); }
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
@keyframes rakePush {
|
|
515
|
+
0%, 100% { transform: rotate(-42deg) translateY(0); }
|
|
516
|
+
50% { transform: rotate(-52deg) translateY(8px); }
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
@keyframes wheelbarrowRoll {
|
|
520
|
+
0%, 100% { transform: translateX(0) rotate(0deg); }
|
|
521
|
+
50% { transform: translateX(-9px) rotate(-1.8deg); }
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
@keyframes wheelSpin {
|
|
525
|
+
to { transform: rotate(360deg); }
|
|
526
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { episode, episodeSampleDescription, youtubeDraftMetadata } from "./episode";
|
|
2
|
+
import type { CartoonRouteSampleForVisual } from "./sample-episode-visual";
|
|
3
|
+
import "./puppet-episode-2d.css";
|
|
4
|
+
|
|
5
|
+
export interface PuppetEpisode2DOptions {
|
|
6
|
+
readonly sampleAt: (time: number) => CartoonRouteSampleForVisual;
|
|
7
|
+
readonly duration: number;
|
|
8
|
+
readonly fixedTime?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface PuppetEpisode2DProof {
|
|
12
|
+
readonly contractId: string;
|
|
13
|
+
readonly episodeId: string;
|
|
14
|
+
readonly title: string;
|
|
15
|
+
readonly route: string;
|
|
16
|
+
readonly mode: "2d-puppet-animation-over-concept-art";
|
|
17
|
+
readonly sourceImage: string;
|
|
18
|
+
readonly notTrue3D: true;
|
|
19
|
+
readonly screenshotTarget: "#puppet-episode-2d";
|
|
20
|
+
readonly sample: CartoonRouteSampleForVisual;
|
|
21
|
+
readonly animatedParts: readonly string[];
|
|
22
|
+
readonly aura3dRole: readonly string[];
|
|
23
|
+
readonly limitations: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sourceImage = "/aura-assets/moon-garden-feature-frame.png";
|
|
27
|
+
const animatedParts = [
|
|
28
|
+
"blue robot head bob",
|
|
29
|
+
"blue robot eyes blink",
|
|
30
|
+
"blue robot broom sweep",
|
|
31
|
+
"blue robot shoulder and elbow arcs",
|
|
32
|
+
"yellow robot head nod",
|
|
33
|
+
"yellow robot eyes blink",
|
|
34
|
+
"yellow robot rake/push arm",
|
|
35
|
+
"wheelbarrow body roll",
|
|
36
|
+
"moon ring pulse",
|
|
37
|
+
"foreground flower glow",
|
|
38
|
+
"caption/timeline timing"
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
export function installPuppetEpisode2D(options: PuppetEpisode2DOptions) {
|
|
42
|
+
document.body.dataset.cartoonView = "puppet-2d";
|
|
43
|
+
const root = document.createElement("section");
|
|
44
|
+
root.id = "puppet-episode-2d";
|
|
45
|
+
root.className = "puppet-episode";
|
|
46
|
+
root.setAttribute("aria-label", "Aura3D 2D puppet cartoon animation over moon garden concept art");
|
|
47
|
+
root.innerHTML = `
|
|
48
|
+
<div class="puppet-episode__frame">
|
|
49
|
+
<div class="puppet-episode__backdrop" aria-hidden="true"></div>
|
|
50
|
+
<div class="puppet-episode__moon-pulse" aria-hidden="true"></div>
|
|
51
|
+
<div class="puppet-episode__glow puppet-episode__glow--left" aria-hidden="true"></div>
|
|
52
|
+
<div class="puppet-episode__glow puppet-episode__glow--right" aria-hidden="true"></div>
|
|
53
|
+
|
|
54
|
+
<div class="puppet-robot puppet-robot--miko" aria-label="Miko sweeping animated puppet" role="img">
|
|
55
|
+
<span class="puppet-robot__shadow"></span>
|
|
56
|
+
<span class="puppet-robot__leg puppet-robot__leg--back"></span>
|
|
57
|
+
<span class="puppet-robot__leg puppet-robot__leg--front"></span>
|
|
58
|
+
<span class="puppet-robot__body"></span>
|
|
59
|
+
<span class="puppet-robot__head">
|
|
60
|
+
<span class="puppet-robot__eye puppet-robot__eye--left"></span>
|
|
61
|
+
<span class="puppet-robot__eye puppet-robot__eye--right"></span>
|
|
62
|
+
<span class="puppet-robot__smile"></span>
|
|
63
|
+
<span class="puppet-robot__antenna"></span>
|
|
64
|
+
</span>
|
|
65
|
+
<span class="puppet-robot__arm puppet-robot__arm--back"></span>
|
|
66
|
+
<span class="puppet-robot__arm puppet-robot__arm--front"></span>
|
|
67
|
+
<span class="puppet-tool puppet-tool--broom"></span>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="puppet-wheelbarrow" aria-hidden="true">
|
|
71
|
+
<span class="puppet-wheelbarrow__bin"></span>
|
|
72
|
+
<span class="puppet-wheelbarrow__wheel"></span>
|
|
73
|
+
<span class="puppet-wheelbarrow__handles"></span>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="puppet-robot puppet-robot--luma" aria-label="Luma pushing animated puppet" role="img">
|
|
77
|
+
<span class="puppet-robot__shadow"></span>
|
|
78
|
+
<span class="puppet-robot__leg puppet-robot__leg--back"></span>
|
|
79
|
+
<span class="puppet-robot__leg puppet-robot__leg--front"></span>
|
|
80
|
+
<span class="puppet-robot__body"></span>
|
|
81
|
+
<span class="puppet-robot__head">
|
|
82
|
+
<span class="puppet-robot__eye puppet-robot__eye--left"></span>
|
|
83
|
+
<span class="puppet-robot__eye puppet-robot__eye--right"></span>
|
|
84
|
+
<span class="puppet-robot__smile"></span>
|
|
85
|
+
<span class="puppet-robot__antenna"></span>
|
|
86
|
+
</span>
|
|
87
|
+
<span class="puppet-robot__arm puppet-robot__arm--back"></span>
|
|
88
|
+
<span class="puppet-robot__arm puppet-robot__arm--front"></span>
|
|
89
|
+
<span class="puppet-tool puppet-tool--rake"></span>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div class="puppet-episode__foreground" aria-hidden="true"></div>
|
|
93
|
+
<div class="puppet-episode__hud">
|
|
94
|
+
<span>2D puppet animation</span>
|
|
95
|
+
<strong data-puppet-shot-label>Shot 1 / 3</strong>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="puppet-episode__caption" data-puppet-caption></div>
|
|
98
|
+
<div class="puppet-episode__timeline" aria-hidden="true">
|
|
99
|
+
<span class="puppet-episode__timeline-fill" data-puppet-progress></span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
`;
|
|
103
|
+
document.body.appendChild(root);
|
|
104
|
+
|
|
105
|
+
const hostSlot = document.querySelector<HTMLElement>("[data-aura-host-slot]");
|
|
106
|
+
const appHost = document.querySelector<HTMLElement>("#app");
|
|
107
|
+
if (hostSlot && appHost) {
|
|
108
|
+
hostSlot.replaceWith(appHost);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const caption = root.querySelector<HTMLElement>("[data-puppet-caption]");
|
|
112
|
+
const shotLabel = root.querySelector<HTMLElement>("[data-puppet-shot-label]");
|
|
113
|
+
const progress = root.querySelector<HTMLElement>("[data-puppet-progress]");
|
|
114
|
+
const query = new URLSearchParams(window.location.search);
|
|
115
|
+
const queryTime = query.get("sampleTime");
|
|
116
|
+
const fixedTime = options.fixedTime ?? (queryTime ? Number(queryTime) : undefined);
|
|
117
|
+
const start = performance.now();
|
|
118
|
+
|
|
119
|
+
function render(time: number) {
|
|
120
|
+
const sample = options.sampleAt(clampTime(time, options.duration));
|
|
121
|
+
const shotIndex = Math.max(0, episode.shotTimeline.shots.findIndex((shot) => shot.shotId === sample.shotId));
|
|
122
|
+
const progressPercent = Math.max(0, Math.min(100, (sample.time / options.duration) * 100));
|
|
123
|
+
|
|
124
|
+
root.dataset.shotId = sample.shotId ?? "";
|
|
125
|
+
root.dataset.captionId = sample.captionId ?? "";
|
|
126
|
+
root.dataset.puppetEpisode = "moon-garden-cleanup";
|
|
127
|
+
|
|
128
|
+
if (caption) {
|
|
129
|
+
caption.textContent = sample.captionText ?? "The robots sweep, blink, nod, and push the garden cart.";
|
|
130
|
+
}
|
|
131
|
+
if (shotLabel) {
|
|
132
|
+
shotLabel.textContent = `Shot ${shotIndex + 1} / ${episode.shotTimeline.shots.length}`;
|
|
133
|
+
}
|
|
134
|
+
if (progress) {
|
|
135
|
+
progress.style.setProperty("--progress", `${progressPercent}%`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
window.__AURA3D_CARTOON_2D_PUPPET_PROOF__ = {
|
|
139
|
+
contractId: episodeSampleDescription.contractId,
|
|
140
|
+
episodeId: episode.episodePlan.episodeId,
|
|
141
|
+
title: episode.episodePlan.title,
|
|
142
|
+
route: "/?view=puppet-2d",
|
|
143
|
+
mode: "2d-puppet-animation-over-concept-art",
|
|
144
|
+
sourceImage,
|
|
145
|
+
notTrue3D: true,
|
|
146
|
+
screenshotTarget: "#puppet-episode-2d",
|
|
147
|
+
sample,
|
|
148
|
+
animatedParts,
|
|
149
|
+
aura3dRole: [
|
|
150
|
+
"episode contract and shot timing",
|
|
151
|
+
"caption timing",
|
|
152
|
+
"animation state/proof metadata",
|
|
153
|
+
"render/record evidence",
|
|
154
|
+
"optional replacement with typed 3D foreground assets"
|
|
155
|
+
],
|
|
156
|
+
limitations: [
|
|
157
|
+
"This is 2D puppet animation over concept art, not a generated 3D scene.",
|
|
158
|
+
"A production pass should replace CSS puppet shapes with separated art layers or rigged character assets.",
|
|
159
|
+
"The source frame supplies the art direction/backdrop; the moving robots are explicit overlay puppets."
|
|
160
|
+
]
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (Number.isFinite(fixedTime)) {
|
|
165
|
+
render(Number(fixedTime));
|
|
166
|
+
} else {
|
|
167
|
+
render(0);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const tick = () => {
|
|
171
|
+
if (!Number.isFinite(fixedTime)) {
|
|
172
|
+
render(((performance.now() - start) / 1000) % options.duration);
|
|
173
|
+
}
|
|
174
|
+
requestAnimationFrame(tick);
|
|
175
|
+
};
|
|
176
|
+
tick();
|
|
177
|
+
return root;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
declare global {
|
|
181
|
+
interface Window {
|
|
182
|
+
__AURA3D_CARTOON_2D_PUPPET_PROOF__?: PuppetEpisode2DProof;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function clampTime(time: number, duration: number) {
|
|
187
|
+
if (!Number.isFinite(time)) return 0;
|
|
188
|
+
return Math.max(0, Math.min(duration - 1 / 30, time));
|
|
189
|
+
}
|
|
@@ -48,7 +48,7 @@ export const audioStemManifest = createAudioStemManifest({
|
|
|
48
48
|
stems: [
|
|
49
49
|
...episode.dialogueTrack.lines.map((line) => ({
|
|
50
50
|
id: `audio:${line.lineId}`,
|
|
51
|
-
role: "dialogue",
|
|
51
|
+
role: "dialogue" as const,
|
|
52
52
|
path: line.audioFile ?? `assets/audio/en/${line.lineId}.wav`,
|
|
53
53
|
startTime: line.startTime,
|
|
54
54
|
duration: line.endTime - line.startTime,
|