@dotcraft/avatar 0.7.3 → 0.7.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/README.md +1 -1
- package/dist/BackDecorations.d.ts.map +1 -1
- package/dist/BackDecorations.js +100 -6
- package/dist/BackDecorations.js.map +1 -1
- package/dist/CloudDragon.d.ts +3 -0
- package/dist/CloudDragon.d.ts.map +1 -0
- package/dist/CloudDragon.js +70 -0
- package/dist/CloudDragon.js.map +1 -0
- package/dist/DecorationShapes.d.ts +5 -0
- package/dist/DecorationShapes.d.ts.map +1 -1
- package/dist/DecorationShapes.js +4 -0
- package/dist/DecorationShapes.js.map +1 -1
- package/dist/Decorations.d.ts.map +1 -1
- package/dist/Decorations.js +3 -2
- package/dist/Decorations.js.map +1 -1
- package/dist/FaceDecorations.d.ts.map +1 -1
- package/dist/FaceDecorations.js +105 -5
- package/dist/FaceDecorations.js.map +1 -1
- package/dist/HandDecorations.d.ts.map +1 -1
- package/dist/HandDecorations.js +19 -2
- package/dist/HandDecorations.js.map +1 -1
- package/dist/HatDecorations.d.ts.map +1 -1
- package/dist/HatDecorations.js +1 -0
- package/dist/HatDecorations.js.map +1 -1
- package/dist/ObjectDecorations.d.ts.map +1 -1
- package/dist/ObjectDecorations.js +59 -0
- package/dist/ObjectDecorations.js.map +1 -1
- package/dist/SkinDecorations.d.ts.map +1 -1
- package/dist/SkinDecorations.js +37 -8
- package/dist/SkinDecorations.js.map +1 -1
- package/dist/accessories.css +4 -2
- package/dist/composer/ComposerMascot.d.ts +1 -1
- package/dist/composer/ComposerMascot.d.ts.map +1 -1
- package/dist/composer/ComposerMascot.js +5 -4
- package/dist/composer/ComposerMascot.js.map +1 -1
- package/dist/composer/styles/energy.css +23 -3
- package/dist/composer/types.d.ts +3 -0
- package/dist/composer/types.d.ts.map +1 -1
- package/dist/decorationCatalog.d.ts.map +1 -1
- package/dist/decorationCatalog.js +91 -0
- package/dist/decorationCatalog.js.map +1 -1
- package/dist/decorationMotion.d.ts.map +1 -1
- package/dist/decorationMotion.js +5 -2
- package/dist/decorationMotion.js.map +1 -1
- package/dist/effects.css +65 -4
- package/dist/items.d.ts +546 -0
- package/dist/items.d.ts.map +1 -1
- package/dist/items.js +42 -13
- package/dist/items.js.map +1 -1
- package/dist/paintMaterials.d.ts +36 -0
- package/dist/paintMaterials.d.ts.map +1 -1
- package/dist/paintMaterials.js +9 -0
- package/dist/paintMaterials.js.map +1 -1
- package/dist/spine.d.ts +15 -0
- package/dist/spine.d.ts.map +1 -0
- package/dist/spine.js +53 -0
- package/dist/spine.js.map +1 -0
- package/package.json +1 -1
- package/src/BackDecorations.tsx +250 -5
- package/src/CloudDragon.tsx +110 -0
- package/src/DecorationShapes.tsx +4 -0
- package/src/Decorations.tsx +4 -3
- package/src/FaceDecorations.tsx +254 -11
- package/src/HandDecorations.tsx +223 -1
- package/src/HatDecorations.tsx +8 -0
- package/src/ObjectDecorations.tsx +180 -0
- package/src/SkinDecorations.tsx +77 -12
- package/src/accessories.css +4 -2
- package/src/composer/ComposerMascot.tsx +5 -4
- package/src/composer/styles/energy.css +23 -3
- package/src/composer/types.ts +3 -0
- package/src/decorationCatalog.ts +91 -0
- package/src/decorationMotion.ts +5 -2
- package/src/effects.css +65 -4
- package/src/items.ts +43 -13
- package/src/paintMaterials.ts +9 -0
- package/src/spine.ts +61 -0
package/src/FaceDecorations.tsx
CHANGED
|
@@ -2,7 +2,22 @@ import { useId, type ReactNode } from 'react'
|
|
|
2
2
|
import type { FaceId, Zone } from './items.js'
|
|
3
3
|
import { itemOf } from './items.js'
|
|
4
4
|
import type { Faceplate } from './MascotRig.js'
|
|
5
|
-
import { useClipId } from './DecorationShapes.js'
|
|
5
|
+
import { Detail, Glow, Silhouette as S, useClipId } from './DecorationShapes.js'
|
|
6
|
+
|
|
7
|
+
const heartLens = 'c-31-11-52-22-52-34 0-10 15-16 29-16 10 0 19 3 23 8 4-5 13-8 23-8 14 0 29 6 29 16 0 12-21 23-52 34Z'
|
|
8
|
+
const snorkelTube = 'M792 458V372q0-30 28-40'
|
|
9
|
+
const mark = 'var(--dca-held-mark, #3161f7)'
|
|
10
|
+
const melon = (x: number, rx: number, ry: number) => `M${x - rx} 414h${rx * 2}a${rx} ${ry} 0 0 1-${rx * 2} 0Z`
|
|
11
|
+
function star(cx: number, cy: number) {
|
|
12
|
+
return `M${Array.from({ length: 10 }, (_, i) => {
|
|
13
|
+
const angle = (i * 36 - 90) * Math.PI / 180, r = i % 2 ? .52 : 1
|
|
14
|
+
return `${(cx + 46 * r * Math.cos(angle)).toFixed(1)} ${(cy + 27 * r * Math.sin(angle)).toFixed(1)}`
|
|
15
|
+
}).join('L')}Z`
|
|
16
|
+
}
|
|
17
|
+
const rosettePoint = (r: number, i: number) => `${(512 + r * Math.cos(i * Math.PI / 5)).toFixed(1)} ${(834 + r * Math.sin(i * Math.PI / 5)).toFixed(1)}`
|
|
18
|
+
const rosette = `M${rosettePoint(40, 0)}${Array.from({ length: 10 }, (_, i) => `A13 13 0 0 1 ${rosettePoint(40, i + 1)}`).join('')}Z`
|
|
19
|
+
const pleats = Array.from({ length: 10 }, (_, i) => `M${rosettePoint(30, i)}L${rosettePoint(42, i)}`).join('')
|
|
20
|
+
const crystal = 'M512 814c12 14 26 28 26 40a26 26 0 0 1-52 0c0-12 14-26 26-40Z'
|
|
6
21
|
|
|
7
22
|
export function FaceDecoration({ id }: { id: FaceId }) {
|
|
8
23
|
switch (id) {
|
|
@@ -17,6 +32,109 @@ export function FaceDecoration({ id }: { id: FaceId }) {
|
|
|
17
32
|
<path d="M488 432h48" stroke="#2b2f3a" strokeWidth="12" strokeLinecap="round" />
|
|
18
33
|
<path d="M386 428h44M550 428h44" stroke="#6b7280" strokeWidth="10" strokeLinecap="round" />
|
|
19
34
|
</>
|
|
35
|
+
case 'heart-glasses': return <>
|
|
36
|
+
<S d={`M430 462${heartLens}M594 462${heartLens}`} fill="#c9577a" stroke={12} />
|
|
37
|
+
<path d="M482 426h60" stroke="#c9577a" strokeWidth="12" strokeLinecap="round" />
|
|
38
|
+
<path d="M396 430q2-9 12-11M560 430q2-9 12-11" stroke="#f2a0b4" strokeWidth="9" strokeLinecap="round" fill="none" />
|
|
39
|
+
</>
|
|
40
|
+
case 'headlamp': return <>
|
|
41
|
+
<path d="M300 436h424" stroke="#3c4658" strokeWidth="20" strokeLinecap="round" />
|
|
42
|
+
<S d="M448 416h128a16 16 0 0 1 16 16v8a16 16 0 0 1-16 16H448a16 16 0 0 1-16-16v-8a16 16 0 0 1 16-16ZM484 436a28 28 0 1 1 56 0a28 28 0 1 1-56 0Z" fill="#3c4658" stroke={12} />
|
|
43
|
+
<circle cx="512" cy="436" r="24" fill="#ffd970" stroke="#8b95a5" strokeWidth="6" /><circle cx="512" cy="436" r="8" fill="#fff" />
|
|
44
|
+
</>
|
|
45
|
+
case 'snorkel-mask': return <>
|
|
46
|
+
<path d="M300 436h424" stroke="#3c4658" strokeWidth="14" strokeLinecap="round" />
|
|
47
|
+
<rect x="378" y="411" width="268" height="52" rx="22" fill="#3c4658" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
48
|
+
<rect x="390" y="422" width="244" height="30" rx="12" fill="#a2c5d1" />
|
|
49
|
+
<path d="m404 428 14 18m190-18 14 18" stroke="#e0eff1" strokeWidth="8" strokeLinecap="round" />
|
|
50
|
+
<g className="dca-part-temple" fill="none" strokeLinecap="round">
|
|
51
|
+
<path d="M724 436h52" stroke="#3c4658" strokeWidth="14" />
|
|
52
|
+
<path d={snorkelTube} stroke="#fff" strokeWidth="52" />
|
|
53
|
+
<path d={snorkelTube} stroke="#ed985f" strokeWidth="36" />
|
|
54
|
+
</g>
|
|
55
|
+
</>
|
|
56
|
+
case 'bow-tie': return <>
|
|
57
|
+
<S d="M512 816 602 788q18-5 18 13v58q0 18-18 13L512 844 422 872q-18 5-18-13v-58q0-18 18-13ZM490 830a22 22 0 1 1 44 0a22 22 0 1 1-44 0Z" fill="#e8654f" stroke={14} />
|
|
58
|
+
<circle cx="512" cy="830" r="22" fill="#b94f50" />
|
|
59
|
+
</>
|
|
60
|
+
case 'neckerchief': return <>
|
|
61
|
+
<S d="M391 786h242a13 13 0 0 1 0 26h-11L524 862q-12 10-24 0L402 812h-11a13 13 0 0 1 0-26Z" fill="#dbaa40" stroke={14} />
|
|
62
|
+
<rect x="378" y="786" width="268" height="26" rx="13" fill="#f3cf62" />
|
|
63
|
+
</>
|
|
64
|
+
case 'bell-collar': return <>
|
|
65
|
+
<rect x="356" y="794" width="312" height="30" rx="15" fill="#e8654f" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
66
|
+
<S d="M468 834a44 44 0 1 1 88 0a44 44 0 1 1-88 0Z" fill="#f6b500" stroke={14} />
|
|
67
|
+
<circle cx="512" cy="848" r="11" fill="#805840" /><path d="M512 848v22" stroke="#805840" strokeWidth="10" strokeLinecap="round" />
|
|
68
|
+
</>
|
|
69
|
+
case 'ear-pencil': return <g className="dca-part-temple" transform="rotate(-40 800 420)">
|
|
70
|
+
<S d="M712 420 752 398h122a14 14 0 0 1 14 14v16a14 14 0 0 1-14 14H752Z" fill="#f3cf62" stroke={14} />
|
|
71
|
+
<path d="M712 420 752 398v44Z" fill="#e0ad84" />
|
|
72
|
+
<path d="M860 398h14a14 14 0 0 1 14 14v16a14 14 0 0 1-14 14h-14Z" fill="#f2a0b4" />
|
|
73
|
+
</g>
|
|
74
|
+
case 'watermelon-glasses': return <>
|
|
75
|
+
<path d="M488 424q24-8 48 0" stroke="#4fae6a" strokeWidth="12" strokeLinecap="round" fill="none" />
|
|
76
|
+
<S d={melon(430, 58, 48) + melon(594, 58, 48)} fill="#4fae6a" stroke={12} />
|
|
77
|
+
<path d={melon(430, 50, 34) + melon(594, 50, 34)} fill="#eaf7d9" />
|
|
78
|
+
<path d={melon(430, 46, 29) + melon(594, 46, 29)} fill="#e8654f" />
|
|
79
|
+
<Detail><g fill="#2b2f3a">
|
|
80
|
+
<ellipse cx="410" cy="424" rx="4" ry="6" /><ellipse cx="432" cy="433" rx="4" ry="6" /><ellipse cx="454" cy="424" rx="4" ry="6" />
|
|
81
|
+
<ellipse cx="574" cy="424" rx="4" ry="6" /><ellipse cx="596" cy="433" rx="4" ry="6" /><ellipse cx="618" cy="424" rx="4" ry="6" />
|
|
82
|
+
</g></Detail>
|
|
83
|
+
</>
|
|
84
|
+
case 'star-glasses': return <>
|
|
85
|
+
<path d="M484 430h56" stroke="#e09a00" strokeWidth="12" strokeLinecap="round" />
|
|
86
|
+
<S d={star(440, 438) + star(584, 438)} fill="#ffd970" stroke={12} />
|
|
87
|
+
<path d={star(440, 438) + star(584, 438)} stroke="#e09a00" strokeWidth="7" strokeLinejoin="round" />
|
|
88
|
+
<path className="dca-fx dca-fx-sparkle-solo" d="M596 424l4 8 8 4-8 4-4 8-4-8-8-4 8-4Z" fill="#fff" />
|
|
89
|
+
</>
|
|
90
|
+
case 'sticky-note': return <g className="dca-part-temple" transform="rotate(12 796 416)">
|
|
91
|
+
<S d="M752 372h88v60l-28 28h-60Z" fill="#f6d365" stroke={14} />
|
|
92
|
+
<path d="M840 432h-22q-6 0-6 6v22Z" fill="#e8b93a" />
|
|
93
|
+
<Detail><path d="M766 398h58M766 420h40" stroke="#c9a13a" strokeWidth="6" strokeLinecap="round" /></Detail>
|
|
94
|
+
</g>
|
|
95
|
+
case 'lanyard-badge': return <>
|
|
96
|
+
<path d="M406 796 500 808M618 796 524 808" stroke="#fff" strokeWidth="28" strokeLinecap="round" />
|
|
97
|
+
<path d="M406 796 500 808M618 796 524 808" stroke="#f6b500" strokeWidth="14" strokeLinecap="round" />
|
|
98
|
+
<rect x="461" y="800" width="102" height="78" rx="12" fill={mark} stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
99
|
+
<rect x="471" y="830" width="82" height="40" rx="6" fill="#fff" />
|
|
100
|
+
<rect x="501" y="790" width="22" height="20" rx="5" fill="#8b95a5" />
|
|
101
|
+
<rect x="478" y="837" width="26" height="26" rx="5" fill="#3c4658" />
|
|
102
|
+
<Detail><path d="M513 845h30M513 859h20" stroke="#a7b1c0" strokeWidth="7" strokeLinecap="round" /></Detail>
|
|
103
|
+
</>
|
|
104
|
+
case 'prize-rosette': return <>
|
|
105
|
+
<S d="M505 828 519 848 459 884 462 870 445 864ZM519 828 505 848 565 884 562 870 579 864Z" fill="#3161f7" stroke={12} />
|
|
106
|
+
<S d={rosette} fill="#4f7cf6" stroke={12} />
|
|
107
|
+
<Detail><path d={pleats} stroke="#3161f7" strokeWidth="5" strokeLinecap="round" /></Detail>
|
|
108
|
+
<circle cx="512" cy="834" r="23" fill="#f6b500" stroke="#dbe6ff" strokeWidth="8" />
|
|
109
|
+
</>
|
|
110
|
+
case 'cherry-charm': return <g className="dca-part-temple">
|
|
111
|
+
<path d="M764 422q4-24 26-30 18 4 34 20" stroke="#fff" strokeWidth="22" strokeLinecap="round" strokeLinejoin="round" fill="none" />
|
|
112
|
+
<path d="M764 422q4-24 26-30 18 4 34 20" stroke="#5b887a" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round" fill="none" />
|
|
113
|
+
<S d="M790 392q10-22 36-22-6 24-36 22Z" fill="#89b875" stroke={10} />
|
|
114
|
+
<S d="M737 448a27 27 0 1 1 54 0a27 27 0 1 1-54 0ZM797 438a27 27 0 1 1 54 0a27 27 0 1 1-54 0Z" fill="#e8654f" stroke={12} />
|
|
115
|
+
<Detail><path d="M750 440q2-9 10-11M810 430q2-9 10-11" stroke="#fff4ef" strokeWidth="6" strokeLinecap="round" fill="none" /><path d="M768 466q14 6 18-9M828 456q14 6 18-9" stroke="#b94f50" strokeWidth="6" strokeLinecap="round" fill="none" /></Detail>
|
|
116
|
+
</g>
|
|
117
|
+
case 'songbird': return <g className="dca-part-temple" strokeLinecap="round">
|
|
118
|
+
<path d="M782 408l-2 10M794 414l-1 16" stroke="#2b2f3a" strokeWidth="6" />
|
|
119
|
+
<S d="M828 376 864 362 860 398 830 396Z" fill="#3161f7" stroke={12} />
|
|
120
|
+
<S d="M770 386a32 32 0 1 1 64 0a32 32 0 1 1-64 0Z" fill="#4f7cf6" stroke={12} />
|
|
121
|
+
<path d="M772 375A32 32 0 0 0 818 414Q812 390 772 375Z" fill="#ed985f" />
|
|
122
|
+
<path d="M808 374q26 0 30 24-20 6-32-8Z" fill="#3b63d6" />
|
|
123
|
+
<g className="dca-fx-swing" style={{ transformOrigin: '788px 372px' }}>
|
|
124
|
+
<path d="M762 348 740 358 762 368Z" fill="#f6b500" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
|
|
125
|
+
<S d="M758 358a21 21 0 1 1 42 0a21 21 0 1 1-42 0Z" fill="#4f7cf6" stroke={12} />
|
|
126
|
+
<circle cx="772" cy="354" r="5" fill="#2b2f3a" />
|
|
127
|
+
</g>
|
|
128
|
+
</g>
|
|
129
|
+
case 'amulet': return <>
|
|
130
|
+
<path d="M404 792q108 36 216 0" stroke="#fff" strokeWidth="24" strokeLinecap="round" fill="none" />
|
|
131
|
+
<path d="M404 792q108 36 216 0" stroke="#3c4658" strokeWidth="10" strokeLinecap="round" fill="none" />
|
|
132
|
+
<Glow blur={14} className="dca-fx-pulse"><path d={crystal} fill="#5eead4" stroke="#5eead4" strokeWidth="18" opacity=".9" /></Glow>
|
|
133
|
+
<S d={crystal} fill="#5eead4" stroke={12} />
|
|
134
|
+
<path d="M512 814c12 14 26 28 26 40a26 26 0 0 1-26 26Z" fill="#2cc5b0" />
|
|
135
|
+
<circle cx="512" cy="812" r="8" fill="#efc65c" stroke="#fff" strokeWidth="8" paintOrder="stroke fill" />
|
|
136
|
+
<Detail><path d="M500 842q-7 10-3 22" stroke="#ccfbf1" strokeWidth="7" strokeLinecap="round" fill="none" /></Detail>
|
|
137
|
+
</>
|
|
20
138
|
default: return null
|
|
21
139
|
}
|
|
22
140
|
}
|
|
@@ -27,6 +145,15 @@ function useGlowFilter() {
|
|
|
27
145
|
const id = `dca-mask-glow-${useId().replace(/:/g, '')}`
|
|
28
146
|
return { id, defs: <defs><filter id={id} x="-30%" y="-60%" width="160%" height="220%"><feGaussianBlur stdDeviation="14" /></filter></defs> }
|
|
29
147
|
}
|
|
148
|
+
function useScanSweep(eyes: string, x: number, y: number, height: number) {
|
|
149
|
+
const clip = useClipId()
|
|
150
|
+
return {
|
|
151
|
+
defs: <defs><clipPath id={clip}><path d={eyes} /></clipPath></defs>,
|
|
152
|
+
sweep: <g className="dca-part-face dca-part-face-operator" data-mask-face="operator-scan" clipPath={`url(#${clip})`}>
|
|
153
|
+
<g className="dca-fx dca-fx-scan-eyes"><rect x={x} y={y} width="10" height={height} fill="#fff" opacity=".95" /><rect x={x - 8} y={y} width="26" height={height} fill="#fff" opacity=".35" /></g>
|
|
154
|
+
</g>,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
30
157
|
function Light({ name, filter, glow, core, glowOpacity = .85, coreOpacity = 1, effect = 'dca-fx-pulse', children }: {
|
|
31
158
|
name: string; filter: string; glow: string; core: string; glowOpacity?: number; coreOpacity?: number; effect?: string; children: ReactNode
|
|
32
159
|
}) {
|
|
@@ -39,17 +166,15 @@ function Light({ name, filter, glow, core, glowOpacity = .85, coreOpacity = 1, e
|
|
|
39
166
|
const goldSlits = 'M364 592 458 578 462 630 368 646ZM660 592 566 578 562 630 656 646Z'
|
|
40
167
|
function GoldEyes() {
|
|
41
168
|
const glow = useGlowFilter()
|
|
42
|
-
const
|
|
169
|
+
const scan = useScanSweep(goldSlits, 360, 570, 84)
|
|
43
170
|
return <>
|
|
44
171
|
{glow.defs}
|
|
45
|
-
|
|
172
|
+
{scan.defs}
|
|
46
173
|
<path d={goldSlits} fill="#2b2010" />
|
|
47
174
|
<Light name="neutral" filter={glow.id} glow="#6fdcff" core="#dff7ff" coreOpacity={.92}><path d={goldSlits} /><path d="M376 612h76M572 612h76" fill="none" stroke="#fff" strokeWidth="8" strokeLinecap="round" /></Light>
|
|
48
175
|
<Light name="happy" filter={glow.id} glow="#ffd970" core="#fff6d6" glowOpacity={1} effect="dca-fx-flare"><path d={goldSlits} /><path d="M372 612h84M568 612h84" fill="none" stroke="#fff" strokeWidth="14" strokeLinecap="round" /></Light>
|
|
49
176
|
<Light name="operator" filter={glow.id} glow="#ffb547" core="#ffd9a0" glowOpacity={.7} effect="dca-fx-none"><path d={goldSlits} /></Light>
|
|
50
|
-
|
|
51
|
-
<g className="dca-fx dca-fx-scan-eyes"><rect x="360" y="570" width="10" height="84" fill="#fff" opacity=".95" /><rect x="352" y="570" width="26" height="84" fill="#fff" opacity=".35" /></g>
|
|
52
|
-
</g>
|
|
177
|
+
{scan.sweep}
|
|
53
178
|
<Light name="sleep" filter={glow.id} glow="#6fdcff" core="#6fdcff" glowOpacity={.3} coreOpacity={.28} effect="dca-fx-breathe"><path d={goldSlits} /></Light>
|
|
54
179
|
</>
|
|
55
180
|
}
|
|
@@ -67,6 +192,77 @@ function NeonEyes() {
|
|
|
67
192
|
</>
|
|
68
193
|
}
|
|
69
194
|
|
|
195
|
+
const dragonEyes = 'M362 586Q414 548 466 628Q406 640 362 586ZM662 586Q610 548 558 628Q618 640 662 586Z'
|
|
196
|
+
const dragonIris = `${dragonEyes}M414 580q16 20 0 40q-16-20 0-40ZM610 580q16 20 0 40q-16-20 0-40Z`
|
|
197
|
+
function DragonEyes() {
|
|
198
|
+
const glow = useGlowFilter()
|
|
199
|
+
const scan = useScanSweep(dragonEyes, 356, 560, 80)
|
|
200
|
+
const iris = <path d={dragonIris} fillRule="evenodd" />
|
|
201
|
+
return <>
|
|
202
|
+
{glow.defs}
|
|
203
|
+
{scan.defs}
|
|
204
|
+
<path d={dragonEyes} fill="#140d09" />
|
|
205
|
+
<Light name="neutral" filter={glow.id} glow="#ffb547" core="#ffc766" effect="dca-fx-none">{iris}</Light>
|
|
206
|
+
<Light name="happy" filter={glow.id} glow="#ffd970" core="#fff0b3" glowOpacity={1} effect="dca-fx-flare">{iris}</Light>
|
|
207
|
+
<Light name="operator" filter={glow.id} glow="#ff5a1f" core="#ff8a3d" glowOpacity={.75} effect="dca-fx-none">{iris}</Light>
|
|
208
|
+
{scan.sweep}
|
|
209
|
+
<Light name="sleep" filter={glow.id} glow="#ff6a2a" core="#ff6a2a" glowOpacity={.3} coreOpacity={.28} effect="dca-fx-breathe">{iris}</Light>
|
|
210
|
+
</>
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const knightEyes = 'M384 602h80v30h-80ZM560 602h80v30h-80Z'
|
|
214
|
+
function KnightEyes() {
|
|
215
|
+
const glow = useGlowFilter()
|
|
216
|
+
const scan = useScanSweep(knightEyes, 376, 598, 38)
|
|
217
|
+
return <>
|
|
218
|
+
{glow.defs}
|
|
219
|
+
{scan.defs}
|
|
220
|
+
<Light name="neutral" filter={glow.id} glow="#ffb547" core="#ffd9a0"><path d={knightEyes} /><path d="M394 617h60M570 617h60" fill="none" stroke="#fff6d6" strokeWidth="8" strokeLinecap="round" /></Light>
|
|
221
|
+
<Light name="happy" filter={glow.id} glow="#ffd970" core="#fff6d6" glowOpacity={1} effect="dca-fx-flare"><path d={knightEyes} /><path d="M390 617h68M566 617h68" fill="none" stroke="#fff" strokeWidth="12" strokeLinecap="round" /></Light>
|
|
222
|
+
<Light name="operator" filter={glow.id} glow="#ff6a2a" core="#ff8a3d" glowOpacity={.7} effect="dca-fx-none"><path d={knightEyes} /></Light>
|
|
223
|
+
{scan.sweep}
|
|
224
|
+
<Light name="sleep" filter={glow.id} glow="#ff6a2a" core="#ff6a2a" glowOpacity={.3} coreOpacity={.28} effect="dca-fx-breathe"><path d={knightEyes} /></Light>
|
|
225
|
+
</>
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const segmentEnds: Record<string, readonly [number, number, number, number]> = {
|
|
229
|
+
a: [0, 0, 1, 0], b: [1, 0, 1, 1], c: [1, 1, 1, 2], d: [0, 2, 1, 2], e: [0, 1, 0, 2], f: [0, 0, 0, 1], g: [0, 1, 1, 1],
|
|
230
|
+
}
|
|
231
|
+
function segments(lit: string) {
|
|
232
|
+
return [398, 566].flatMap(x => [...lit].map(key => {
|
|
233
|
+
const [c0, r0, c1, r1] = segmentEnds[key]
|
|
234
|
+
const [x0, y0, x1, y1] = [x + c0 * 60, 556 + r0 * 60, x + c1 * 60, 556 + r1 * 60]
|
|
235
|
+
return y0 === y1 ? `M${x0 + 3} ${y0}l11-11H${x1 - 14}l11 11-11 11H${x0 + 14}Z` : `M${x0} ${y0 + 3}l11 11V${y1 - 14}l-11 11-11-11V${y0 + 14}Z`
|
|
236
|
+
})).join('')
|
|
237
|
+
}
|
|
238
|
+
const colon = 'M505 579h14v14h-14ZM505 639h14v14h-14Z'
|
|
239
|
+
function SegmentEyes() {
|
|
240
|
+
const layer = (name: string, lit: string, extra?: ReactNode, opacity?: number) => <g className={`dca-part-face dca-part-face-${name}`} data-mask-face={name} fill="#2f3a2b">
|
|
241
|
+
<path className="dca-part-eyes" d={segments(lit)} opacity={opacity} />{extra}
|
|
242
|
+
</g>
|
|
243
|
+
return <>
|
|
244
|
+
<path d={segments('abcdefg') + colon} fill="#2f3a2b" opacity=".1" />
|
|
245
|
+
{layer('neutral', 'abcdef')}
|
|
246
|
+
{layer('happy', 'abf')}
|
|
247
|
+
{layer('operator', 'g', <path className="dca-fx dca-fx-node" d={colon} />)}
|
|
248
|
+
{layer('sleep', 'd', <path className="dca-fx dca-fx-breathe" d={segments('d')} opacity=".35" />, .35)}
|
|
249
|
+
</>
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function PortholeGlass() {
|
|
253
|
+
const clip = useClipId()
|
|
254
|
+
return <>
|
|
255
|
+
<defs><clipPath id={clip}><circle cx="512" cy="622" r="104" /></clipPath></defs>
|
|
256
|
+
<circle cx="512" cy="622" r="128" fill="#e3a06b" />
|
|
257
|
+
<circle cx="512" cy="622" r="104" fill="#1f4a5a" />
|
|
258
|
+
<g clipPath={`url(#${clip})`} fill="#c7f6ff">
|
|
259
|
+
<circle className="dca-fx dca-fx-steam" cx="566" cy="556" r="12" />
|
|
260
|
+
<circle className="dca-fx dca-fx-steam" cx="456" cy="688" r="9" style={{ animationDelay: '-.9s' }} />
|
|
261
|
+
<circle className="dca-fx dca-fx-steam" cx="584" cy="690" r="14" style={{ animationDelay: '-1.7s' }} />
|
|
262
|
+
</g>
|
|
263
|
+
</>
|
|
264
|
+
}
|
|
265
|
+
|
|
70
266
|
function Plate({ fill, children }: { fill: string; children?: ReactNode }) {
|
|
71
267
|
const clip = useClipId()
|
|
72
268
|
return <>
|
|
@@ -80,20 +276,48 @@ const topLight = (fill: string, opacity: number) => <path d="M307 544v-68h410v68
|
|
|
80
276
|
const mechaEyes = 'M356 604 448 614 452 648 362 636ZM668 604 576 614 572 648 662 636Z'
|
|
81
277
|
function MechaEyes() {
|
|
82
278
|
const glow = useGlowFilter()
|
|
83
|
-
const
|
|
279
|
+
const scan = useScanSweep(mechaEyes, 352, 596, 60)
|
|
84
280
|
return <>
|
|
85
281
|
{glow.defs}
|
|
86
|
-
|
|
282
|
+
{scan.defs}
|
|
87
283
|
<Light name="neutral" filter={glow.id} glow="#d9ff5a" core="#f6ffb0"><path d={mechaEyes} /></Light>
|
|
88
284
|
<Light name="happy" filter={glow.id} glow="#f6ffb0" core="#ffffff" glowOpacity={1} effect="dca-fx-flare"><path d={mechaEyes} /></Light>
|
|
89
285
|
<Light name="operator" filter={glow.id} glow="#ffb547" core="#ffd9a0" glowOpacity={.75} effect="dca-fx-none"><path d={mechaEyes} /></Light>
|
|
90
|
-
|
|
91
|
-
<g className="dca-fx dca-fx-scan-eyes"><rect x="352" y="596" width="10" height="60" fill="#fff" opacity=".95" /><rect x="344" y="596" width="26" height="60" fill="#fff" opacity=".35" /></g>
|
|
92
|
-
</g>
|
|
286
|
+
{scan.sweep}
|
|
93
287
|
<Light name="sleep" filter={glow.id} glow="#d9ff5a" core="#d9ff5a" glowOpacity={.25} coreOpacity={.3} effect="dca-fx-breathe"><path d={mechaEyes} /></Light>
|
|
94
288
|
</>
|
|
95
289
|
}
|
|
96
290
|
|
|
291
|
+
function codeRain() {
|
|
292
|
+
const glyphs: string[] = [], heads: string[] = []
|
|
293
|
+
for (let column = 0; column < 13; column++) {
|
|
294
|
+
const x = 318 + column * 32
|
|
295
|
+
for (const [start, length] of [[column * 197 % 560, 3 + column * 5 % 5], [(column * 197 + 290) % 560, 2 + column * 3 % 4]]) {
|
|
296
|
+
for (let row = 0; row < length; row++) {
|
|
297
|
+
const width = (row + column) % 3 ? 14 : 8, y = (start + row * 24) % 560
|
|
298
|
+
// Each glyph repeats one scanline travel (560) apart, so the looping fall never shows a seam.
|
|
299
|
+
for (const top of [y - 84, y + 476]) (row === length - 1 ? heads : glyphs).push(`M${x + (14 - width) / 2} ${top}h${width}v16h-${width}Z`)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return { glyphs: glyphs.join(''), heads: heads.join('') }
|
|
304
|
+
}
|
|
305
|
+
const rain = codeRain()
|
|
306
|
+
const rainSockets = 'M390 596a28 28 0 0 1 28-28h24a28 28 0 0 1 28 28v44a28 28 0 0 1-28 28h-24a28 28 0 0 1-28-28ZM554 596a28 28 0 0 1 28-28h24a28 28 0 0 1 28 28v44a28 28 0 0 1-28 28h-24a28 28 0 0 1-28-28Z'
|
|
307
|
+
function CodeRainEyes() {
|
|
308
|
+
const glow = useGlowFilter()
|
|
309
|
+
return <>
|
|
310
|
+
{glow.defs}
|
|
311
|
+
<path d={rainSockets} fill="#020805" stroke="#1c3a26" strokeWidth="4" />
|
|
312
|
+
<Light name="neutral" filter={glow.id} glow="#7dff8a" core="#d9ffe0"><rect x="398" y="576" width="64" height="84" rx="22" /><rect x="562" y="576" width="64" height="84" rx="22" /></Light>
|
|
313
|
+
<Light name="happy" filter={glow.id} glow="#7dff8a" core="#f0fff2" glowOpacity={1} effect="dca-fx-flare">
|
|
314
|
+
<path d="M398 598a22 22 0 0 1 22-22h20a22 22 0 0 1 22 22v36q-32-22-64 0Z" /><path d="M562 598a22 22 0 0 1 22-22h20a22 22 0 0 1 22 22v36q-32-22-64 0Z" />
|
|
315
|
+
</Light>
|
|
316
|
+
<Light name="operator" filter={glow.id} glow="#7dff8a" core="#d9ffe0" glowOpacity={.75} effect="dca-fx-none"><rect x="398" y="614" width="64" height="46" rx="12" /><rect x="562" y="614" width="64" height="46" rx="12" /></Light>
|
|
317
|
+
<Light name="sleep" filter={glow.id} glow="#7dff8a" core="#7dff8a" glowOpacity={.3} coreOpacity={.4} effect="dca-fx-breathe"><rect x="398" y="648" width="64" height="10" rx="5" /><rect x="562" y="648" width="64" height="10" rx="5" /></Light>
|
|
318
|
+
</>
|
|
319
|
+
}
|
|
320
|
+
|
|
97
321
|
function PixelEyes() {
|
|
98
322
|
const glow = useGlowFilter()
|
|
99
323
|
const block = (x: number, y: number, w = 48, h = 48) => <rect key={`${x}-${y}`} x={x} y={y} width={w} height={h} />
|
|
@@ -125,6 +349,20 @@ export function FaceplatePlate({ id }: { id: FaceId }) {
|
|
|
125
349
|
<rect x="348" y="476" width="10" height="291" fill="#4de3ff" opacity=".45" />
|
|
126
350
|
</g>
|
|
127
351
|
</Plate></g>
|
|
352
|
+
case 'segment-display': return <g data-faceplate={id}><Plate fill="#b7c49a">{topLight('#c8d4ad', .8)}</Plate></g>
|
|
353
|
+
case 'knight-visor': return <g data-faceplate={id}><Plate fill="#a7b1c0">
|
|
354
|
+
{topLight('#c3cad6', .8)}
|
|
355
|
+
<path d="M344 604q0-8 8-8h320q8 0 8 8v26q0 8-8 8H530v92q0 8-8 8h-20q-8 0-8-8v-92H352q-8 0-8-8Z" fill="#1d2433" />
|
|
356
|
+
</Plate></g>
|
|
357
|
+
case 'porthole-helmet': return <g data-faceplate={id}><Plate fill="#c47a4a">{topLight('#d9925f', .8)}<PortholeGlass /></Plate></g>
|
|
358
|
+
case 'dragon-visor': return <g data-faceplate={id}><Plate fill="#1f2b2c">
|
|
359
|
+
<path d="M307 476h410v58q-41 34-82 0-41 34-82 0-41 34-82 0-41 34-82 0-41 34-82 0Z" fill="#2f4543" />
|
|
360
|
+
<path d="M478 660h68l40 107H438Z" fill="#2f4543" />
|
|
361
|
+
<path d="M476 718q14-14 32-6-10 16-32 6ZM548 718q-14-14-32-6 10 16 32 6Z" fill="#0f1616" />
|
|
362
|
+
</Plate></g>
|
|
363
|
+
case 'code-rain': return <g data-faceplate={id}><Plate fill="#0b1410">
|
|
364
|
+
<g className="dca-fx dca-fx-scanline" opacity=".35"><path d={rain.glyphs} fill="#7dff8a" /><path d={rain.heads} fill="#d9ffe0" /></g>
|
|
365
|
+
</Plate></g>
|
|
128
366
|
default: return null
|
|
129
367
|
}
|
|
130
368
|
}
|
|
@@ -135,6 +373,11 @@ export function FaceplateEyes({ id }: { id: FaceId }) {
|
|
|
135
373
|
case 'pixel-screen': return <PixelEyes />
|
|
136
374
|
case 'gold-faceplate': return <GoldEyes />
|
|
137
375
|
case 'neon-visor': return <NeonEyes />
|
|
376
|
+
case 'segment-display': return <SegmentEyes />
|
|
377
|
+
case 'knight-visor': return <KnightEyes />
|
|
378
|
+
case 'porthole-helmet': return <g transform="translate(512 622) scale(.75) translate(-512 -618)"><NeonEyes /></g>
|
|
379
|
+
case 'dragon-visor': return <DragonEyes />
|
|
380
|
+
case 'code-rain': return <CodeRainEyes />
|
|
138
381
|
default: return null
|
|
139
382
|
}
|
|
140
383
|
}
|
package/src/HandDecorations.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HandId } from './items.js'
|
|
2
|
-
import { Glow } from './DecorationShapes.js'
|
|
2
|
+
import { Glow, Plane, useClipId } from './DecorationShapes.js'
|
|
3
3
|
|
|
4
4
|
const mark = 'var(--dca-held-mark, #3161f7)'
|
|
5
5
|
const accent = 'var(--dca-held-accent, #f6b500)'
|
|
@@ -71,6 +71,18 @@ export function HandDecoration({ id }: { id: HandId }) {
|
|
|
71
71
|
<rect x="777" y="712" width="46" height="18" rx="6" fill="#8b95a5" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
72
72
|
<rect x="783" y="726" width="34" height="90" rx="12" fill="#2a3140" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
73
73
|
</g>}
|
|
74
|
+
{id === 'thunder-hammer' && <g transform="translate(233 640) rotate(-12) scale(.86) translate(-800 -700)">
|
|
75
|
+
<Glow blur={16} className="dca-fx-pulse"><rect x="708" y="456" width="184" height="120" rx="28" fill="#4de3ff" opacity=".55" /></Glow>
|
|
76
|
+
<rect x="787" y="556" width="26" height="186" rx="12" fill="#3c4658" stroke="#fff" strokeWidth="16" paintOrder="stroke fill" />
|
|
77
|
+
<rect x="778" y="734" width="44" height="28" rx="10" fill="#8b95a5" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
78
|
+
<rect x="715" y="466" width="170" height="100" rx="20" fill="#aab4c3" stroke="#fff" strokeWidth="18" paintOrder="stroke fill" />
|
|
79
|
+
<path d="M735 466h14v100h-14q-20 0-20-20v-60q0-20 20-20ZM865 466h-14v100h14q20 0 20-20v-60q0-20-20-20Z" fill="#737e90" />
|
|
80
|
+
<rect x="777" y="466" width="46" height="100" fill={mark} />
|
|
81
|
+
{['M740 458l-24-26 26-8-18-40', 'M860 458l18-28-26-6 26-36', 'M712 510l-22 2 12 14-14 10'].map((d, index) =>
|
|
82
|
+
<g key={d} className="dca-fx dca-fx-node" fill="none" strokeLinejoin="miter" style={index ? { animationDelay: `${index * .6}s` } : undefined}>
|
|
83
|
+
<path d={d} stroke="#4de3ff" strokeWidth="20" /><path d={d} stroke="#f2feff" strokeWidth="8" />
|
|
84
|
+
</g>)}
|
|
85
|
+
</g>}
|
|
74
86
|
{id === 'paintbrush' && <g transform="translate(233 640) rotate(-25) translate(-800 -720)">
|
|
75
87
|
<rect x="788" y="660" width="24" height="180" rx="12" fill="#e0ad84" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
76
88
|
<rect x="780" y="626" width="40" height="40" rx="6" fill="#8b95a5" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
@@ -109,5 +121,215 @@ export function HandDecoration({ id }: { id: HandId }) {
|
|
|
109
121
|
<circle className="dca-fx-orb-color" cx="800" cy="544" r="34" fill="#8b5cf6" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
110
122
|
<circle cx="788" cy="532" r="10" fill="#fff" opacity=".85" />
|
|
111
123
|
</g>}
|
|
124
|
+
{id === 'umbrella' && <g transform="translate(233 640) rotate(-14) scale(.85) translate(-800 -708)">
|
|
125
|
+
<path d="M800 366V770a22 22 0 0 1-44 0" stroke="#fff" strokeWidth="36" />
|
|
126
|
+
<path d="M800 366V770a22 22 0 0 1-44 0" stroke="#3c4658" strokeWidth="16" />
|
|
127
|
+
<path d="M695 490c0-64 47-104 105-104s105 40 105 104a35 22 0 0 0-70 0a35 22 0 0 0-70 0a35 22 0 0 0-70 0Z" fill="#e8654f" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
128
|
+
<path d="M800 386c-20 22-34 60-35 104a35 22 0 0 1 70 0c-1-44-15-82-35-104Z" fill="#b94f50" />
|
|
129
|
+
</g>}
|
|
130
|
+
{id === 'pizza-slice' && <g transform="translate(233 640) rotate(-10) scale(.9) translate(-800 -707)">
|
|
131
|
+
<g fill="#fff" stroke="#fff" strokeWidth="28"><path d="M800 500 876 700H724Z" /><rect x="714" y="688" width="172" height="38" rx="19" /></g>
|
|
132
|
+
<path d="M800 500 876 700H724Z" fill="#f3cf62" />
|
|
133
|
+
<rect x="714" y="688" width="172" height="38" rx="19" fill="#e0ad84" />
|
|
134
|
+
<g fill="#e8654f"><circle cx="800" cy="578" r="17" /><circle cx="774" cy="650" r="17" /><circle cx="826" cy="640" r="17" /></g>
|
|
135
|
+
</g>}
|
|
136
|
+
{id === 'sunflower' && <g transform="translate(233 640) rotate(-12) translate(-800 -780)">
|
|
137
|
+
<rect x="792" y="600" width="16" height="240" rx="8" fill="#89b875" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
138
|
+
<path d="M792 716c-14-34-44-48-74-40 8 32 38 50 74 40Z" fill="#89b875" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
139
|
+
<path d="M800 531a13 13 0 1 1 22 6a13 13 0 1 1 16 16a13 13 0 1 1 6 22a13 13 0 1 1-6 22a13 13 0 1 1-16 16a13 13 0 1 1-22 6a13 13 0 1 1-22-6a13 13 0 1 1-16-16a13 13 0 1 1-6-22a13 13 0 1 1 6-22a13 13 0 1 1 16-16a13 13 0 1 1 22-6Z" fill="#f6b500" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
140
|
+
<circle cx="800" cy="575" r="26" fill="#805840" />
|
|
141
|
+
</g>}
|
|
142
|
+
{id === 'camera' && <g transform="translate(233 640) scale(1.05) translate(-800 -695)">
|
|
143
|
+
<g fill="#fff" stroke="#fff" strokeWidth="30"><rect x="740" y="624" width="56" height="36" rx="12" /><rect x="838" y="630" width="30" height="24" rx="8" /><rect x="720" y="646" width="160" height="104" rx="28" /></g>
|
|
144
|
+
<rect x="740" y="624" width="56" height="36" rx="12" fill="#fff" stroke={mark} strokeWidth="11" />
|
|
145
|
+
<rect x="838" y="630" width="30" height="24" rx="8" fill={accent} />
|
|
146
|
+
<rect x="720" y="646" width="160" height="104" rx="28" fill="#fff" stroke={mark} strokeWidth="11" />
|
|
147
|
+
<circle cx="812" cy="700" r="36" fill="#fff" stroke={mark} strokeWidth="18" />
|
|
148
|
+
<circle cx="812" cy="700" r="12" fill={mark} />
|
|
149
|
+
</g>}
|
|
150
|
+
{id === 'binoculars' && <g transform="translate(233 640) scale(.95) translate(-800 -700)">
|
|
151
|
+
<g fill="#fff" stroke="#fff" strokeWidth="28"><rect x="743" y="598" width="36" height="40" rx="10" /><rect x="821" y="598" width="36" height="40" rx="10" /><rect x="728" y="626" width="144" height="128" rx="24" /></g>
|
|
152
|
+
<rect x="784" y="648" width="32" height="44" rx="8" fill="#3c4658" />
|
|
153
|
+
<g fill="#3c4658"><rect x="743" y="598" width="36" height="40" rx="10" /><rect x="821" y="598" width="36" height="40" rx="10" /></g>
|
|
154
|
+
<g fill="#537f59"><rect x="728" y="626" width="64" height="128" rx="24" /><rect x="808" y="626" width="64" height="128" rx="24" /></g>
|
|
155
|
+
<g fill="#a2c5d1"><circle cx="760" cy="716" r="22" /><circle cx="840" cy="716" r="22" /></g>
|
|
156
|
+
</g>}
|
|
157
|
+
{id === 'goldfish-bag' && <g transform="translate(233 640) rotate(6) scale(1.1) translate(-800 -644)">
|
|
158
|
+
<path d="M800 648 782 606h36Z" fill="#a2c5d1" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
159
|
+
<path d="M792 642h16c4 22 54 30 54 84 0 30-28 46-62 46s-62-16-62-46c0-54 50-62 54-84Z" fill="#a2c5d1" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
160
|
+
<path d="M792 642h16c3 17 32 25 46 51H746c14-26 43-34 46-51Z" fill="#c7f6ff" />
|
|
161
|
+
<path d="M764 730c0-11 13-18 29-18 12 0 22 6 27 13l20-14v38l-20-14c-5 7-15 13-27 13-16 0-29-7-29-18Z" fill="#ed985f" />
|
|
162
|
+
</g>}
|
|
163
|
+
{id === 'megaphone' && <g transform="translate(233 640) rotate(-26) translate(-800 -700)">
|
|
164
|
+
<path d="M818 618l26 30" stroke="#fff" strokeWidth="44" />
|
|
165
|
+
<path d="M818 618l26 30" stroke={mark} strokeWidth="22" />
|
|
166
|
+
<path d="M784 664 740 520h120l-44 144Z" fill="#fff" stroke="#fff" strokeWidth="30" />
|
|
167
|
+
<path d="M784 664 740 520h120l-44 144Z" fill="#fff" stroke={mark} strokeWidth="11" />
|
|
168
|
+
<path d="M761 590h78l-7 24h-64Z" fill={mark} />
|
|
169
|
+
<ellipse cx="800" cy="520" rx="60" ry="18" fill="#fff" stroke={mark} strokeWidth="16" />
|
|
170
|
+
<rect x="782" y="660" width="36" height="30" rx="8" fill={accent} stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
171
|
+
</g>}
|
|
172
|
+
{id === 'parrot' && <g transform="translate(233 640) translate(-800 -640)">
|
|
173
|
+
<path d="M780 610 764 740h36l16-126Z" fill="#4fae6a" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
174
|
+
<path d="M802 510c32 0 48 28 48 64 0 42-22 70-52 70-28 0-44-26-44-62 0-42 18-72 48-72Z" fill="#4fae6a" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
175
|
+
<g className="dca-fx-swing" style={{ transformOrigin: '800px 516px' }}>
|
|
176
|
+
<path d="M824 474c16-2 28 10 28 26-2 6-6 8-10 4-2-8-8-12-18-12Z" fill="#f6b500" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
177
|
+
<circle cx="802" cy="490" r="30" fill="#e8654f" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
178
|
+
<circle cx="812" cy="484" r="6" fill="#202124" />
|
|
179
|
+
</g>
|
|
180
|
+
</g>}
|
|
181
|
+
{id === 'firefly-jar' && <g transform="translate(233 640) scale(1.12) translate(-800 -705)">
|
|
182
|
+
<rect x="744" y="646" width="112" height="120" rx="26" fill="#c7f6ff" fillOpacity=".6" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
183
|
+
<rect x="752" y="626" width="96" height="28" rx="8" fill="#8b95a5" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
184
|
+
<Glow blur={10} className="dca-fx-pulse"><g fill="#d9ff5a"><circle cx="776" cy="702" r="24" /><circle cx="826" cy="684" r="24" /><circle cx="808" cy="738" r="24" /></g></Glow>
|
|
185
|
+
<g fill="#d9ff5a">
|
|
186
|
+
<circle className="dca-fx dca-fx-node" cx="776" cy="702" r="13" /><circle className="dca-fx dca-fx-node" cx="826" cy="684" r="13" style={{ animationDelay: '.6s' }} /><circle className="dca-fx dca-fx-node" cx="808" cy="738" r="13" style={{ animationDelay: '1.2s' }} />
|
|
187
|
+
</g>
|
|
188
|
+
</g>}
|
|
189
|
+
{id === 'trophy' && <g transform="translate(233 640) rotate(-6) scale(.8) translate(-800 -706)">
|
|
190
|
+
<Glow blur={16} className="dca-fx-pulse"><path d="M750 540h100v30c0 44-22 72-50 72s-50-28-50-72Z" fill="#ffd970" opacity=".85" /></Glow>
|
|
191
|
+
<path d="M752 562c-34-4-40 50 4 56M848 562c34-4 40 50-4 56" stroke="#fff" strokeWidth="36" />
|
|
192
|
+
<path d="M752 562c-34-4-40 50 4 56M848 562c34-4 40 50-4 56" stroke="#c99139" strokeWidth="14" />
|
|
193
|
+
<rect x="788" y="632" width="24" height="48" fill="#c99139" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
194
|
+
<path d="M750 540h100v30c0 44-22 72-50 72s-50-28-50-72Z" fill="#efc65c" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
195
|
+
<rect x="754" y="676" width="92" height="34" rx="8" fill="#3c4658" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
196
|
+
<g className="dca-fx dca-fx-sparkle" fill="#fff3c4">
|
|
197
|
+
<path d="M742 508l5 12 12 5-12 5-5 12-5-12-12-5 12-5Z" />
|
|
198
|
+
<path d="M864 520l4 10 10 4-10 4-4 10-4-10-10-4 10-4Z" style={{ animationDelay: '.6s' }} />
|
|
199
|
+
<path d="M806 490l4 9 9 4-9 4-4 9-4-9-9-4 9-4Z" style={{ animationDelay: '1.1s' }} />
|
|
200
|
+
</g>
|
|
201
|
+
</g>}
|
|
202
|
+
{id === 'walkie-talkie' && <g transform="translate(233 640) scale(1.05) translate(-800 -695)">
|
|
203
|
+
<g fill="#fff" stroke="#fff" strokeWidth="30"><rect x="814" y="572" width="26" height="72" rx="13" /><rect x="760" y="600" width="28" height="28" rx="8" /><rect x="752" y="624" width="96" height="164" rx="26" /></g>
|
|
204
|
+
<rect x="814" y="572" width="26" height="72" rx="13" fill="#3c4658" />
|
|
205
|
+
<rect x="760" y="600" width="28" height="28" rx="8" fill={accent} />
|
|
206
|
+
<rect x="752" y="624" width="96" height="164" rx="26" fill="#fff" stroke={mark} strokeWidth="11" />
|
|
207
|
+
<rect x="772" y="648" width="56" height="66" rx="12" fill={mark} />
|
|
208
|
+
<path d="M786 666h28M786 681h28M786 696h28" stroke="#fff" strokeWidth="7" />
|
|
209
|
+
<circle cx="800" cy="748" r="13" fill={mark} />
|
|
210
|
+
</g>}
|
|
211
|
+
{id === 'potion' && <g transform="translate(233 640) scale(1.1) translate(-800 -640)">
|
|
212
|
+
<g fill="#fff" stroke="#fff" strokeWidth="26"><rect x="780" y="578" width="40" height="34" rx="10" /><rect x="784" y="606" width="32" height="52" rx="6" /><circle cx="800" cy="690" r="52" /></g>
|
|
213
|
+
<rect x="784" y="606" width="32" height="52" rx="6" fill="#f4f8ff" stroke="#a9b8cc" strokeWidth="8" />
|
|
214
|
+
<circle cx="800" cy="690" r="52" fill="#f4f8ff" stroke="#a9b8cc" strokeWidth="8" />
|
|
215
|
+
<path d="M756.7 682A44 44 0 1 0 843.3 682Z" fill="#e05aa8" />
|
|
216
|
+
<g fill="#f7b8d9"><circle cx="786" cy="712" r="6" /><circle cx="816" cy="698" r="4" /></g>
|
|
217
|
+
<path d="M766 670c4-10 12-18 22-22" stroke="#fff" strokeWidth="9" />
|
|
218
|
+
<rect x="780" y="578" width="40" height="34" rx="10" fill="#c49b5e" />
|
|
219
|
+
</g>}
|
|
220
|
+
{id === 'genie-lamp' && <g transform="translate(233 650) scale(1.12) translate(-800 -650)">
|
|
221
|
+
<path d="M804 640c30-20 56 0 50 22-4 18-26 22-48 12" stroke="#fff" strokeWidth="38" />
|
|
222
|
+
<path d="M804 640c30-20 56 0 50 22-4 18-26 22-48 12" stroke="#c99139" strokeWidth="16" />
|
|
223
|
+
<g fill="#efc65c" stroke="#fff" strokeWidth="14" paintOrder="stroke fill">
|
|
224
|
+
<path d="M743 686h32l9 16h-50Z" />
|
|
225
|
+
<path d="M718 648C706 648 698 638 692 620l-14 8c6 24 20 42 44 50Z" />
|
|
226
|
+
<ellipse cx="759" cy="656" rx="50" ry="32" />
|
|
227
|
+
<path d="M731 632c2-18 12-30 28-30s26 12 28 30Z" />
|
|
228
|
+
<circle cx="759" cy="592" r="10" />
|
|
229
|
+
</g>
|
|
230
|
+
<path d="M711 662q48 20 96 0" stroke="#c99139" strokeWidth="9" />
|
|
231
|
+
<path d="M733 640q26-8 52 0" stroke="#fff3c4" strokeWidth="7" />
|
|
232
|
+
</g>}
|
|
233
|
+
{id === 'lollipop' && <g transform="translate(233 640) rotate(-6) translate(-800 -800)">
|
|
234
|
+
<rect x="791" y="640" width="18" height="240" rx="9" fill="#fff" stroke="#fff" strokeWidth="26" />
|
|
235
|
+
<rect x="791" y="640" width="18" height="240" rx="9" fill="#fff" stroke="#c9d1dd" strokeWidth="5" />
|
|
236
|
+
<circle cx="800" cy="639" r="80" fill="#f2a0b4" stroke="#fff" strokeWidth="16" paintOrder="stroke fill" />
|
|
237
|
+
<path d="M800 639a10 10 0 0 1 20 0a20 20 0 0 1-40 0a30 30 0 0 1 60 0a40 40 0 0 1-80 0a50 50 0 0 1 100 0a60 60 0 0 1-120 0" stroke="#e8654f" strokeWidth="15" />
|
|
238
|
+
<path d="M752 596c10-12 24-20 40-22" stroke="#fff" strokeWidth="10" opacity=".8" />
|
|
239
|
+
</g>}
|
|
240
|
+
{id === 'pickaxe' && <g transform="translate(233 640) rotate(-12) scale(.85) translate(-800 -800)">
|
|
241
|
+
<rect x="789" y="548" width="22" height="318" rx="11" fill="#e0ad84" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
242
|
+
<rect x="786" y="796" width="28" height="60" rx="8" fill="#f6b500" />
|
|
243
|
+
<path d="M696 600C712 540 754 506 800 506S888 540 904 600C874 574 838 562 800 562S726 574 696 600Z" fill="#8b95a5" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
244
|
+
<path d="M726 562c20-24 46-38 74-38s54 14 74 38" stroke="#c3cad6" strokeWidth="9" />
|
|
245
|
+
<rect x="778" y="504" width="44" height="62" rx="10" fill="#5d6778" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
246
|
+
</g>}
|
|
247
|
+
{id === 'bug-net' && <g transform="translate(233 640) translate(-800 -640)">
|
|
248
|
+
<path d="M836 432 791 690" stroke="#fff" strokeWidth="34" />
|
|
249
|
+
<path d="M836 432 791 690" stroke={mark} strokeWidth="18" />
|
|
250
|
+
<path d="M697 440C694 500 716 552 750 562S812 540 826 500C832 482 836 460 838 424Z" fill="#fff" fillOpacity=".9" stroke="#fff" strokeWidth="14" strokeLinejoin="round" />
|
|
251
|
+
<path d="M720 446C722 500 736 540 750 556M752 440C754 500 754 540 752 560M784 438C784 500 774 540 758 558M812 434C810 490 792 530 766 556M704 482Q765 502 832 472M714 522Q760 538 818 514" stroke="#b9c2d1" strokeWidth="4" />
|
|
252
|
+
<g className="dca-fx-swing" style={{ transformOrigin: '760px 518px' }}>
|
|
253
|
+
<path d="M752 492c-4-10-12-14-20-12M768 492c4-10 12-14 20-12M742 512h-16M742 528h-16M778 512h16M778 528h16" stroke="#2b2f3a" strokeWidth="6" />
|
|
254
|
+
<circle cx="760" cy="498" r="11" fill="#2b2f3a" />
|
|
255
|
+
<ellipse cx="760" cy="522" rx="20" ry="24" fill="#2b2f3a" />
|
|
256
|
+
<path d="M760 502v44" stroke="#5b6577" strokeWidth="4" />
|
|
257
|
+
<ellipse cx="752" cy="514" rx="4" ry="7" fill="#fff" opacity=".7" />
|
|
258
|
+
</g>
|
|
259
|
+
<ellipse cx="767" cy="432" rx="72" ry="30" transform="rotate(-8 767 432)" stroke="#fff" strokeWidth="32" />
|
|
260
|
+
<ellipse cx="767" cy="432" rx="72" ry="30" transform="rotate(-8 767 432)" stroke={mark} strokeWidth="14" />
|
|
261
|
+
</g>}
|
|
262
|
+
{id === 'hot-pepper' && <g transform="translate(233 640) scale(1.1) translate(-800 -640)">
|
|
263
|
+
<Glow blur={12} className="dca-fx-pulse"><ellipse cx="744" cy="452" rx="34" ry="44" fill="#ffb347" opacity=".8" /></Glow>
|
|
264
|
+
<g className="dca-fx dca-fx-flame" style={{ transformOrigin: '742px 488px' }}>
|
|
265
|
+
<path d="M742 488C712 476 706 446 722 420c4 14 12 20 20 20-4-22 6-40 24-50-4 24 10 38 12 58 2 22-14 36-36 40Z" fill="#ffb347" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
266
|
+
<path d="M744 480c-14-6-18-22-10-36 4 8 10 10 14 10 0-12 4-22 12-28-2 14 6 24 6 36s-8 20-22 18Z" fill="#ffe08a" />
|
|
267
|
+
</g>
|
|
268
|
+
<path d="M808 656c4 16 14 26 30 28" stroke="#fff" strokeWidth="28" />
|
|
269
|
+
<path d="M808 656c4 16 14 26 30 28" stroke="#3f8f4f" strokeWidth="12" />
|
|
270
|
+
<path d="M762 640C742 604 732 566 736 530c2-20 0-32-6-44-4-8 4-14 12-8 22 14 40 44 52 72 14 32 34 54 46 80Z" fill="#e8654f" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
271
|
+
<path d="M776 612c-12-24-20-50-22-80" stroke="#fff" strokeWidth="9" opacity=".55" />
|
|
272
|
+
<path d="M756 648c-2-18 16-30 44-30s48 12 46 30c-14 12-76 12-90 0Z" fill="#4fae6a" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
|
|
273
|
+
</g>}
|
|
274
|
+
{id === 'plasma-globe' && <g transform="translate(233 640) translate(-800 -640)">
|
|
275
|
+
<path d="M756 684h88l-10-62h-68Z" fill="#1d2433" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
276
|
+
<rect x="772" y="602" width="56" height="22" rx="6" fill="#3c4658" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
277
|
+
<circle cx="800" cy="540" r="70" fill="#34245c" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
278
|
+
<Glow blur={14} className="dca-fx-pulse"><circle cx="800" cy="540" r="40" fill="#c084fc" opacity=".8" /></Glow>
|
|
279
|
+
{['M800 540l-14-22 12-8-18-26', 'M800 540l24-10 2-16 24-8', 'M800 540l-26 6 4 14-28 8', 'M800 540l14 22 16-4 10 22'].map((d, index) =>
|
|
280
|
+
<g key={d} className="dca-fx dca-fx-node" fill="none" style={index ? { animationDelay: `${index * .45}s` } : undefined}>
|
|
281
|
+
<path d={d} stroke="#c084fc" strokeWidth="12" /><path d={d} stroke="#f5d0fe" strokeWidth="5" />
|
|
282
|
+
</g>)}
|
|
283
|
+
<circle cx="800" cy="540" r="15" fill="#f5d0fe" />
|
|
284
|
+
<path d="M752 508c8-16 22-28 40-32" stroke="#fff" strokeWidth="9" opacity=".7" />
|
|
285
|
+
</g>}
|
|
286
|
+
{id === 'master-key' && <MasterKey />}
|
|
287
|
+
{id === 'pet-dragon' && <PetDragon />}
|
|
288
|
+
</g>
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function MasterKey() {
|
|
292
|
+
const clip = useClipId()
|
|
293
|
+
const shape = 'M728 422H818V712H782V508H728V486H746V470H728V452H750V436H728Z'
|
|
294
|
+
const bow = 'M800 718a54 54 0 1 1 0 108 54 54 0 1 1 0-108Zm0 34a20 20 0 1 0 0 40 20 20 0 1 0 0-40Z'
|
|
295
|
+
return <g transform="translate(233 640) rotate(-12) scale(.9) translate(-800 -760)">
|
|
296
|
+
<defs><clipPath id={clip}><path d={shape} /><path d={bow} /></clipPath></defs>
|
|
297
|
+
<Glow blur={16} className="dca-fx-pulse"><path d="M772 410h56v326h-56ZM716 412h70v108h-70Z" fill="#ffd970" opacity=".8" /></Glow>
|
|
298
|
+
<path d={shape} fill="#efc65c" stroke="#fff" strokeWidth="16" strokeLinejoin="round" paintOrder="stroke fill" />
|
|
299
|
+
<path d={bow} fill="#efc65c" fillRule="evenodd" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
|
|
300
|
+
<path d="M812 432v270" stroke="#c99139" strokeWidth="7" />
|
|
301
|
+
<rect x="774" y="700" width="52" height="26" rx="8" fill="#c99139" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
|
|
302
|
+
<g clipPath={`url(#${clip})`}><g transform="translate(800 740) rotate(-90) scale(.45 1)"><g className="dca-fx dca-fx-sheen" fill="#fff3c4"><path d="M3-80h67l-73 160h-67Z" opacity=".9" /></g></g></g>
|
|
303
|
+
</g>
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const dragonWing = 'M0 0C-10-60-50-110-100-128Q-84-104-92-80Q-72-86-60-66Q-40-66-30-40Q-14-30 0 0Z'
|
|
307
|
+
const dragonFarWing = 'M0 0C-4-60-20-110-42-138Q-40-112-54-92Q-40-88-34-66Q-22-62-18-40Q-8-26 0 0Z'
|
|
308
|
+
// One outline for tail, body and head: the head overlaps the body so no contour cuts across the neck.
|
|
309
|
+
const petDragonBody = [
|
|
310
|
+
'M824 604C852 636 852 688 820 710c-10 6-18-2-10-10 22-20 22-50 2-78Z',
|
|
311
|
+
'M806 532c34 0 48 34 46 64-2 34-24 54-50 54s-40-20-38-54c2-30 14-64 42-64Z',
|
|
312
|
+
'M826 512c0-22-16-38-38-38-18 0-32 8-40 20-10 4-18 10-18 20 0 10 10 16 24 16 14 10 30 14 46 12 16-4 26-14 26-30Z',
|
|
313
|
+
]
|
|
314
|
+
function PetDragon() {
|
|
315
|
+
return <g transform="translate(233 640) translate(-800 -640)">
|
|
316
|
+
{[{ at: 'translate(790 552)', d: dragonWing }, { at: 'translate(814 552) scale(-1 1)', d: dragonFarWing }].map(wing =>
|
|
317
|
+
<g key={wing.at} transform={wing.at}><g className="dca-fx-flap-slow" style={{ transformOrigin: '0px 0px' }}>
|
|
318
|
+
<path d={wing.d} fill="#2f7a4f" stroke="#fff" strokeWidth="12" strokeLinejoin="round" paintOrder="stroke fill" />
|
|
319
|
+
</g></g>)}
|
|
320
|
+
<path d="M812 486 840 446 826 490ZM796 482 806 438 786 482Z" fill="#e0ad84" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
|
|
321
|
+
<Plane d={petDragonBody} fill="#4fae6a" contour={14} />
|
|
322
|
+
<path d="M812 700l-26 6 18 18Z" fill="#2f7a4f" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
|
|
323
|
+
<ellipse cx="786" cy="600" rx="16" ry="34" fill="#f6e3a1" />
|
|
324
|
+
<path d="M788 644v14M812 646v14" stroke="#fff" strokeWidth="22" />
|
|
325
|
+
<path d="M788 644v14M812 646v14" stroke="#2f7a4f" strokeWidth="10" />
|
|
326
|
+
<circle cx="794" cy="502" r="7" fill="#202124" />
|
|
327
|
+
<g transform="translate(728 518) rotate(-80)">
|
|
328
|
+
<Glow blur={10} className="dca-fx-pulse"><ellipse cy="-30" rx="18" ry="32" fill="#ffb347" opacity=".75" /></Glow>
|
|
329
|
+
<g className="dca-fx dca-fx-flame" style={{ transformOrigin: '0px 0px' }}>
|
|
330
|
+
<path d="M0 0C-16-6-22-24-14-40c2 10 8 14 14 14-4-14 2-28 12-36-4 16 6 26 6 40S10 0 0 0Z" fill="#ffb347" stroke="#fff" strokeWidth="8" paintOrder="stroke fill" />
|
|
331
|
+
<path d="M1-8c-8-4-10-14-6-20 2 4 6 6 8 6 0-8 2-14 6-18 0 10 4 16 4 22s-4 12-12 10Z" fill="#ffe08a" />
|
|
332
|
+
</g>
|
|
333
|
+
</g>
|
|
112
334
|
</g>
|
|
113
335
|
}
|
package/src/HatDecorations.tsx
CHANGED
|
@@ -97,6 +97,14 @@ export function HatDecoration({ id }: { id: HeadId }) {
|
|
|
97
97
|
<path d="M312 392c56-22 344-22 400 0-64 36-336 36-400 0Z" fill="#3c4658" />
|
|
98
98
|
<circle cx="512" cy="300" r="28" fill="#fff" /><circle cx="501" cy="296" r="5" fill="#2b2f3a" /><circle cx="523" cy="296" r="5" fill="#2b2f3a" />
|
|
99
99
|
</>
|
|
100
|
+
case 'viking-helmet': return <>
|
|
101
|
+
<S d="M396 344C330 344 300 290 330 150C352 222 372 262 410 280ZM628 344C694 344 724 290 694 150C672 222 652 262 614 280Z" fill="#f6e6c6" />
|
|
102
|
+
<path d="M330 150C352 222 372 262 410 280L402 300C360 282 336 240 330 150ZM694 150C672 222 652 262 614 280L622 300C664 282 688 240 694 150Z" fill="#dcc08a" />
|
|
103
|
+
<S d="M376 344c0-96 58-156 136-156s136 60 136 156Z" fill="#a7b1c0" />
|
|
104
|
+
<path d="M540 190c70 12 108 72 108 154h-46c0-72-20-124-62-154Z" fill="#8b95a5" />
|
|
105
|
+
<rect x="360" y="336" width="304" height="66" rx="20" fill="#c49b5e" />
|
|
106
|
+
<Detail><path d="M406 316c4-44 24-76 52-92" stroke="#d3dae4" strokeWidth="14" strokeLinecap="round" /></Detail>
|
|
107
|
+
</>
|
|
100
108
|
default: return null
|
|
101
109
|
}
|
|
102
110
|
}
|