@dotcraft/avatar 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +46 -43
- package/dist/accessories.css +14 -14
- package/dist/avatar.css +62 -62
- package/dist/composer/ComposerMascot.d.ts +1 -1
- package/dist/composer/ComposerMascot.d.ts.map +1 -1
- package/dist/composer/ComposerMascot.js +2 -2
- package/dist/composer/ComposerMascot.js.map +1 -1
- package/dist/composer/styles/energy.css +99 -99
- package/dist/composer/styles/expressions.css +20 -20
- package/dist/composer/styles/feedback.css +188 -188
- package/dist/composer/styles/focus.css +72 -72
- package/dist/composer/styles/foundation.css +301 -287
- package/dist/composer/styles/idle.css +438 -438
- package/dist/composer/styles/overdrive.css +264 -264
- package/dist/composer/styles/props.css +21 -21
- package/dist/composer/types.d.ts +1 -0
- package/dist/composer/types.d.ts.map +1 -1
- package/dist/rig.css +265 -265
- package/dist/styles.css +13 -13
- package/package.json +56 -55
- package/src/AnimatedDecoration.tsx +43 -0
- package/src/AppearanceRig.tsx +15 -0
- package/src/Avatar.tsx +85 -0
- package/src/DecorationShapes.tsx +8 -0
- package/src/Decorations.tsx +31 -0
- package/src/Faces.tsx +37 -0
- package/src/HatDecorations.tsx +75 -0
- package/src/HeldDecorations.tsx +48 -0
- package/src/MascotRig.tsx +191 -0
- package/src/ObjectDecorations.tsx +55 -0
- package/src/accessories.css +14 -0
- package/src/appearanceModel.ts +65 -0
- package/src/avatar.css +62 -0
- package/src/characters.ts +5 -0
- package/src/composer/ComposerMascot.tsx +521 -0
- package/src/composer/ComposerMascotShadow.tsx +5 -0
- package/src/composer/constants.ts +68 -0
- package/src/composer/mascotHandoff.ts +19 -0
- package/src/composer/styles/energy.css +99 -0
- package/src/composer/styles/expressions.css +20 -0
- package/src/composer/styles/feedback.css +188 -0
- package/src/composer/styles/focus.css +72 -0
- package/src/composer/styles/foundation.css +301 -0
- package/src/composer/styles/idle.css +438 -0
- package/src/composer/styles/overdrive.css +264 -0
- package/src/composer/styles/props.css +21 -0
- package/src/composer/types.ts +32 -0
- package/src/composer/useComposerAvatarBehavior.ts +97 -0
- package/src/composer/useComposerMotion.ts +15 -0
- package/src/composer/useComposerProfile.ts +50 -0
- package/src/decorationCatalog.ts +45 -0
- package/src/decorationMotion.ts +68 -0
- package/src/environment.ts +46 -0
- package/src/index.ts +5 -0
- package/src/palette.ts +52 -0
- package/src/react.ts +6 -0
- package/src/rig.css +265 -0
- package/src/styles.css +13 -0
- package/src/useEventReplay.ts +13 -0
- package/src/useGesture.ts +51 -0
package/dist/rig.css
CHANGED
|
@@ -1,265 +1,265 @@
|
|
|
1
|
-
/* The robot's arm/antenna/face pieces carry stable dca-part-* classes (see
|
|
2
|
-
MascotRig.tsx). Each arm's white and blue pieces are separate elements moving in
|
|
3
|
-
lockstep, so transform-box: view-box resolves one shared origin for both. */
|
|
4
|
-
.dca-part-eyes,
|
|
5
|
-
.dca-part-glow,
|
|
6
|
-
.dca-part-light,
|
|
7
|
-
.dca-part-face {
|
|
8
|
-
transform-box: fill-box;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/* The incoming face waits out a ~70ms blank beat so two faces never blend into a
|
|
12
|
-
double exposure. */
|
|
13
|
-
.dca-part-face {
|
|
14
|
-
opacity: 0;
|
|
15
|
-
transition: opacity 110ms ease;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.dca-part-robot[data-expression='neutral'] .dca-part-face-neutral,
|
|
19
|
-
.dca-part-robot[data-expression='happy'] .dca-part-face-happy,
|
|
20
|
-
.dca-part-robot[data-expression='operator'] .dca-part-face-operator,
|
|
21
|
-
.dca-part-robot[data-expression='sleep'] .dca-part-face-sleep {
|
|
22
|
-
opacity: 1;
|
|
23
|
-
transition: opacity 150ms ease 70ms;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.dca-part-eyes {
|
|
27
|
-
transform-origin: center;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.dca-part-glow {
|
|
31
|
-
opacity: 0;
|
|
32
|
-
transform-origin: center;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.dca-part-light {
|
|
36
|
-
transform-origin: center;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/* The default 140ms transition-delay sequences "prop first, arm after" on retract, so
|
|
40
|
-
a prop is never left floating. Every rule that ENTERS a posed arm state overrides
|
|
41
|
-
the delay back to 0 so raises stay immediate. */
|
|
42
|
-
.dca-part-arm-l-w,
|
|
43
|
-
.dca-part-arm-l {
|
|
44
|
-
transform-box: view-box;
|
|
45
|
-
transform-origin: 233px 514px;
|
|
46
|
-
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 140ms;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.dca-part-arm-r-w,
|
|
50
|
-
.dca-part-arm-r-b {
|
|
51
|
-
transform-box: view-box;
|
|
52
|
-
transform-origin: 791px 514px;
|
|
53
|
-
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 140ms;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Every keyframe keeps the same function list (translate + rotate + scaleY) so the
|
|
57
|
-
interpolation stays smooth. translate dy=88 lands the hinge at ≈602 viewBox, the
|
|
58
|
-
height of the resting arm nub, so the hand lifts from where the arm already is. */
|
|
59
|
-
@keyframes dca-action-wave-arm {
|
|
60
|
-
0% {
|
|
61
|
-
transform: translate(0, 0) rotate(0) scaleY(1);
|
|
62
|
-
}
|
|
63
|
-
16% {
|
|
64
|
-
transform: translate(-48px, 88px) rotate(-122deg) scaleY(0.8);
|
|
65
|
-
}
|
|
66
|
-
32% {
|
|
67
|
-
transform: translate(-48px, 88px) rotate(-92deg) scaleY(0.8);
|
|
68
|
-
}
|
|
69
|
-
48% {
|
|
70
|
-
transform: translate(-48px, 88px) rotate(-122deg) scaleY(0.8);
|
|
71
|
-
}
|
|
72
|
-
64% {
|
|
73
|
-
transform: translate(-48px, 88px) rotate(-92deg) scaleY(0.8);
|
|
74
|
-
}
|
|
75
|
-
80% {
|
|
76
|
-
transform: translate(-48px, 88px) rotate(-114deg) scaleY(0.8);
|
|
77
|
-
}
|
|
78
|
-
100% {
|
|
79
|
-
transform: translate(0, 0) rotate(0) scaleY(1);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@keyframes dca-action-wave-lean {
|
|
84
|
-
0%,
|
|
85
|
-
100% {
|
|
86
|
-
transform: rotate(0);
|
|
87
|
-
}
|
|
88
|
-
20%,
|
|
89
|
-
80% {
|
|
90
|
-
transform: rotate(3deg);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.dca-action-wave .dca-part-arm-r-w,
|
|
95
|
-
.dca-action-wave .dca-part-arm-r-b {
|
|
96
|
-
animation: dca-action-wave-arm 1.6s ease-in-out both;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.dca-action-wave .dca-action-jelly {
|
|
100
|
-
animation: dca-action-wave-lean 1.6s ease-in-out both;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* Props are always-mounted `dca-part-prop-*` groups inside MascotRobot at opacity 0,
|
|
104
|
-
revealed by these composer root classes. */
|
|
105
|
-
|
|
106
|
-
/* Mini terminal: the 1200ms transition delay keeps quick turns from flashing it. The
|
|
107
|
-
arms only tuck inward by pure translate — a rotation would trigger the solid-colour
|
|
108
|
-
swap and break the gradient's continuity with the torso. */
|
|
109
|
-
.dca-part-prop-laptop {
|
|
110
|
-
opacity: 0;
|
|
111
|
-
transition: opacity 200ms ease;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.dca-action-prop-laptop .dca-part-prop-laptop {
|
|
115
|
-
opacity: 1;
|
|
116
|
-
transition: opacity 240ms ease 1200ms;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.dca-action-prop-laptop .dca-part-arm-l-w,
|
|
120
|
-
.dca-action-prop-laptop .dca-part-arm-l {
|
|
121
|
-
transform: translate(18px, 0);
|
|
122
|
-
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 1200ms;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.dca-action-prop-laptop .dca-part-arm-r-w,
|
|
126
|
-
.dca-action-prop-laptop .dca-part-arm-r-b {
|
|
127
|
-
transform: translate(-18px, 0);
|
|
128
|
-
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 1200ms;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
@keyframes dca-action-laptop-scroll {
|
|
132
|
-
0%,
|
|
133
|
-
58% {
|
|
134
|
-
transform: translateY(0);
|
|
135
|
-
}
|
|
136
|
-
66%,
|
|
137
|
-
100% {
|
|
138
|
-
transform: translateY(-36px);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.dca-action-prop-laptop .dca-part-laptop-lines {
|
|
143
|
-
animation: dca-action-laptop-scroll 2200ms ease-in-out 1640ms infinite;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@keyframes dca-action-laptop-caret {
|
|
147
|
-
0%,
|
|
148
|
-
100% {
|
|
149
|
-
opacity: 1;
|
|
150
|
-
}
|
|
151
|
-
50% {
|
|
152
|
-
opacity: 0;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.dca-action-prop-laptop .dca-part-laptop-caret {
|
|
157
|
-
animation: dca-action-laptop-caret 800ms steps(1, end) infinite;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/* The sign fades in only after the arm settles (320ms spring plus a beat), and on
|
|
161
|
-
retract it hides first while the arm waits out its 140ms transition-delay, so the
|
|
162
|
-
prop is never left floating without a hand. */
|
|
163
|
-
.dca-action-hold-sign .dca-part-arm-r-w,
|
|
164
|
-
.dca-action-hold-sign .dca-part-arm-r-b {
|
|
165
|
-
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
166
|
-
transition-delay: 0ms;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.dca-action-hold-sign .dca-part-arm-r-b {
|
|
170
|
-
fill: var(--dca-part-raised-arm-right, #7a96fb);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.dca-part-prop-sign {
|
|
174
|
-
opacity: 0;
|
|
175
|
-
transition: opacity 140ms ease;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.dca-action-hold-sign .dca-part-prop-sign {
|
|
179
|
-
opacity: 1;
|
|
180
|
-
transition: opacity 180ms ease 340ms;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/* Click greeting while the sign is held: only the angle moves, and it starts and ends
|
|
184
|
-
exactly at the held pose so the hand-off to .dca-action-hold-sign is seamless.
|
|
185
|
-
The compound selector outranks the lone .dca-action-wave arm rule. */
|
|
186
|
-
@keyframes dca-action-sign-wave-arm {
|
|
187
|
-
0% {
|
|
188
|
-
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
189
|
-
}
|
|
190
|
-
18% {
|
|
191
|
-
transform: translate(-48px, 88px) rotate(-143deg) scaleY(0.8);
|
|
192
|
-
}
|
|
193
|
-
42% {
|
|
194
|
-
transform: translate(-48px, 88px) rotate(-113deg) scaleY(0.8);
|
|
195
|
-
}
|
|
196
|
-
66% {
|
|
197
|
-
transform: translate(-48px, 88px) rotate(-143deg) scaleY(0.8);
|
|
198
|
-
}
|
|
199
|
-
86% {
|
|
200
|
-
transform: translate(-48px, 88px) rotate(-120deg) scaleY(0.8);
|
|
201
|
-
}
|
|
202
|
-
100% {
|
|
203
|
-
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/* Pure rotation about the hand's pivot: the shoulder hinge (791,514) shifted by the
|
|
208
|
-
held translate (-48,88), i.e. C = (743,602), by exactly the arm's angular deviation
|
|
209
|
-
from -128° at each step. Same centre and delta keeps the board gripped. */
|
|
210
|
-
@keyframes dca-action-sign-wave-prop {
|
|
211
|
-
0% {
|
|
212
|
-
transform: rotate(0deg);
|
|
213
|
-
}
|
|
214
|
-
18% {
|
|
215
|
-
transform: rotate(-15deg);
|
|
216
|
-
}
|
|
217
|
-
42% {
|
|
218
|
-
transform: rotate(15deg);
|
|
219
|
-
}
|
|
220
|
-
66% {
|
|
221
|
-
transform: rotate(-15deg);
|
|
222
|
-
}
|
|
223
|
-
86% {
|
|
224
|
-
transform: rotate(8deg);
|
|
225
|
-
}
|
|
226
|
-
100% {
|
|
227
|
-
transform: rotate(0deg);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.dca-action-hold-sign.dca-action-wave .dca-part-arm-r-w,
|
|
232
|
-
.dca-action-hold-sign.dca-action-wave .dca-part-arm-r-b {
|
|
233
|
-
animation: dca-action-sign-wave-arm 1.6s ease-in-out;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.dca-action-hold-sign.dca-action-wave .dca-part-prop-sign {
|
|
237
|
-
transform-box: view-box;
|
|
238
|
-
transform-origin: 743px 602px;
|
|
239
|
-
animation: dca-action-sign-wave-prop 1.6s ease-in-out;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/* The cheer reuses the wave's slide-then-rotate hinge grammar, so the outline wraps
|
|
243
|
-
the band and the colour stays seam-continuous. */
|
|
244
|
-
.dca-action-celebrate .dca-part-arm-l-w,
|
|
245
|
-
.dca-action-celebrate .dca-part-arm-l {
|
|
246
|
-
transform: translate(48px, 88px) rotate(135deg) scaleY(0.82);
|
|
247
|
-
transition-delay: 0ms;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.dca-action-celebrate .dca-part-arm-r-w,
|
|
251
|
-
.dca-action-celebrate .dca-part-arm-r-b {
|
|
252
|
-
transform: translate(-48px, 88px) rotate(-135deg) scaleY(0.82);
|
|
253
|
-
transition-delay: 0ms;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/* Raised arms swap the body gradient for a solid hinge colour, so a rotated arm has
|
|
257
|
-
no gradient to diverge from the torso's field. White halo capsules stay white. */
|
|
258
|
-
.dca-action-wave .dca-part-arm-r-b,
|
|
259
|
-
.dca-action-celebrate .dca-part-arm-r-b {
|
|
260
|
-
fill: var(--dca-part-raised-arm-right, #7a96fb);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.dca-action-celebrate .dca-part-arm-l-b {
|
|
264
|
-
fill: var(--dca-part-raised-arm-left, #3161f7);
|
|
265
|
-
}
|
|
1
|
+
/* The robot's arm/antenna/face pieces carry stable dca-part-* classes (see
|
|
2
|
+
MascotRig.tsx). Each arm's white and blue pieces are separate elements moving in
|
|
3
|
+
lockstep, so transform-box: view-box resolves one shared origin for both. */
|
|
4
|
+
.dca-part-eyes,
|
|
5
|
+
.dca-part-glow,
|
|
6
|
+
.dca-part-light,
|
|
7
|
+
.dca-part-face {
|
|
8
|
+
transform-box: fill-box;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* The incoming face waits out a ~70ms blank beat so two faces never blend into a
|
|
12
|
+
double exposure. */
|
|
13
|
+
.dca-part-face {
|
|
14
|
+
opacity: 0;
|
|
15
|
+
transition: opacity 110ms ease;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.dca-part-robot[data-expression='neutral'] .dca-part-face-neutral,
|
|
19
|
+
.dca-part-robot[data-expression='happy'] .dca-part-face-happy,
|
|
20
|
+
.dca-part-robot[data-expression='operator'] .dca-part-face-operator,
|
|
21
|
+
.dca-part-robot[data-expression='sleep'] .dca-part-face-sleep {
|
|
22
|
+
opacity: 1;
|
|
23
|
+
transition: opacity 150ms ease 70ms;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.dca-part-eyes {
|
|
27
|
+
transform-origin: center;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.dca-part-glow {
|
|
31
|
+
opacity: 0;
|
|
32
|
+
transform-origin: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.dca-part-light {
|
|
36
|
+
transform-origin: center;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* The default 140ms transition-delay sequences "prop first, arm after" on retract, so
|
|
40
|
+
a prop is never left floating. Every rule that ENTERS a posed arm state overrides
|
|
41
|
+
the delay back to 0 so raises stay immediate. */
|
|
42
|
+
.dca-part-arm-l-w,
|
|
43
|
+
.dca-part-arm-l {
|
|
44
|
+
transform-box: view-box;
|
|
45
|
+
transform-origin: 233px 514px;
|
|
46
|
+
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 140ms;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.dca-part-arm-r-w,
|
|
50
|
+
.dca-part-arm-r-b {
|
|
51
|
+
transform-box: view-box;
|
|
52
|
+
transform-origin: 791px 514px;
|
|
53
|
+
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 140ms;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Every keyframe keeps the same function list (translate + rotate + scaleY) so the
|
|
57
|
+
interpolation stays smooth. translate dy=88 lands the hinge at ≈602 viewBox, the
|
|
58
|
+
height of the resting arm nub, so the hand lifts from where the arm already is. */
|
|
59
|
+
@keyframes dca-action-wave-arm {
|
|
60
|
+
0% {
|
|
61
|
+
transform: translate(0, 0) rotate(0) scaleY(1);
|
|
62
|
+
}
|
|
63
|
+
16% {
|
|
64
|
+
transform: translate(-48px, 88px) rotate(-122deg) scaleY(0.8);
|
|
65
|
+
}
|
|
66
|
+
32% {
|
|
67
|
+
transform: translate(-48px, 88px) rotate(-92deg) scaleY(0.8);
|
|
68
|
+
}
|
|
69
|
+
48% {
|
|
70
|
+
transform: translate(-48px, 88px) rotate(-122deg) scaleY(0.8);
|
|
71
|
+
}
|
|
72
|
+
64% {
|
|
73
|
+
transform: translate(-48px, 88px) rotate(-92deg) scaleY(0.8);
|
|
74
|
+
}
|
|
75
|
+
80% {
|
|
76
|
+
transform: translate(-48px, 88px) rotate(-114deg) scaleY(0.8);
|
|
77
|
+
}
|
|
78
|
+
100% {
|
|
79
|
+
transform: translate(0, 0) rotate(0) scaleY(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@keyframes dca-action-wave-lean {
|
|
84
|
+
0%,
|
|
85
|
+
100% {
|
|
86
|
+
transform: rotate(0);
|
|
87
|
+
}
|
|
88
|
+
20%,
|
|
89
|
+
80% {
|
|
90
|
+
transform: rotate(3deg);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.dca-action-wave .dca-part-arm-r-w,
|
|
95
|
+
.dca-action-wave .dca-part-arm-r-b {
|
|
96
|
+
animation: dca-action-wave-arm 1.6s ease-in-out both;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.dca-action-wave .dca-action-jelly {
|
|
100
|
+
animation: dca-action-wave-lean 1.6s ease-in-out both;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Props are always-mounted `dca-part-prop-*` groups inside MascotRobot at opacity 0,
|
|
104
|
+
revealed by these composer root classes. */
|
|
105
|
+
|
|
106
|
+
/* Mini terminal: the 1200ms transition delay keeps quick turns from flashing it. The
|
|
107
|
+
arms only tuck inward by pure translate — a rotation would trigger the solid-colour
|
|
108
|
+
swap and break the gradient's continuity with the torso. */
|
|
109
|
+
.dca-part-prop-laptop {
|
|
110
|
+
opacity: 0;
|
|
111
|
+
transition: opacity 200ms ease;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.dca-action-prop-laptop .dca-part-prop-laptop {
|
|
115
|
+
opacity: 1;
|
|
116
|
+
transition: opacity 240ms ease 1200ms;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.dca-action-prop-laptop .dca-part-arm-l-w,
|
|
120
|
+
.dca-action-prop-laptop .dca-part-arm-l {
|
|
121
|
+
transform: translate(18px, 0);
|
|
122
|
+
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 1200ms;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.dca-action-prop-laptop .dca-part-arm-r-w,
|
|
126
|
+
.dca-action-prop-laptop .dca-part-arm-r-b {
|
|
127
|
+
transform: translate(-18px, 0);
|
|
128
|
+
transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 1200ms;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@keyframes dca-action-laptop-scroll {
|
|
132
|
+
0%,
|
|
133
|
+
58% {
|
|
134
|
+
transform: translateY(0);
|
|
135
|
+
}
|
|
136
|
+
66%,
|
|
137
|
+
100% {
|
|
138
|
+
transform: translateY(-36px);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.dca-action-prop-laptop .dca-part-laptop-lines {
|
|
143
|
+
animation: dca-action-laptop-scroll 2200ms ease-in-out 1640ms infinite;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@keyframes dca-action-laptop-caret {
|
|
147
|
+
0%,
|
|
148
|
+
100% {
|
|
149
|
+
opacity: 1;
|
|
150
|
+
}
|
|
151
|
+
50% {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.dca-action-prop-laptop .dca-part-laptop-caret {
|
|
157
|
+
animation: dca-action-laptop-caret 800ms steps(1, end) infinite;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* The sign fades in only after the arm settles (320ms spring plus a beat), and on
|
|
161
|
+
retract it hides first while the arm waits out its 140ms transition-delay, so the
|
|
162
|
+
prop is never left floating without a hand. */
|
|
163
|
+
.dca-action-hold-sign .dca-part-arm-r-w,
|
|
164
|
+
.dca-action-hold-sign .dca-part-arm-r-b {
|
|
165
|
+
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
166
|
+
transition-delay: 0ms;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.dca-action-hold-sign .dca-part-arm-r-b {
|
|
170
|
+
fill: var(--dca-part-raised-arm-right, #7a96fb);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.dca-part-prop-sign {
|
|
174
|
+
opacity: 0;
|
|
175
|
+
transition: opacity 140ms ease;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.dca-action-hold-sign .dca-part-prop-sign {
|
|
179
|
+
opacity: 1;
|
|
180
|
+
transition: opacity 180ms ease 340ms;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Click greeting while the sign is held: only the angle moves, and it starts and ends
|
|
184
|
+
exactly at the held pose so the hand-off to .dca-action-hold-sign is seamless.
|
|
185
|
+
The compound selector outranks the lone .dca-action-wave arm rule. */
|
|
186
|
+
@keyframes dca-action-sign-wave-arm {
|
|
187
|
+
0% {
|
|
188
|
+
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
189
|
+
}
|
|
190
|
+
18% {
|
|
191
|
+
transform: translate(-48px, 88px) rotate(-143deg) scaleY(0.8);
|
|
192
|
+
}
|
|
193
|
+
42% {
|
|
194
|
+
transform: translate(-48px, 88px) rotate(-113deg) scaleY(0.8);
|
|
195
|
+
}
|
|
196
|
+
66% {
|
|
197
|
+
transform: translate(-48px, 88px) rotate(-143deg) scaleY(0.8);
|
|
198
|
+
}
|
|
199
|
+
86% {
|
|
200
|
+
transform: translate(-48px, 88px) rotate(-120deg) scaleY(0.8);
|
|
201
|
+
}
|
|
202
|
+
100% {
|
|
203
|
+
transform: translate(-48px, 88px) rotate(-128deg) scaleY(0.8);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Pure rotation about the hand's pivot: the shoulder hinge (791,514) shifted by the
|
|
208
|
+
held translate (-48,88), i.e. C = (743,602), by exactly the arm's angular deviation
|
|
209
|
+
from -128° at each step. Same centre and delta keeps the board gripped. */
|
|
210
|
+
@keyframes dca-action-sign-wave-prop {
|
|
211
|
+
0% {
|
|
212
|
+
transform: rotate(0deg);
|
|
213
|
+
}
|
|
214
|
+
18% {
|
|
215
|
+
transform: rotate(-15deg);
|
|
216
|
+
}
|
|
217
|
+
42% {
|
|
218
|
+
transform: rotate(15deg);
|
|
219
|
+
}
|
|
220
|
+
66% {
|
|
221
|
+
transform: rotate(-15deg);
|
|
222
|
+
}
|
|
223
|
+
86% {
|
|
224
|
+
transform: rotate(8deg);
|
|
225
|
+
}
|
|
226
|
+
100% {
|
|
227
|
+
transform: rotate(0deg);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.dca-action-hold-sign.dca-action-wave .dca-part-arm-r-w,
|
|
232
|
+
.dca-action-hold-sign.dca-action-wave .dca-part-arm-r-b {
|
|
233
|
+
animation: dca-action-sign-wave-arm 1.6s ease-in-out;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.dca-action-hold-sign.dca-action-wave .dca-part-prop-sign {
|
|
237
|
+
transform-box: view-box;
|
|
238
|
+
transform-origin: 743px 602px;
|
|
239
|
+
animation: dca-action-sign-wave-prop 1.6s ease-in-out;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* The cheer reuses the wave's slide-then-rotate hinge grammar, so the outline wraps
|
|
243
|
+
the band and the colour stays seam-continuous. */
|
|
244
|
+
.dca-action-celebrate .dca-part-arm-l-w,
|
|
245
|
+
.dca-action-celebrate .dca-part-arm-l {
|
|
246
|
+
transform: translate(48px, 88px) rotate(135deg) scaleY(0.82);
|
|
247
|
+
transition-delay: 0ms;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.dca-action-celebrate .dca-part-arm-r-w,
|
|
251
|
+
.dca-action-celebrate .dca-part-arm-r-b {
|
|
252
|
+
transform: translate(-48px, 88px) rotate(-135deg) scaleY(0.82);
|
|
253
|
+
transition-delay: 0ms;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* Raised arms swap the body gradient for a solid hinge colour, so a rotated arm has
|
|
257
|
+
no gradient to diverge from the torso's field. White halo capsules stay white. */
|
|
258
|
+
.dca-action-wave .dca-part-arm-r-b,
|
|
259
|
+
.dca-action-celebrate .dca-part-arm-r-b {
|
|
260
|
+
fill: var(--dca-part-raised-arm-right, #7a96fb);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.dca-action-celebrate .dca-part-arm-l-b {
|
|
264
|
+
fill: var(--dca-part-raised-arm-left, #3161f7);
|
|
265
|
+
}
|
package/dist/styles.css
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
@import './rig.css';
|
|
2
|
-
@import './avatar.css';
|
|
3
|
-
@import './accessories.css';
|
|
4
|
-
|
|
5
|
-
@import "./composer/styles/foundation.css";
|
|
6
|
-
@import "./composer/styles/overdrive.css";
|
|
7
|
-
@import "./composer/styles/idle.css";
|
|
8
|
-
@import "./composer/styles/focus.css";
|
|
9
|
-
@import "./composer/styles/expressions.css";
|
|
10
|
-
@import "./composer/styles/feedback.css";
|
|
11
|
-
@import "./composer/styles/props.css";
|
|
12
|
-
|
|
13
|
-
@import "./composer/styles/energy.css";
|
|
1
|
+
@import './rig.css';
|
|
2
|
+
@import './avatar.css';
|
|
3
|
+
@import './accessories.css';
|
|
4
|
+
|
|
5
|
+
@import "./composer/styles/foundation.css";
|
|
6
|
+
@import "./composer/styles/overdrive.css";
|
|
7
|
+
@import "./composer/styles/idle.css";
|
|
8
|
+
@import "./composer/styles/focus.css";
|
|
9
|
+
@import "./composer/styles/expressions.css";
|
|
10
|
+
@import "./composer/styles/feedback.css";
|
|
11
|
+
@import "./composer/styles/props.css";
|
|
12
|
+
|
|
13
|
+
@import "./composer/styles/energy.css";
|
package/package.json
CHANGED
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dotcraft/avatar",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "Name-derived DotCraft avatars and React SVG animation components",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./react": {
|
|
14
|
-
"types": "./dist/react.d.ts",
|
|
15
|
-
"import": "./dist/react.js"
|
|
16
|
-
},
|
|
17
|
-
"./styles.css": "./dist/styles.css"
|
|
18
|
-
},
|
|
19
|
-
"files": [
|
|
20
|
-
"dist"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"react
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@dotcraft/avatar",
|
|
3
|
+
"version": "0.6.4",
|
|
4
|
+
"description": "Name-derived DotCraft avatars and React SVG animation components",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./react": {
|
|
14
|
+
"types": "./dist/react.d.ts",
|
|
15
|
+
"import": "./dist/react.js"
|
|
16
|
+
},
|
|
17
|
+
"./styles.css": "./dist/styles.css"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"src"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"**/*.css"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "node ../../scripts/clean-dist.mjs . && tsc -p tsconfig.json && node scripts/copy-styles.mjs",
|
|
28
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
29
|
+
"test": "npm run build && node --test tests/*.test.mjs"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": "^19.0.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependenciesMeta": {
|
|
35
|
+
"react": {
|
|
36
|
+
"optional": true
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"react": "^19.0.0",
|
|
41
|
+
"react-dom": "^19.0.0",
|
|
42
|
+
"@types/react": "^19.0.0",
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"jsdom": "^29.1.1"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"registry": "https://registry.npmjs.org"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/DotHarness/dotcraft.git",
|
|
53
|
+
"directory": "sdk/typescript/packages/avatar"
|
|
54
|
+
},
|
|
55
|
+
"license": "Apache-2.0"
|
|
56
|
+
}
|