@mumulinya167/ccm-pet-assets 2.0.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/README.md +4 -0
- package/assets/calico/calico-collapsing.apng +0 -0
- package/assets/calico/calico-dozing.apng +0 -0
- package/assets/calico/calico-error.apng +0 -0
- package/assets/calico/calico-happy.apng +0 -0
- package/assets/calico/calico-idle-follow.svg +324 -0
- package/assets/calico/calico-idle.apng +0 -0
- package/assets/calico/calico-mini-alert.apng +0 -0
- package/assets/calico/calico-mini-crabwalk.apng +0 -0
- package/assets/calico/calico-mini-enter.apng +0 -0
- package/assets/calico/calico-mini-happy.apng +0 -0
- package/assets/calico/calico-mini-idle.apng +0 -0
- package/assets/calico/calico-mini-peek.apng +0 -0
- package/assets/calico/calico-mini-sleep.apng +0 -0
- package/assets/calico/calico-notification.apng +0 -0
- package/assets/calico/calico-react-drag.apng +0 -0
- package/assets/calico/calico-react-left.apng +0 -0
- package/assets/calico/calico-react-poke.apng +0 -0
- package/assets/calico/calico-sleeping.apng +0 -0
- package/assets/calico/calico-thinking.apng +0 -0
- package/assets/calico/calico-waking.apng +0 -0
- package/assets/calico/calico-working-building.apng +0 -0
- package/assets/calico/calico-working-carrying.apng +0 -0
- package/assets/calico/calico-working-conducting.apng +0 -0
- package/assets/calico/calico-working-juggling.apng +0 -0
- package/assets/calico/calico-working-sweeping.apng +0 -0
- package/assets/calico/calico-working-typing.apng +0 -0
- package/assets/calico/calico-yawning.apng +0 -0
- package/assets/calico.svg +324 -0
- package/assets/clawd/LICENSE +22 -0
- package/assets/clawd/clawd-about-hero.svg +202 -0
- package/assets/clawd/clawd-collapse-sleep.svg +247 -0
- package/assets/clawd/clawd-error.svg +94 -0
- package/assets/clawd/clawd-happy.svg +161 -0
- package/assets/clawd/clawd-headphones-groove.svg +194 -0
- package/assets/clawd/clawd-idle-bubble.svg +180 -0
- package/assets/clawd/clawd-idle-collapse.svg +101 -0
- package/assets/clawd/clawd-idle-doze.svg +72 -0
- package/assets/clawd/clawd-idle-follow.svg +64 -0
- package/assets/clawd/clawd-idle-living.svg +196 -0
- package/assets/clawd/clawd-idle-look.svg +115 -0
- package/assets/clawd/clawd-idle-reading.svg +252 -0
- package/assets/clawd/clawd-idle-yawn.svg +158 -0
- package/assets/clawd/clawd-mini-alert.svg +129 -0
- package/assets/clawd/clawd-mini-crabwalk.svg +76 -0
- package/assets/clawd/clawd-mini-enter-sleep.svg +64 -0
- package/assets/clawd/clawd-mini-enter.svg +114 -0
- package/assets/clawd/clawd-mini-happy.svg +124 -0
- package/assets/clawd/clawd-mini-idle.svg +83 -0
- package/assets/clawd/clawd-mini-peek.svg +82 -0
- package/assets/clawd/clawd-mini-sleep.svg +112 -0
- package/assets/clawd/clawd-mini-typing.svg +153 -0
- package/assets/clawd/clawd-notification.svg +438 -0
- package/assets/clawd/clawd-react-annoyed.svg +167 -0
- package/assets/clawd/clawd-react-double-jump.svg +229 -0
- package/assets/clawd/clawd-react-double.svg +108 -0
- package/assets/clawd/clawd-react-drag.svg +102 -0
- package/assets/clawd/clawd-react-left.svg +102 -0
- package/assets/clawd/clawd-react-right.svg +102 -0
- package/assets/clawd/clawd-sleeping.svg +118 -0
- package/assets/clawd/clawd-static-base.svg +21 -0
- package/assets/clawd/clawd-wake.svg +277 -0
- package/assets/clawd/clawd-working-building.svg +329 -0
- package/assets/clawd/clawd-working-carrying.svg +178 -0
- package/assets/clawd/clawd-working-debugger.svg +245 -0
- package/assets/clawd/clawd-working-juggling.svg +183 -0
- package/assets/clawd/clawd-working-sweeping.svg +248 -0
- package/assets/clawd/clawd-working-thinking.svg +501 -0
- package/assets/clawd/clawd-working-typing-boss.svg +307 -0
- package/assets/clawd/clawd-working-typing.svg +273 -0
- package/assets/clawd/clawd-working-ultrathink.svg +166 -0
- package/assets/clawd/clawd-working-wizard.svg +356 -0
- package/assets/clawd.svg +64 -0
- package/assets/cloudling/cloudling/cloudling-attention.svg +380 -0
- package/assets/cloudling/cloudling/cloudling-building.svg +667 -0
- package/assets/cloudling/cloudling/cloudling-carrying.svg +604 -0
- package/assets/cloudling/cloudling/cloudling-conducting.svg +616 -0
- package/assets/cloudling/cloudling/cloudling-dozing-to-sleeping.svg +578 -0
- package/assets/cloudling/cloudling/cloudling-dozing.svg +358 -0
- package/assets/cloudling/cloudling/cloudling-error.svg +428 -0
- package/assets/cloudling/cloudling/cloudling-idle-reading.svg +658 -0
- package/assets/cloudling/cloudling/cloudling-idle-to-dozing.svg +568 -0
- package/assets/cloudling/cloudling/cloudling-idle-to-sleeping.svg +811 -0
- package/assets/cloudling/cloudling/cloudling-idle.svg +255 -0
- package/assets/cloudling/cloudling/cloudling-juggling.svg +648 -0
- package/assets/cloudling/cloudling/cloudling-mini-alert.svg +390 -0
- package/assets/cloudling/cloudling/cloudling-mini-crabwalk.svg +335 -0
- package/assets/cloudling/cloudling/cloudling-mini-enter-roll-in.svg +226 -0
- package/assets/cloudling/cloudling/cloudling-mini-enter-sleep.svg +232 -0
- package/assets/cloudling/cloudling/cloudling-mini-happy.svg +371 -0
- package/assets/cloudling/cloudling/cloudling-mini-idle.svg +279 -0
- package/assets/cloudling/cloudling/cloudling-mini-peek.svg +328 -0
- package/assets/cloudling/cloudling/cloudling-mini-sleep.svg +260 -0
- package/assets/cloudling/cloudling/cloudling-mini-typing.svg +692 -0
- package/assets/cloudling/cloudling/cloudling-notification.svg +494 -0
- package/assets/cloudling/cloudling/cloudling-react-drag.svg +83 -0
- package/assets/cloudling/cloudling/cloudling-sleeping-to-idle.svg +555 -0
- package/assets/cloudling/cloudling/cloudling-sleeping.svg +500 -0
- package/assets/cloudling/cloudling/cloudling-sweeping.svg +292 -0
- package/assets/cloudling/cloudling/cloudling-thinking.svg +720 -0
- package/assets/cloudling/cloudling/cloudling-typing.svg +354 -0
- package/assets/cloudling/cloudling-attention.svg +380 -0
- package/assets/cloudling/cloudling-building.svg +667 -0
- package/assets/cloudling/cloudling-carrying.svg +604 -0
- package/assets/cloudling/cloudling-conducting.svg +616 -0
- package/assets/cloudling/cloudling-dozing-to-sleeping.svg +578 -0
- package/assets/cloudling/cloudling-dozing.svg +358 -0
- package/assets/cloudling/cloudling-error.svg +428 -0
- package/assets/cloudling/cloudling-idle-reading.svg +658 -0
- package/assets/cloudling/cloudling-idle-to-dozing.svg +568 -0
- package/assets/cloudling/cloudling-idle-to-sleeping.svg +811 -0
- package/assets/cloudling/cloudling-idle.svg +255 -0
- package/assets/cloudling/cloudling-juggling.svg +648 -0
- package/assets/cloudling/cloudling-mini-alert.svg +390 -0
- package/assets/cloudling/cloudling-mini-crabwalk.svg +335 -0
- package/assets/cloudling/cloudling-mini-enter-roll-in.svg +226 -0
- package/assets/cloudling/cloudling-mini-enter-sleep.svg +232 -0
- package/assets/cloudling/cloudling-mini-happy.svg +371 -0
- package/assets/cloudling/cloudling-mini-idle.svg +279 -0
- package/assets/cloudling/cloudling-mini-peek.svg +328 -0
- package/assets/cloudling/cloudling-mini-sleep.svg +260 -0
- package/assets/cloudling/cloudling-mini-typing.svg +692 -0
- package/assets/cloudling/cloudling-notification.svg +494 -0
- package/assets/cloudling/cloudling-react-drag.svg +83 -0
- package/assets/cloudling/cloudling-sleeping-to-idle.svg +555 -0
- package/assets/cloudling/cloudling-sleeping.svg +500 -0
- package/assets/cloudling/cloudling-sweeping.svg +292 -0
- package/assets/cloudling/cloudling-thinking.svg +720 -0
- package/assets/cloudling/cloudling-typing.svg +354 -0
- package/assets/cloudling.svg +255 -0
- package/assets/ghost-attention.svg +19 -0
- package/assets/ghost-carrying.svg +19 -0
- package/assets/ghost-collapsing.svg +19 -0
- package/assets/ghost-dozing.svg +23 -0
- package/assets/ghost-error.svg +19 -0
- package/assets/ghost-happy.svg +23 -0
- package/assets/ghost-idle-action1.svg +19 -0
- package/assets/ghost-idle-action2.svg +19 -0
- package/assets/ghost-idle-action3.svg +19 -0
- package/assets/ghost-idle.svg +11 -0
- package/assets/ghost-juggling.svg +19 -0
- package/assets/ghost-notification.svg +19 -0
- package/assets/ghost-react-double.svg +23 -0
- package/assets/ghost-react-drag.svg +23 -0
- package/assets/ghost-react-left.svg +19 -0
- package/assets/ghost-react-right.svg +19 -0
- package/assets/ghost-sleeping.svg +19 -0
- package/assets/ghost-sweeping.svg +19 -0
- package/assets/ghost-thinking.svg +19 -0
- package/assets/ghost-waking.svg +19 -0
- package/assets/ghost-working.svg +19 -0
- package/assets/ghost-yawning.svg +23 -0
- package/assets/ghost.svg +11 -0
- package/assets/robot-attention.svg +19 -0
- package/assets/robot-carrying.svg +19 -0
- package/assets/robot-collapsing.svg +19 -0
- package/assets/robot-dozing.svg +23 -0
- package/assets/robot-error.svg +19 -0
- package/assets/robot-happy.svg +23 -0
- package/assets/robot-idle-action1.svg +19 -0
- package/assets/robot-idle-action2.svg +19 -0
- package/assets/robot-idle-action3.svg +19 -0
- package/assets/robot-idle.svg +11 -0
- package/assets/robot-juggling.svg +19 -0
- package/assets/robot-notification.svg +19 -0
- package/assets/robot-react-double.svg +23 -0
- package/assets/robot-react-drag.svg +23 -0
- package/assets/robot-react-left.svg +19 -0
- package/assets/robot-react-right.svg +19 -0
- package/assets/robot-sleeping.svg +19 -0
- package/assets/robot-sweeping.svg +19 -0
- package/assets/robot-thinking.svg +19 -0
- package/assets/robot-waking.svg +19 -0
- package/assets/robot-working.svg +19 -0
- package/assets/robot-yawning.svg +23 -0
- package/assets/robot.svg +11 -0
- package/manifest.json +889 -0
- package/package.json +18 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 36 36" preserveAspectRatio="xMidYMid meet">
|
|
2
|
+
<style><![CDATA[
|
|
3
|
+
.edge-rim-tight { stroke-opacity: .9; }
|
|
4
|
+
.edge-rim-soft { stroke-opacity: .75; }
|
|
5
|
+
.edge-contact { stroke-opacity: .9; }
|
|
6
|
+
.statusbar, .preset {
|
|
7
|
+
font-size: 10px;
|
|
8
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
9
|
+
color: #9fb2ff;
|
|
10
|
+
background: #151824;
|
|
11
|
+
border-radius: 8px;
|
|
12
|
+
padding: 6px 14px;
|
|
13
|
+
min-width: min(820px, calc(100vw - 40px));
|
|
14
|
+
text-align: center;
|
|
15
|
+
letter-spacing: 0.03em;
|
|
16
|
+
}
|
|
17
|
+
.preset {
|
|
18
|
+
color: rgba(224,224,230,.70);
|
|
19
|
+
text-align: left;
|
|
20
|
+
white-space: pre-wrap;
|
|
21
|
+
line-height: 1.45;
|
|
22
|
+
}
|
|
23
|
+
@media (prefers-color-scheme: light) {
|
|
24
|
+
.edge-rim-tight { stroke-opacity: .95; }
|
|
25
|
+
.edge-rim-soft { stroke-opacity: .85; }
|
|
26
|
+
.edge-contact { stroke-opacity: .95; }
|
|
27
|
+
.cloud-drop-shadow { flood-opacity: .13; }
|
|
28
|
+
.statusbar, .preset { background: #fff; color: #3941FF; }
|
|
29
|
+
.food-cloud-shadow { flood-opacity: .28; flood-color: #5060FF; }
|
|
30
|
+
.food-cloud > path {
|
|
31
|
+
stroke: #5870E8 !important;
|
|
32
|
+
stroke-width: 1.2 !important;
|
|
33
|
+
stroke-opacity: .9 !important;
|
|
34
|
+
vector-effect: non-scaling-stroke !important;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
]]></style>
|
|
38
|
+
<defs>
|
|
39
|
+
<path id="cloud-shape" d="M9.064 3.344a4.578 4.578 0 012.285-.312c1 .115 1.891.54 2.673 1.275.01.01.024.017.037.021a.09.09 0 00.043 0 4.55 4.55 0 013.046.275l.047.022.116.057a4.581 4.581 0 012.188 2.399c.209.51.313 1.041.315 1.595a4.24 4.24 0 01-.134 1.223.123.123 0 00.03.115c.594.607.988 1.33 1.183 2.17.289 1.425-.007 2.71-.887 3.854l-.136.166a4.548 4.548 0 01-2.201 1.388.123.123 0 00-.081.076c-.191.551-.383 1.023-.74 1.494-.9 1.187-2.222 1.846-3.711 1.838-1.187-.006-2.239-.44-3.157-1.302a.107.107 0 00-.105-.024c-.388.125-.78.143-1.204.138a4.441 4.441 0 01-1.945-.466 4.544 4.544 0 01-1.61-1.335c-.152-.202-.303-.392-.414-.617a5.81 5.81 0 01-.37-.961 4.582 4.582 0 01-.014-2.298.124.124 0 00.006-.056.085.085 0 00-.027-.048 4.467 4.467 0 01-1.034-1.651 3.896 3.896 0 01-.251-1.192 5.189 5.189 0 01.141-1.6c.337-1.112.982-1.985 1.933-2.618.212-.141.413-.251.601-.33.215-.089.43-.164.646-.227a.098.098 0 00.065-.066 4.51 4.51 0 01.829-1.615 4.535 4.535 0 011.837-1.388z"/>
|
|
40
|
+
<clipPath id="cloud-clip"><use href="#cloud-shape"/></clipPath>
|
|
41
|
+
|
|
42
|
+
<linearGradient id="body-grad" x1="12" y1="1.5" x2="12" y2="22.8" gradientUnits="userSpaceOnUse">
|
|
43
|
+
<stop id="body-top" offset="0" stop-color="#6A708E"/>
|
|
44
|
+
<stop id="body-mid" offset=".44" stop-color="#333A53"/>
|
|
45
|
+
<stop id="body-bottom" offset="1" stop-color="#151A30"/>
|
|
46
|
+
</linearGradient>
|
|
47
|
+
<radialGradient id="body-hi" cx="9.2" cy="5.2" r="18" gradientUnits="userSpaceOnUse">
|
|
48
|
+
<stop offset="0" stop-color="#8B92B2" stop-opacity=".16"/>
|
|
49
|
+
<stop offset=".62" stop-color="#6C7394" stop-opacity=".08"/>
|
|
50
|
+
<stop offset="1" stop-color="#6C7394" stop-opacity="0"/>
|
|
51
|
+
</radialGradient>
|
|
52
|
+
<radialGradient id="body-core" cx="12.2" cy="17.5" r="11.8" gradientUnits="userSpaceOnUse">
|
|
53
|
+
<stop id="core-stop-a" offset="0" stop-color="#0C1023" stop-opacity=".22"/>
|
|
54
|
+
<stop id="core-stop-b" offset=".68" stop-color="#0C1023" stop-opacity=".09"/>
|
|
55
|
+
<stop offset="1" stop-color="#0C1023" stop-opacity="0"/>
|
|
56
|
+
</radialGradient>
|
|
57
|
+
|
|
58
|
+
<radialGradient id="flow-cool" cx="0.5" cy="0.5" r="0.65">
|
|
59
|
+
<stop offset="0" stop-color="#858DAE" stop-opacity=".26"/>
|
|
60
|
+
<stop offset=".52" stop-color="#697290" stop-opacity=".13"/>
|
|
61
|
+
<stop offset="1" stop-color="#697290" stop-opacity="0"/>
|
|
62
|
+
</radialGradient>
|
|
63
|
+
<radialGradient id="flow-deep" cx="0.5" cy="0.5" r="0.60">
|
|
64
|
+
<stop offset="0" stop-color="#020514" stop-opacity=".56"/>
|
|
65
|
+
<stop offset=".58" stop-color="#020514" stop-opacity=".18"/>
|
|
66
|
+
<stop offset="1" stop-color="#020514" stop-opacity="0"/>
|
|
67
|
+
</radialGradient>
|
|
68
|
+
<linearGradient id="flow-band-grad" x1="1" y1="0" x2="23" y2="0" gradientUnits="userSpaceOnUse">
|
|
69
|
+
<stop offset="0" stop-color="#747D9E" stop-opacity="0"/>
|
|
70
|
+
<stop offset=".45" stop-color="#747D9E" stop-opacity=".16"/>
|
|
71
|
+
<stop offset="1" stop-color="#747D9E" stop-opacity="0"/>
|
|
72
|
+
</linearGradient>
|
|
73
|
+
|
|
74
|
+
<linearGradient id="eye-grad" x1="12" y1="8.5" x2="12" y2="15.8" gradientUnits="userSpaceOnUse">
|
|
75
|
+
<stop offset="0" stop-color="#A9BCFF"/>
|
|
76
|
+
<stop offset=".54" stop-color="#6B89FF"/>
|
|
77
|
+
<stop offset="1" stop-color="#3941FF"/>
|
|
78
|
+
</linearGradient>
|
|
79
|
+
|
|
80
|
+
<filter id="cloud-shadow" x="-75%" y="-75%" width="250%" height="250%">
|
|
81
|
+
<feDropShadow id="hard-shadow" dx="0" dy=".8" stdDeviation="1.15" flood-color="#040611" flood-opacity=".70"/>
|
|
82
|
+
<feDropShadow id="blue-glow" dx="0" dy="0" stdDeviation="2.1" flood-color="#3941FF" flood-opacity=".18"/>
|
|
83
|
+
</filter>
|
|
84
|
+
<filter id="mist-blur" x="-30%" y="-30%" width="160%" height="160%">
|
|
85
|
+
<feGaussianBlur id="mist-blur-node" stdDeviation=".34"/>
|
|
86
|
+
</filter>
|
|
87
|
+
<filter id="ground-blur" x="-50%" y="-80%" width="200%" height="260%">
|
|
88
|
+
<feGaussianBlur stdDeviation="1"/>
|
|
89
|
+
</filter>
|
|
90
|
+
</defs>
|
|
91
|
+
|
|
92
|
+
<g id="rain" display="none" stroke="#7180C2" stroke-width=".45" stroke-linecap="round"></g>
|
|
93
|
+
<ellipse id="ground" cx="12" cy="22.9" rx="8.7" ry="1.25" fill="#030513" opacity=".48" filter="url(#ground-blur)"/>
|
|
94
|
+
|
|
95
|
+
<g id="cloud-root">
|
|
96
|
+
<g filter="url(#cloud-shadow)">
|
|
97
|
+
<use href="#cloud-shape" fill="url(#body-grad)" stroke="#9CA8D8" stroke-opacity=".22" stroke-width=".34"/>
|
|
98
|
+
<rect x="-3" y="-3" width="30" height="30" fill="url(#body-hi)" clip-path="url(#cloud-clip)"/>
|
|
99
|
+
<rect x="-3" y="-3" width="30" height="30" fill="url(#body-core)" clip-path="url(#cloud-clip)"/>
|
|
100
|
+
<g id="flow-layer" clip-path="url(#cloud-clip)" filter="url(#mist-blur)">
|
|
101
|
+
<ellipse id="flow-light" cx="8.5" cy="7.0" rx="14.8" ry="8.4" fill="url(#flow-cool)" opacity=".34"/>
|
|
102
|
+
<ellipse id="flow-dark" cx="15.6" cy="17.4" rx="13.6" ry="7.8" fill="url(#flow-deep)" opacity=".30"/>
|
|
103
|
+
<rect id="flow-band" x="-10" y="2.0" width="44" height="9.4" fill="url(#flow-band-grad)" opacity=".26" transform="rotate(-12 12 12)"/>
|
|
104
|
+
</g>
|
|
105
|
+
</g>
|
|
106
|
+
|
|
107
|
+
<g id="eyes" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
108
|
+
<g id="eye-l" transform="translate(8.95 12.2) rotate(-5)">
|
|
109
|
+
<path d="M-1.15 -1.35 L1.15 1.35 M1.15 -1.35 L-1.15 1.35" stroke="#FFFFFF" stroke-width="1.42" stroke-opacity=".18"/>
|
|
110
|
+
<path d="M-1.15 -1.35 L1.15 1.35 M1.15 -1.35 L-1.15 1.35" stroke="url(#eye-grad)" stroke-width="1.08"/>
|
|
111
|
+
</g>
|
|
112
|
+
<g id="eye-r" transform="translate(15.05 12.25) rotate(6)">
|
|
113
|
+
<path d="M-1.15 -1.35 L1.15 1.35 M1.15 -1.35 L-1.15 1.35" stroke="#FFFFFF" stroke-width="1.42" stroke-opacity=".18"/>
|
|
114
|
+
<path d="M-1.15 -1.35 L1.15 1.35 M1.15 -1.35 L-1.15 1.35" stroke="url(#eye-grad)" stroke-width="1.08"/>
|
|
115
|
+
</g>
|
|
116
|
+
</g>
|
|
117
|
+
</g>
|
|
118
|
+
<g id="__cloudling-export-shims" opacity="0" pointer-events="none" style="display:none">
|
|
119
|
+
<g id="params"></g>
|
|
120
|
+
<g id="preset"></g>
|
|
121
|
+
<g id="statusbar"></g>
|
|
122
|
+
</g>
|
|
123
|
+
|
|
124
|
+
<script type="application/ecmascript"><![CDATA[
|
|
125
|
+
const TAU = Math.PI * 2;
|
|
126
|
+
const DEFAULTS = {
|
|
127
|
+
period: 4.0,
|
|
128
|
+
breathAmp: 0.070,
|
|
129
|
+
breathSpeed: 1.00,
|
|
130
|
+
squeezeStart: 0.53,
|
|
131
|
+
squeezeDuration: 0.66,
|
|
132
|
+
squeezeRamp: 0.60,
|
|
133
|
+
squeezePower: 0.95,
|
|
134
|
+
reboundOvershoot: 0.018,
|
|
135
|
+
reboundDamping: 0.78,
|
|
136
|
+
squashAmp: 0.088,
|
|
137
|
+
squashXBoost: 0.058,
|
|
138
|
+
squeezeDropY: 0.30,
|
|
139
|
+
rainDelay: 0.05,
|
|
140
|
+
rainDuration: 0.66,
|
|
141
|
+
rainBurstPower: 1.00,
|
|
142
|
+
flowAlpha: 0.56,
|
|
143
|
+
flowTravel: 4.1,
|
|
144
|
+
flowSpeed: 1.25,
|
|
145
|
+
flowBlur: 0.50,
|
|
146
|
+
darkFlowAlpha: 0.48,
|
|
147
|
+
bandAlpha: 0.28,
|
|
148
|
+
twistFlowBoost: 0.55,
|
|
149
|
+
rainBaseOpacity: 0.58,
|
|
150
|
+
rainBurstOpacity: 0.34,
|
|
151
|
+
rainBaseSpeed: 0.62,
|
|
152
|
+
rainBurstSpeed: 0.82,
|
|
153
|
+
rainBaseLength: 1.30,
|
|
154
|
+
rainBurstLength: 1.60,
|
|
155
|
+
rainCount: 8,
|
|
156
|
+
rainDrift: 0.40,
|
|
157
|
+
eyeDim: 0.08,
|
|
158
|
+
};
|
|
159
|
+
let P = { ...DEFAULTS };
|
|
160
|
+
let paused = false;
|
|
161
|
+
let pauseStart = 0;
|
|
162
|
+
let pausedTotal = 0;
|
|
163
|
+
const startedAt = performance.now();
|
|
164
|
+
const RAIN_LINES = [
|
|
165
|
+
{ x: 1.8, y: 22.9, len: 1.15, delay: 0.04, alpha: 0.78 },
|
|
166
|
+
{ x: 4.3, y: 24.1, len: 1.00, delay: 0.31, alpha: 0.52 },
|
|
167
|
+
{ x: 6.5, y: 22.9, len: 0.92, delay: 0.62, alpha: 0.42 },
|
|
168
|
+
{ x: 9.1, y: 24.5, len: 0.88, delay: 0.83, alpha: 0.36 },
|
|
169
|
+
{ x: 14.9, y: 23.4, len: 0.92, delay: 0.18, alpha: 0.40 },
|
|
170
|
+
{ x: 17.4, y: 24.4, len: 1.05, delay: 0.49, alpha: 0.54 },
|
|
171
|
+
{ x: 20.0, y: 23.0, len: 1.22, delay: 0.70, alpha: 0.82 },
|
|
172
|
+
{ x: 22.6, y: 24.0, len: 1.00, delay: 0.92, alpha: 0.50 },
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
const PARAM_DEFS = [
|
|
176
|
+
{ group: '循环 / CYCLE' },
|
|
177
|
+
{ key: 'period', label: '总周期 s', min: 3.6, max: 7.0, step: 0.1 },
|
|
178
|
+
{ key: 'squeezeStart', label: '开始拧的位置', min: 0.08, max: 0.70, step: 0.01 },
|
|
179
|
+
{ key: 'squeezeDuration', label: '拧+回弹时长', min: 0.22, max: 0.86, step: 0.01 },
|
|
180
|
+
{ key: 'squeezeRamp', label: '压扁用时占比', min: 0.20, max: 0.70, step: 0.01 },
|
|
181
|
+
{ key: 'squeezePower', label: '压扁曲线硬度', min: 0.6, max: 3.0, step: 0.05 },
|
|
182
|
+
{ group: '云体呼吸 / BODY' },
|
|
183
|
+
{ key: 'breathAmp', label: '呼吸大小幅度', min: 0.00, max: 0.10, step: 0.005 },
|
|
184
|
+
{ key: 'breathSpeed', label: '呼吸速度倍数', min: 0.3, max: 2.0, step: 0.05 },
|
|
185
|
+
{ key: 'squashAmp', label: '拧毛巾压扁幅度', min: 0.00, max: 0.16, step: 0.005 },
|
|
186
|
+
{ key: 'squashXBoost', label: '压扁横向膨胀', min: 0.00, max: 0.12, step: 0.005 },
|
|
187
|
+
{ key: 'squeezeDropY', label: '压扁下沉', min: 0.00, max: 0.90, step: 0.02 },
|
|
188
|
+
{ key: 'reboundOvershoot', label: '回弹过冲', min: 0.00, max: 0.08, step: 0.002 },
|
|
189
|
+
{ key: 'reboundDamping', label: '回弹衰减', min: 0.20, max: 1.20, step: 0.05 },
|
|
190
|
+
{ group: '挤出的雨 / BURST' },
|
|
191
|
+
{ key: 'rainDelay', label: '雨跟拧的错位', min: 0.00, max: 0.14, step: 0.01 },
|
|
192
|
+
{ key: 'rainDuration', label: '雨随拧持续', min: 0.20, max: 0.86, step: 0.01 },
|
|
193
|
+
{ key: 'rainBurstPower', label: '雨峰曲线硬度', min: 0.5, max: 3.0, step: 0.05 },
|
|
194
|
+
{ group: '乌云流动 / FLOW' },
|
|
195
|
+
{ key: 'flowAlpha', label: '浅色漫反射流动', min: 0.00, max: 0.90, step: 0.01 },
|
|
196
|
+
{ key: 'darkFlowAlpha', label: '暗部漫反射流动', min: 0.00, max: 0.90, step: 0.01 },
|
|
197
|
+
{ key: 'bandAlpha', label: '漫反射流带强度', min: 0.00, max: 0.80, step: 0.01 },
|
|
198
|
+
{ key: 'flowTravel', label: '流动位移', min: 0.0, max: 7.0, step: 0.1 },
|
|
199
|
+
{ key: 'flowSpeed', label: '流动速度', min: 0.2, max: 3.0, step: 0.05 },
|
|
200
|
+
{ key: 'flowBlur', label: '流动柔化', min: 0.0, max: 1.0, step: 0.02 },
|
|
201
|
+
{ key: 'twistFlowBoost', label: '拧时流动加速感', min: 0.00, max: 1.20, step: 0.05 },
|
|
202
|
+
{ group: '雨 / RAIN' },
|
|
203
|
+
{ key: 'rainCount', label: '雨线数量', min: 2, max: 8, step: 1 },
|
|
204
|
+
{ key: 'rainBaseOpacity', label: '常态雨透明度', min: 0.05, max: 1.0, step: 0.01 },
|
|
205
|
+
{ key: 'rainBurstOpacity', label: '挤出时增亮', min: 0.00, max: 0.70, step: 0.01 },
|
|
206
|
+
{ key: 'rainBaseSpeed', label: '常态雨速度', min: 0.15, max: 1.5, step: 0.05 },
|
|
207
|
+
{ key: 'rainBurstSpeed', label: '挤出时加速', min: 0.00, max: 1.8, step: 0.05 },
|
|
208
|
+
{ key: 'rainBaseLength', label: '常态雨长度', min: 0.40, max: 2.4, step: 0.05 },
|
|
209
|
+
{ key: 'rainBurstLength', label: '挤出时变长', min: 0.00, max: 2.8, step: 0.05 },
|
|
210
|
+
{ key: 'rainDrift', label: '雨线斜移', min: 0.00, max: 1.2, step: 0.02 },
|
|
211
|
+
{ group: '眼睛 / EYES' },
|
|
212
|
+
{ key: 'eyeDim', label: '拧时眼睛变暗', min: 0.00, max: 0.30, step: 0.01 },
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
const el = {
|
|
216
|
+
cloudRoot: document.getElementById('cloud-root'),
|
|
217
|
+
rain: document.getElementById('rain'),
|
|
218
|
+
bodyGrad: document.getElementById('body-grad'),
|
|
219
|
+
bodyHi: document.getElementById('body-hi'),
|
|
220
|
+
bodyCore: document.getElementById('body-core'),
|
|
221
|
+
coreA: document.getElementById('core-stop-a'),
|
|
222
|
+
coreB: document.getElementById('core-stop-b'),
|
|
223
|
+
eyeGrad: document.getElementById('eye-grad'),
|
|
224
|
+
eyes: document.getElementById('eyes'),
|
|
225
|
+
eyeL: document.getElementById('eye-l'),
|
|
226
|
+
eyeR: document.getElementById('eye-r'),
|
|
227
|
+
flowLight: document.getElementById('flow-light'),
|
|
228
|
+
flowDark: document.getElementById('flow-dark'),
|
|
229
|
+
flowBand: document.getElementById('flow-band'),
|
|
230
|
+
blur: document.getElementById('mist-blur-node'),
|
|
231
|
+
ground: document.getElementById('ground'),
|
|
232
|
+
hardShadow: document.getElementById('hard-shadow'),
|
|
233
|
+
blueGlow: document.getElementById('blue-glow'),
|
|
234
|
+
status: document.getElementById('statusbar'),
|
|
235
|
+
preset: document.getElementById('preset'),
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const RAIN_COPIES = 2;
|
|
239
|
+
const rainPaths = RAIN_LINES.map(() => {
|
|
240
|
+
const copies = [];
|
|
241
|
+
for (let i = 0; i < RAIN_COPIES; i++) {
|
|
242
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
243
|
+
path.setAttribute('fill', 'none');
|
|
244
|
+
el.rain.appendChild(path);
|
|
245
|
+
copies.push(path);
|
|
246
|
+
}
|
|
247
|
+
return copies;
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
function buildParams() {
|
|
251
|
+
const params = document.getElementById('params');
|
|
252
|
+
params.innerHTML = '';
|
|
253
|
+
for (const def of PARAM_DEFS) {
|
|
254
|
+
if (def.group) {
|
|
255
|
+
const h = document.createElement('h3');
|
|
256
|
+
h.textContent = def.group;
|
|
257
|
+
params.appendChild(h);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const lab = document.createElement('label');
|
|
261
|
+
lab.innerHTML = `
|
|
262
|
+
<span>${def.label}</span>
|
|
263
|
+
<input type="range" data-key="${def.key}" min="${def.min}" max="${def.max}" step="${def.step}" value="${P[def.key]}"/>
|
|
264
|
+
<span class="val" data-val="${def.key}">${formatValue(P[def.key], def.step)}</span>
|
|
265
|
+
`;
|
|
266
|
+
const range = lab.querySelector('input');
|
|
267
|
+
const val = lab.querySelector('[data-val]');
|
|
268
|
+
range.oninput = e => {
|
|
269
|
+
P[def.key] = parseFloat(e.target.value);
|
|
270
|
+
if (def.key === 'rainCount') P[def.key] = Math.round(P[def.key]);
|
|
271
|
+
val.textContent = formatValue(P[def.key], def.step);
|
|
272
|
+
updatePreset();
|
|
273
|
+
};
|
|
274
|
+
params.appendChild(lab);
|
|
275
|
+
}
|
|
276
|
+
updatePreset();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function formatValue(v, step) {
|
|
280
|
+
if (Number.isInteger(step)) return String(v);
|
|
281
|
+
if (step >= 0.1) return Number(v).toFixed(1);
|
|
282
|
+
if (step >= 0.01) return Number(v).toFixed(2);
|
|
283
|
+
return Number(v).toFixed(3);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function updatePreset() {
|
|
287
|
+
const keys = PARAM_DEFS.filter(d => d.key).map(d => d.key);
|
|
288
|
+
const subset = {};
|
|
289
|
+
keys.forEach(k => subset[k] = P[k]);
|
|
290
|
+
el.preset.textContent = `当前参数: ${JSON.stringify(subset)}`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function clamp01(v) { return Math.max(0, Math.min(1, v)); }
|
|
294
|
+
function mix(a, b, t) { return a + (b - a) * t; }
|
|
295
|
+
function smoothstep(edge0, edge1, x) {
|
|
296
|
+
const t = clamp01((x - edge0) / (edge1 - edge0));
|
|
297
|
+
return t * t * (3 - 2 * t);
|
|
298
|
+
}
|
|
299
|
+
function wrap01(v) {
|
|
300
|
+
return ((v % 1) + 1) % 1;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function cycleLocal(phase, start, duration) {
|
|
304
|
+
const u = wrap01(phase - start);
|
|
305
|
+
if (u > duration) return null;
|
|
306
|
+
return u / duration;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function squeezeAt(phase) {
|
|
310
|
+
const u = cycleLocal(phase, P.squeezeStart, P.squeezeDuration);
|
|
311
|
+
if (u === null) return 0;
|
|
312
|
+
const ramp = clamp01(P.squeezeRamp);
|
|
313
|
+
if (u <= ramp) {
|
|
314
|
+
return Math.pow(smoothstep(0, 1, u / ramp), P.squeezePower);
|
|
315
|
+
}
|
|
316
|
+
const release = (u - ramp) / Math.max(0.001, 1 - ramp);
|
|
317
|
+
return Math.pow(1 - smoothstep(0, 1, release), P.squeezePower);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function rainBurstAt(phase) {
|
|
321
|
+
const start = wrap01(P.squeezeStart + P.rainDelay);
|
|
322
|
+
const u = cycleLocal(phase, start, P.rainDuration);
|
|
323
|
+
if (u === null) return 0;
|
|
324
|
+
const rampInCycle = Math.max(0.04, P.squeezeDuration * P.squeezeRamp);
|
|
325
|
+
const ramp = clamp01(rampInCycle / Math.max(0.001, P.rainDuration));
|
|
326
|
+
if (u <= ramp) {
|
|
327
|
+
return Math.pow(smoothstep(0, 1, u / ramp), P.rainBurstPower);
|
|
328
|
+
}
|
|
329
|
+
const release = (u - ramp) / Math.max(0.001, 1 - ramp);
|
|
330
|
+
return Math.pow(1 - smoothstep(0, 1, release), P.rainBurstPower);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function reboundAt(phase) {
|
|
334
|
+
const start = wrap01(P.squeezeStart + P.squeezeDuration * P.squeezeRamp);
|
|
335
|
+
const duration = Math.max(0.08, P.squeezeDuration * (1 - P.squeezeRamp));
|
|
336
|
+
const u = cycleLocal(phase, start, duration);
|
|
337
|
+
if (u === null) return 0;
|
|
338
|
+
return Math.sin(Math.PI * u) * Math.pow(1 - u, P.reboundDamping);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function renderAt(timeMs) {
|
|
342
|
+
const t = timeMs / 1000;
|
|
343
|
+
const phase = (t / P.period) % 1;
|
|
344
|
+
const squeeze = squeezeAt(phase);
|
|
345
|
+
const rainBurst = rainBurstAt(phase);
|
|
346
|
+
const rebound = reboundAt(phase);
|
|
347
|
+
const breath = 0.5 + 0.5 * Math.sin(TAU * (phase * P.breathSpeed - 0.18));
|
|
348
|
+
const breathScale = 1 + (breath - 0.5) * 2 * P.breathAmp;
|
|
349
|
+
const sx = 1.02 * breathScale + squeeze * P.squashXBoost - rebound * P.reboundOvershoot * 0.35;
|
|
350
|
+
const sy = 0.995 * breathScale - squeeze * P.squashAmp + rebound * P.reboundOvershoot;
|
|
351
|
+
const ty = 0.08 + (breath - 0.5) * 0.18 + squeeze * P.squeezeDropY - rebound * 0.12;
|
|
352
|
+
const twist = Math.sin(TAU * phase * 2.0) * squeeze;
|
|
353
|
+
const rot = (breath - 0.5) * 1.1 - squeeze * 1.15 + rebound * 0.55 + twist * 0.55;
|
|
354
|
+
el.cloudRoot.setAttribute(
|
|
355
|
+
'transform',
|
|
356
|
+
`translate(12 ${(12.1 + ty).toFixed(3)}) rotate(${rot.toFixed(3)}) scale(${sx.toFixed(4)} ${sy.toFixed(4)}) translate(-12 -12)`
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
const flow = t / P.period * P.flowSpeed * (1 + squeeze * P.twistFlowBoost);
|
|
360
|
+
el.bodyGrad.setAttribute('y1', (1.0 + Math.sin(flow * TAU * 0.36) * 0.35).toFixed(3));
|
|
361
|
+
el.bodyGrad.setAttribute('y2', (22.9 + Math.cos(flow * TAU * 0.32) * 0.30).toFixed(3));
|
|
362
|
+
el.bodyHi.setAttribute('cx', (9.2 + Math.sin(flow * TAU * 0.28) * 0.65).toFixed(3));
|
|
363
|
+
el.bodyHi.setAttribute('cy', (5.2 + Math.cos(flow * TAU * 0.24) * 0.35).toFixed(3));
|
|
364
|
+
el.bodyHi.setAttribute('r', (18.0 + Math.sin(flow * TAU * 0.20) * 0.18).toFixed(3));
|
|
365
|
+
el.bodyCore.setAttribute('cx', (12.2 + Math.sin(flow * TAU * 0.26 + 1.5) * 0.55).toFixed(3));
|
|
366
|
+
el.bodyCore.setAttribute('cy', (17.5 + Math.cos(flow * TAU * 0.22) * 0.40).toFixed(3));
|
|
367
|
+
el.bodyCore.setAttribute('r', (11.2 + Math.sin(flow * TAU * 0.18) * 0.25).toFixed(3));
|
|
368
|
+
el.coreA.setAttribute('stop-opacity', '0.20');
|
|
369
|
+
el.coreB.setAttribute('stop-opacity', '0.08');
|
|
370
|
+
|
|
371
|
+
const travel = P.flowTravel;
|
|
372
|
+
el.blur.setAttribute('stdDeviation', P.flowBlur.toFixed(3));
|
|
373
|
+
el.flowLight.setAttribute('cx', (8.5 + Math.sin(flow * TAU * 0.45) * travel * 0.55).toFixed(3));
|
|
374
|
+
el.flowLight.setAttribute('cy', (7.0 + Math.cos(flow * TAU * 0.34) * travel * 0.18).toFixed(3));
|
|
375
|
+
el.flowLight.setAttribute('opacity', (P.flowAlpha * 0.50).toFixed(3));
|
|
376
|
+
el.flowDark.setAttribute('cx', (15.6 + Math.cos(flow * TAU * 0.40) * travel * 0.55).toFixed(3));
|
|
377
|
+
el.flowDark.setAttribute('cy', (17.4 + Math.sin(flow * TAU * 0.32) * travel * 0.20).toFixed(3));
|
|
378
|
+
el.flowDark.setAttribute('opacity', (P.darkFlowAlpha * 0.70).toFixed(3));
|
|
379
|
+
const bandX = -13 + ((flow * 18) % 24);
|
|
380
|
+
el.flowBand.setAttribute('transform', `translate(${bandX.toFixed(3)} 0) rotate(-12 12 12)`);
|
|
381
|
+
el.flowBand.setAttribute('opacity', (P.bandAlpha * 0.46).toFixed(3));
|
|
382
|
+
|
|
383
|
+
const eyeYOffset = squeeze * 0.14;
|
|
384
|
+
el.eyes.setAttribute('opacity', (0.90 - squeeze * P.eyeDim + Math.sin(flow * TAU * 1.0) * 0.012).toFixed(3));
|
|
385
|
+
el.eyeGrad.setAttribute('y1', (8.5 + Math.sin(flow * TAU * 0.74) * 0.8).toFixed(3));
|
|
386
|
+
el.eyeGrad.setAttribute('y2', (15.8 + Math.sin(flow * TAU * 0.74) * 0.8).toFixed(3));
|
|
387
|
+
el.eyeL.setAttribute('transform', `translate(8.95 ${(12.2 + eyeYOffset).toFixed(3)}) rotate(${(-5 - squeeze * 1.5).toFixed(3)}) scale(${(1 - squeeze * 0.030).toFixed(3)})`);
|
|
388
|
+
el.eyeR.setAttribute('transform', `translate(15.05 ${(12.25 + eyeYOffset).toFixed(3)}) rotate(${(6 + squeeze * 1.2).toFixed(3)}) scale(${(1 - squeeze * 0.030).toFixed(3)})`);
|
|
389
|
+
|
|
390
|
+
el.hardShadow.setAttribute('flood-opacity', '0.62');
|
|
391
|
+
el.blueGlow.setAttribute('flood-opacity', '0.14');
|
|
392
|
+
el.ground.setAttribute('rx', (8.5 + (breath - 0.5) * 0.4).toFixed(3));
|
|
393
|
+
el.ground.setAttribute('opacity', '0.42');
|
|
394
|
+
|
|
395
|
+
const rainPower = clamp01(P.rainBaseOpacity + rainBurst * P.rainBurstOpacity);
|
|
396
|
+
el.rain.setAttribute('opacity', rainPower.toFixed(3));
|
|
397
|
+
el.rain.setAttribute('stroke-width', (0.36 + rainBurst * 0.13).toFixed(3));
|
|
398
|
+
RAIN_LINES.forEach((line, i) => {
|
|
399
|
+
const visible = i < P.rainCount;
|
|
400
|
+
const speed = P.rainBaseSpeed + rainBurst * P.rainBurstSpeed;
|
|
401
|
+
const fall = mix(2.6, 6.2, rainBurst);
|
|
402
|
+
const len = (line.len * P.rainBaseLength) + rainBurst * P.rainBurstLength;
|
|
403
|
+
rainPaths[i].forEach((path, copyIndex) => {
|
|
404
|
+
const p = (t * speed + line.delay + copyIndex / RAIN_COPIES) % 1;
|
|
405
|
+
const fadeIn = smoothstep(0.00, 0.24, p);
|
|
406
|
+
const fadeOut = 1 - smoothstep(0.76, 1.00, p);
|
|
407
|
+
const fade = Math.max(0.12, fadeIn * fadeOut);
|
|
408
|
+
const y1 = line.y + p * fall - squeeze * 0.30 - copyIndex * 0.15;
|
|
409
|
+
const x1 = line.x - p * P.rainDrift - squeeze * 0.12;
|
|
410
|
+
const y2 = y1 + len;
|
|
411
|
+
const x2 = x1 - 0.42;
|
|
412
|
+
path.setAttribute('d', `M${x1.toFixed(3)} ${y1.toFixed(3)} L${x2.toFixed(3)} ${y2.toFixed(3)}`);
|
|
413
|
+
path.setAttribute('opacity', visible ? (line.alpha * fade * 0.72).toFixed(3) : '0');
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
el.status.textContent = `phase ${phase.toFixed(2)} · squeeze ${squeeze.toFixed(2)} · rainBurst ${rainBurst.toFixed(2)} · rebound ${rebound.toFixed(2)} · sx ${sx.toFixed(3)} · sy ${sy.toFixed(3)}`;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function loop(now) {
|
|
421
|
+
if (!paused) {
|
|
422
|
+
renderAt(now - startedAt - pausedTotal);
|
|
423
|
+
}
|
|
424
|
+
requestAnimationFrame(loop);
|
|
425
|
+
}
|
|
426
|
+
requestAnimationFrame(loop);
|
|
427
|
+
]]></script>
|
|
428
|
+
</svg>
|