mocode-pet-app 1.4.0 → 1.7.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/assets/pets/01-robo-cat.motion.css +42 -0
- package/assets/pets/01-robo-cat.svg +2 -2
- package/assets/pets/02-robo-dog.motion.css +42 -0
- package/assets/pets/02-robo-dog.svg +1 -1
- package/assets/pets/03-robo-fox.motion.css +63 -0
- package/assets/pets/03-robo-fox.svg +1 -1
- package/assets/pets/04-robo-panda.motion.css +61 -0
- package/assets/pets/04-robo-panda.svg +1 -1
- package/assets/pets/05-robo-owl.motion.css +88 -0
- package/assets/pets/05-robo-owl.svg +3 -3
- package/assets/pets/06-robo-bunny.motion.css +84 -0
- package/assets/pets/06-robo-bunny.svg +2 -2
- package/assets/pets/07-robo-frog.motion.css +65 -0
- package/assets/pets/07-robo-frog.svg +3 -3
- package/assets/pets/08-robo-bear.motion.css +65 -0
- package/assets/pets/09-robo-penguin.motion.css +94 -0
- package/assets/pets/09-robo-penguin.svg +3 -3
- package/assets/pets/10-robo-dino.motion.css +91 -0
- package/assets/pets/10-robo-dino.svg +3 -3
- package/assets/pets/11-slime-blob.motion.css +44 -0
- package/assets/pets/11-slime-blob.svg +3 -3
- package/assets/pets/12-ghost-byte.motion.css +73 -0
- package/assets/pets/12-ghost-byte.svg +3 -3
- package/assets/pets/13-cactus-bot.motion.css +90 -0
- package/assets/pets/13-cactus-bot.svg +2 -2
- package/assets/pets/14-crystal-bot.motion.css +63 -0
- package/assets/pets/15-satellite-bot.motion.css +72 -0
- package/assets/pets/15-satellite-bot.svg +1 -1
- package/assets/pets/16-jellyfish-bot.motion.css +71 -0
- package/assets/pets/16-jellyfish-bot.svg +3 -3
- package/assets/pets/17-mushroom-bot.motion.css +65 -0
- package/assets/pets/18-star-bot.motion.css +72 -0
- package/assets/pets/18-star-bot.svg +3 -3
- package/assets/pets/manifest.json +139 -25
- package/dist/assets/pets/01-robo-cat.motion.css +42 -0
- package/dist/assets/pets/01-robo-cat.svg +2 -2
- package/dist/assets/pets/02-robo-dog.motion.css +42 -0
- package/dist/assets/pets/02-robo-dog.svg +1 -1
- package/dist/assets/pets/03-robo-fox.motion.css +63 -0
- package/dist/assets/pets/03-robo-fox.svg +1 -1
- package/dist/assets/pets/04-robo-panda.motion.css +61 -0
- package/dist/assets/pets/04-robo-panda.svg +1 -1
- package/dist/assets/pets/05-robo-owl.motion.css +88 -0
- package/dist/assets/pets/05-robo-owl.svg +3 -3
- package/dist/assets/pets/06-robo-bunny.motion.css +84 -0
- package/dist/assets/pets/06-robo-bunny.svg +2 -2
- package/dist/assets/pets/07-robo-frog.motion.css +65 -0
- package/dist/assets/pets/07-robo-frog.svg +3 -3
- package/dist/assets/pets/08-robo-bear.motion.css +65 -0
- package/dist/assets/pets/09-robo-penguin.motion.css +94 -0
- package/dist/assets/pets/09-robo-penguin.svg +3 -3
- package/dist/assets/pets/10-robo-dino.motion.css +91 -0
- package/dist/assets/pets/10-robo-dino.svg +3 -3
- package/dist/assets/pets/11-slime-blob.motion.css +44 -0
- package/dist/assets/pets/11-slime-blob.svg +3 -3
- package/dist/assets/pets/12-ghost-byte.motion.css +73 -0
- package/dist/assets/pets/12-ghost-byte.svg +3 -3
- package/dist/assets/pets/13-cactus-bot.motion.css +90 -0
- package/dist/assets/pets/13-cactus-bot.svg +2 -2
- package/dist/assets/pets/14-crystal-bot.motion.css +63 -0
- package/dist/assets/pets/15-satellite-bot.motion.css +72 -0
- package/dist/assets/pets/15-satellite-bot.svg +1 -1
- package/dist/assets/pets/16-jellyfish-bot.motion.css +71 -0
- package/dist/assets/pets/16-jellyfish-bot.svg +3 -3
- package/dist/assets/pets/17-mushroom-bot.motion.css +65 -0
- package/dist/assets/pets/18-star-bot.motion.css +72 -0
- package/dist/assets/pets/18-star-bot.svg +3 -3
- package/dist/assets/pets/manifest.json +139 -25
- package/dist/assets/tray-icon.png +0 -0
- package/dist/e2e-mood-check.js +150 -0
- package/dist/main.js +53 -2
- package/dist/mood-current-state.test.js +55 -0
- package/dist/mood-determinism.pbt.js +66 -0
- package/dist/mood-tracker-timing.test.js +70 -0
- package/dist/mood-tracker.js +41 -0
- package/dist/mood-tracker.test.js +56 -0
- package/dist/mood.js +102 -0
- package/dist/mood.pbt.js +52 -0
- package/dist/quips.js +59 -0
- package/dist/quips.test.js +98 -0
- package/dist/renderer/dom-mood.js +55 -0
- package/dist/renderer/dom-mood.test.js +105 -0
- package/dist/renderer/index.html +2 -0
- package/dist/renderer/preload.js +20 -2
- package/dist/renderer/renderer.js +29 -9
- package/dist/renderer/style.css +89 -0
- package/dist/skins.js +50 -1
- package/dist/skins.test.js +112 -0
- package/package.json +1 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* 机械熊猫(robo-panda)专属演出:体现"熊猫"的慵懒与迟缓,所有节奏都比通用更慢。
|
|
2
|
+
* 没有 #pet-arm-*,tool_call 改用身体大幅摇摆代替双臂摆动。 */
|
|
3
|
+
|
|
4
|
+
/* ── thinking:非常慢的小幅点头,像在打盹时梦到什么 ── */
|
|
5
|
+
@keyframes panda-think-drowsy {
|
|
6
|
+
0%, 100% { transform: rotate(0deg); }
|
|
7
|
+
50% { transform: rotate(-2deg); }
|
|
8
|
+
}
|
|
9
|
+
.pet-thinking #pet-body-group {
|
|
10
|
+
animation: panda-think-drowsy 2.4s ease-in-out infinite;
|
|
11
|
+
transform-origin: 128px 125px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* ── idle:非常慢的慵懒浮动,曲线比通用 3s 更沉 ── */
|
|
15
|
+
@keyframes panda-idle-lazy-float {
|
|
16
|
+
0%, 100% { transform: translateY(0); }
|
|
17
|
+
50% { transform: translateY(-3px); }
|
|
18
|
+
}
|
|
19
|
+
.pet-idle #pet-body-group {
|
|
20
|
+
animation: panda-idle-lazy-float 4.2s ease-in-out infinite;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* ── tool_call:慢慢左右晃身(代替双臂),动作幅度大但迟缓,像在嚼竹子 ── */
|
|
24
|
+
@keyframes panda-tool-sway {
|
|
25
|
+
0%, 100% { transform: rotate(0deg); }
|
|
26
|
+
50% { transform: rotate(6deg); }
|
|
27
|
+
}
|
|
28
|
+
.pet-tool #pet-body-group {
|
|
29
|
+
animation: panda-tool-sway 1.2s ease-in-out infinite;
|
|
30
|
+
transform-origin: 128px 125px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ── mood-tired:缓慢下沉 + 略微变暗,疲惫感比通用更浓 ── */
|
|
34
|
+
@keyframes panda-tired-sink {
|
|
35
|
+
0%, 100% { transform: translateY(0); opacity: 1; }
|
|
36
|
+
50% { transform: translateY(6px); opacity: 0.8; }
|
|
37
|
+
}
|
|
38
|
+
.mood-tired #pet-body-group {
|
|
39
|
+
animation: panda-tired-sink 4.8s ease-in-out infinite;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── mood-bored:慢到极致的左右摇晃,像快睡着了 ── */
|
|
43
|
+
@keyframes panda-bored-sway {
|
|
44
|
+
0%, 100% { transform: rotate(0deg); }
|
|
45
|
+
50% { transform: rotate(3deg); }
|
|
46
|
+
}
|
|
47
|
+
.mood-bored #pet-body-group {
|
|
48
|
+
animation: panda-bored-sway 3.2s ease-in-out infinite;
|
|
49
|
+
transform-origin: 128px 125px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* ── done:慵懒但满足的小弹 ── */
|
|
53
|
+
@keyframes panda-done-soft-bounce {
|
|
54
|
+
0% { transform: scale(1); }
|
|
55
|
+
40% { transform: scale(1.05); }
|
|
56
|
+
100% { transform: scale(1); }
|
|
57
|
+
}
|
|
58
|
+
.pet-done #pet-body-group {
|
|
59
|
+
animation: panda-done-soft-bounce 0.6s ease-out 1;
|
|
60
|
+
transform-origin: 128px 220px;
|
|
61
|
+
}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
<!-- Nose + mouth -->
|
|
45
45
|
<ellipse cx="128" cy="142" rx="8" ry="6" fill="#161a1e"/>
|
|
46
|
-
<rect x="112" y="150" width="32" height="5" rx="2.5" fill="#161a1e" fill-opacity="0.7"/>
|
|
46
|
+
<rect id="pet-mouth" x="112" y="150" width="32" height="5" rx="2.5" fill="#161a1e" fill-opacity="0.7"/>
|
|
47
47
|
|
|
48
48
|
<!-- Legs / feet -->
|
|
49
49
|
<rect x="76" y="200" width="20" height="26" rx="8" fill="#161a1e" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* 机械猫头鹰(robo-owl)专属演出:体现"猫头鹰"的机警与睿智。
|
|
2
|
+
* 头身一体的体型让"转头巡视"成为招牌动作;
|
|
3
|
+
* 双翼作为 #pet-arm-* 在这里承担"扇翅"的语义而非"挥臂"。 */
|
|
4
|
+
|
|
5
|
+
/* ── thinking:慢速 360° 巡视(大角度旋转,因为体型方,看起来像头部旋转) ── */
|
|
6
|
+
@keyframes owl-think-slow-scan {
|
|
7
|
+
0% { transform: rotate(0deg); }
|
|
8
|
+
100% { transform: rotate(360deg); }
|
|
9
|
+
}
|
|
10
|
+
.pet-thinking #pet-body-group {
|
|
11
|
+
animation: owl-think-slow-scan 4s linear infinite;
|
|
12
|
+
transform-origin: 128px 140px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* ── idle:缓慢左右转头巡视 ── */
|
|
16
|
+
@keyframes owl-idle-turn {
|
|
17
|
+
0%, 100% { transform: rotate(0deg); }
|
|
18
|
+
25% { transform: rotate(-8deg); }
|
|
19
|
+
75% { transform: rotate(8deg); }
|
|
20
|
+
}
|
|
21
|
+
.pet-idle #pet-body-group {
|
|
22
|
+
animation: owl-idle-turn 3.6s ease-in-out infinite;
|
|
23
|
+
transform-origin: 128px 140px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ── tool_call:双翼大幅拍动代替通用"双臂小幅摆动" ── */
|
|
27
|
+
@keyframes owl-tool-wing-left {
|
|
28
|
+
0%, 100% { transform: rotate(-12deg); }
|
|
29
|
+
50% { transform: rotate(-30deg); }
|
|
30
|
+
}
|
|
31
|
+
@keyframes owl-tool-wing-right {
|
|
32
|
+
0%, 100% { transform: rotate(12deg); }
|
|
33
|
+
50% { transform: rotate(30deg); }
|
|
34
|
+
}
|
|
35
|
+
.pet-tool #pet-arm-left {
|
|
36
|
+
animation: owl-tool-wing-left 0.4s ease-in-out infinite;
|
|
37
|
+
transform-origin: 26px 160px;
|
|
38
|
+
}
|
|
39
|
+
.pet-tool #pet-arm-right {
|
|
40
|
+
animation: owl-tool-wing-right 0.4s ease-in-out infinite 0.2s;
|
|
41
|
+
transform-origin: 230px 160px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* ── mood-urging:急促的翅膀拍打 + 身体前倾 ── */
|
|
45
|
+
@keyframes owl-urging-wing-left {
|
|
46
|
+
0%, 100% { transform: rotate(-12deg); }
|
|
47
|
+
50% { transform: rotate(-40deg); }
|
|
48
|
+
}
|
|
49
|
+
@keyframes owl-urging-wing-right {
|
|
50
|
+
0%, 100% { transform: rotate(12deg); }
|
|
51
|
+
50% { transform: rotate(40deg); }
|
|
52
|
+
}
|
|
53
|
+
@keyframes owl-urging-lean {
|
|
54
|
+
0%, 100% { transform: translateY(0) rotate(0deg); }
|
|
55
|
+
50% { transform: translateY(-2px) rotate(-3deg); }
|
|
56
|
+
}
|
|
57
|
+
.mood-urging #pet-arm-left {
|
|
58
|
+
animation: owl-urging-wing-left 0.2s ease-in-out infinite;
|
|
59
|
+
transform-origin: 26px 160px;
|
|
60
|
+
}
|
|
61
|
+
.mood-urging #pet-arm-right {
|
|
62
|
+
animation: owl-urging-wing-right 0.2s ease-in-out infinite 0.1s;
|
|
63
|
+
transform-origin: 230px 160px;
|
|
64
|
+
}
|
|
65
|
+
.mood-urging #pet-body-group {
|
|
66
|
+
animation: owl-urging-lean 0.4s ease-in-out infinite;
|
|
67
|
+
transform-origin: 128px 140px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ── done:展翅庆祝 ── */
|
|
71
|
+
@keyframes owl-done-spread-left {
|
|
72
|
+
0% { transform: rotate(-12deg); }
|
|
73
|
+
40% { transform: rotate(-50deg); }
|
|
74
|
+
100% { transform: rotate(-12deg); }
|
|
75
|
+
}
|
|
76
|
+
@keyframes owl-done-spread-right {
|
|
77
|
+
0% { transform: rotate(12deg); }
|
|
78
|
+
40% { transform: rotate(50deg); }
|
|
79
|
+
100% { transform: rotate(12deg); }
|
|
80
|
+
}
|
|
81
|
+
.pet-done #pet-arm-left {
|
|
82
|
+
animation: owl-done-spread-left 0.5s ease-out 1;
|
|
83
|
+
transform-origin: 26px 160px;
|
|
84
|
+
}
|
|
85
|
+
.pet-done #pet-arm-right {
|
|
86
|
+
animation: owl-done-spread-right 0.5s ease-out 1;
|
|
87
|
+
transform-origin: 230px 160px;
|
|
88
|
+
}
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
</circle>
|
|
34
34
|
|
|
35
35
|
<!-- Beak -->
|
|
36
|
-
<path d="M120 156 L128 172 L136 156 Z" fill="#ffb74d"/>
|
|
36
|
+
<path id="pet-mouth" d="M120 156 L128 172 L136 156 Z" fill="#ffb74d"/>
|
|
37
37
|
|
|
38
38
|
<!-- Folded wing arms(填充块面而非线条,末端贴身收圆) -->
|
|
39
|
-
<ellipse cx="26" cy="160" rx="14" ry="30" transform="rotate(-12 26 160)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
40
|
-
<ellipse cx="230" cy="160" rx="14" ry="30" transform="rotate(12 230 160)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
39
|
+
<ellipse id="pet-arm-left" cx="26" cy="160" rx="14" ry="30" transform="rotate(-12 26 160)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
40
|
+
<ellipse id="pet-arm-right" cx="230" cy="160" rx="14" ry="30" transform="rotate(12 230 160)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
41
41
|
|
|
42
42
|
<!-- Feet / talons -->
|
|
43
43
|
<rect x="76" y="200" width="20" height="24" rx="6" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5"/>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* 机械兔(robo-bunny)专属演出:体现"兔子"的轻快与活泼,节奏普遍偏快、幅度偏小。
|
|
2
|
+
* 注意:robo-bunny.svg 的 #pet-arm-left/right 自带 inline <animateTransform> 缓慢摆动,
|
|
3
|
+
* 这里在状态/mood class 下用更快的 keyframe 覆盖之;非覆盖状态下内置动画继续提供自然律动。 */
|
|
4
|
+
|
|
5
|
+
/* ── thinking:短促高频的小点头 ── */
|
|
6
|
+
@keyframes bunny-think-bob {
|
|
7
|
+
0%, 100% { transform: rotate(0deg); }
|
|
8
|
+
50% { transform: rotate(-3deg); }
|
|
9
|
+
}
|
|
10
|
+
.pet-thinking #pet-body-group {
|
|
11
|
+
animation: bunny-think-bob 0.6s ease-in-out infinite;
|
|
12
|
+
transform-origin: 128px 125px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* ── idle:轻微上下小跳,代替通用浮动 ── */
|
|
16
|
+
@keyframes bunny-idle-hop {
|
|
17
|
+
0%, 100% { transform: translateY(0); }
|
|
18
|
+
50% { transform: translateY(-8px); }
|
|
19
|
+
}
|
|
20
|
+
.pet-idle #pet-body-group {
|
|
21
|
+
animation: bunny-idle-hop 1.4s ease-in-out infinite;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ── tool_call:手臂快摆(覆盖内置慢摆),蹦跳式连续工作 ── */
|
|
25
|
+
@keyframes bunny-tool-arm-left {
|
|
26
|
+
0%, 100% { transform: rotate(-18deg); }
|
|
27
|
+
50% { transform: rotate(-40deg); }
|
|
28
|
+
}
|
|
29
|
+
@keyframes bunny-tool-arm-right {
|
|
30
|
+
0%, 100% { transform: rotate(18deg); }
|
|
31
|
+
50% { transform: rotate(40deg); }
|
|
32
|
+
}
|
|
33
|
+
.pet-tool #pet-arm-left {
|
|
34
|
+
animation: bunny-tool-arm-left 0.3s ease-in-out infinite;
|
|
35
|
+
transform-origin: 34px 130px;
|
|
36
|
+
}
|
|
37
|
+
.pet-tool #pet-arm-right {
|
|
38
|
+
animation: bunny-tool-arm-right 0.3s ease-in-out infinite 0.15s;
|
|
39
|
+
transform-origin: 222px 130px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── mood-tired:身体略微下沉,叠加在内置慢摆之上 ── */
|
|
43
|
+
@keyframes bunny-tired-sink {
|
|
44
|
+
0%, 100% { transform: translateY(0); opacity: 1; }
|
|
45
|
+
50% { transform: translateY(3px); opacity: 0.9; }
|
|
46
|
+
}
|
|
47
|
+
.mood-tired #pet-body-group {
|
|
48
|
+
animation: bunny-tired-sink 3.2s ease-in-out infinite;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* ── mood-urging:高频小跳 + 急切摆臂 ── */
|
|
52
|
+
@keyframes bunny-urging-hop {
|
|
53
|
+
0%, 100% { transform: translateY(0); }
|
|
54
|
+
50% { transform: translateY(-6px); }
|
|
55
|
+
}
|
|
56
|
+
@keyframes bunny-urging-arm-left {
|
|
57
|
+
0%, 100% { transform: rotate(-18deg); }
|
|
58
|
+
50% { transform: rotate(-50deg); }
|
|
59
|
+
}
|
|
60
|
+
@keyframes bunny-urging-arm-right {
|
|
61
|
+
0%, 100% { transform: rotate(18deg); }
|
|
62
|
+
50% { transform: rotate(50deg); }
|
|
63
|
+
}
|
|
64
|
+
.mood-urging #pet-body-group {
|
|
65
|
+
animation: bunny-urging-hop 0.35s ease-in-out infinite;
|
|
66
|
+
}
|
|
67
|
+
.mood-urging #pet-arm-left {
|
|
68
|
+
animation: bunny-urging-arm-left 0.2s ease-in-out infinite;
|
|
69
|
+
transform-origin: 34px 130px;
|
|
70
|
+
}
|
|
71
|
+
.mood-urging #pet-arm-right {
|
|
72
|
+
animation: bunny-urging-arm-right 0.2s ease-in-out infinite 0.1s;
|
|
73
|
+
transform-origin: 222px 130px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ── done:大弹跳一次 ── */
|
|
77
|
+
@keyframes bunny-done-bounce {
|
|
78
|
+
0% { transform: translateY(0) scale(1); }
|
|
79
|
+
40% { transform: translateY(-14px) scale(1.05); }
|
|
80
|
+
100% { transform: translateY(0) scale(1); }
|
|
81
|
+
}
|
|
82
|
+
.pet-done #pet-body-group {
|
|
83
|
+
animation: bunny-done-bounce 0.5s ease-out 1;
|
|
84
|
+
}
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
<path d="M122 148 L128 156 L134 148 Z" fill="#ff6ec7" filter="url(#glow)"/>
|
|
44
44
|
|
|
45
45
|
<!-- Arms (gentle wave) -->
|
|
46
|
-
<ellipse cx="34" cy="150" rx="12" ry="22" transform="rotate(-18 34 130)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5">
|
|
46
|
+
<ellipse id="pet-arm-left" cx="34" cy="150" rx="12" ry="22" transform="rotate(-18 34 130)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5">
|
|
47
47
|
<animateTransform attributeName="transform" type="rotate" values="-18 34 130;-30 34 130;-18 34 130;-6 34 130;-18 34 130" keyTimes="0;0.25;0.5;0.75;1" dur="2.6s" repeatCount="indefinite"/>
|
|
48
48
|
</ellipse>
|
|
49
|
-
<ellipse cx="222" cy="150" rx="12" ry="22" transform="rotate(18 222 130)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5">
|
|
49
|
+
<ellipse id="pet-arm-right" cx="222" cy="150" rx="12" ry="22" transform="rotate(18 222 130)" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2.5">
|
|
50
50
|
<animateTransform attributeName="transform" type="rotate" values="18 222 130;30 222 130;18 222 130;6 222 130;18 222 130" keyTimes="0;0.25;0.5;0.75;1" dur="2.6s" repeatCount="indefinite"/>
|
|
51
51
|
</ellipse>
|
|
52
52
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* 机械蛙(robo-frog)专属演出:利用"挤压/弹跳"这个青蛙的核心视觉语言,
|
|
2
|
+
* SVG 里没有 #pet-arm-*,tool_call 用整体压扁弹起代替通用双臂摆动。 */
|
|
3
|
+
|
|
4
|
+
/* ── thinking:嘴部开合(呱呱叫的雏形) ── */
|
|
5
|
+
@keyframes frog-think-mouth {
|
|
6
|
+
0%, 100% { transform: scaleY(1); }
|
|
7
|
+
50% { transform: scaleY(1.6); }
|
|
8
|
+
}
|
|
9
|
+
.pet-thinking #pet-mouth {
|
|
10
|
+
animation: frog-think-mouth 0.8s ease-in-out infinite;
|
|
11
|
+
transform-origin: 128px 150px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* ── idle:极轻微的鼓起呼吸 ── */
|
|
15
|
+
@keyframes frog-idle-breathe {
|
|
16
|
+
0%, 100% { transform: scale(1); }
|
|
17
|
+
50% { transform: scale(1.02); }
|
|
18
|
+
}
|
|
19
|
+
.pet-idle #pet-body-group {
|
|
20
|
+
animation: frog-idle-breathe 2.6s ease-in-out infinite;
|
|
21
|
+
transform-origin: 128px 200px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ── tool_call:压扁弹起,代替双臂摆动,像青蛙蓄力跳 ── */
|
|
25
|
+
@keyframes frog-tool-squash {
|
|
26
|
+
0%, 100% { transform: scaleY(1) scaleX(1); }
|
|
27
|
+
30% { transform: scaleY(0.78) scaleX(1.15); }
|
|
28
|
+
60% { transform: scaleY(1.18) scaleX(0.88); }
|
|
29
|
+
}
|
|
30
|
+
.pet-tool #pet-body-group {
|
|
31
|
+
animation: frog-tool-squash 0.55s ease-in-out infinite;
|
|
32
|
+
transform-origin: 128px 200px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ── mood-urging:嘴部急速张合(急促呱呱催促) ── */
|
|
36
|
+
@keyframes frog-urging-mouth {
|
|
37
|
+
0%, 100% { transform: scaleY(1); }
|
|
38
|
+
50% { transform: scaleY(2.4); }
|
|
39
|
+
}
|
|
40
|
+
.mood-urging #pet-mouth {
|
|
41
|
+
animation: frog-urging-mouth 0.25s ease-in-out infinite;
|
|
42
|
+
transform-origin: 128px 150px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── mood-tired:身体整体慢慢压扁变矮,像没气了的蛙 ── */
|
|
46
|
+
@keyframes frog-tired-squash {
|
|
47
|
+
0%, 100% { transform: scaleY(1); }
|
|
48
|
+
50% { transform: scaleY(0.86); }
|
|
49
|
+
}
|
|
50
|
+
.mood-tired #pet-body-group {
|
|
51
|
+
animation: frog-tired-squash 4.4s ease-in-out infinite;
|
|
52
|
+
transform-origin: 128px 200px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ── done:大跳跃一次 ── */
|
|
56
|
+
@keyframes frog-done-jump {
|
|
57
|
+
0% { transform: translateY(0) scaleY(1); }
|
|
58
|
+
30% { transform: translateY(0) scaleY(0.78) scaleX(1.15); }
|
|
59
|
+
50% { transform: translateY(-18px) scaleY(1.1) scaleX(0.92); }
|
|
60
|
+
100% { transform: translateY(0) scaleY(1); }
|
|
61
|
+
}
|
|
62
|
+
.pet-done #pet-body-group {
|
|
63
|
+
animation: frog-done-jump 0.55s ease-out 1;
|
|
64
|
+
transform-origin: 128px 200px;
|
|
65
|
+
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<feGaussianBlur stdDeviation="3" result="blur"/>
|
|
13
13
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
14
14
|
</filter>
|
|
15
|
-
</defs>
|
|
15
|
+
</defs>
|
|
16
16
|
<g id="pet-body-group">
|
|
17
17
|
|
|
18
18
|
<!-- Body / head (wide, squat) -->
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
|
|
31
31
|
<!-- Screen mouth panel -->
|
|
32
32
|
<rect x="60" y="110" width="136" height="72" rx="14" fill="#0a1420" stroke="#69f0ae" stroke-opacity="0.4" stroke-width="1.5"/>
|
|
33
|
-
<path d="M76 150 Q128 176 180 150" stroke="url(#accentGrad)" stroke-width="5" fill="none" stroke-linecap="round" filter="url(#glow)"/>
|
|
33
|
+
<path id="pet-mouth" d="M76 150 Q128 176 180 150" stroke="url(#accentGrad)" stroke-width="5" fill="none" stroke-linecap="round" filter="url(#glow)"/>
|
|
34
34
|
|
|
35
35
|
<!-- Bent frog legs -->
|
|
36
36
|
<path d="M50 176 Q20 190 30 224 Q46 236 56 214" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="3"/>
|
|
37
37
|
<path d="M206 176 Q236 190 226 224 Q210 236 200 214" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="3"/>
|
|
38
|
-
</g>
|
|
38
|
+
</g>
|
|
39
39
|
</svg>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* 机械熊(robo-bear)专属演出:体现"熊"的笨重与迟缓,所有动作幅度大但慢半拍。
|
|
2
|
+
* 没有 #pet-arm-*,tool_call 改为大角度身体摇摆代替双臂摆动。 */
|
|
3
|
+
|
|
4
|
+
/* ── thinking:沉甸甸的大幅点头,模拟思考时整颗头都跟着动 ── */
|
|
5
|
+
@keyframes bear-think-heavy-nod {
|
|
6
|
+
0%, 100% { transform: rotate(0deg); }
|
|
7
|
+
50% { transform: rotate(7deg); }
|
|
8
|
+
}
|
|
9
|
+
.pet-thinking #pet-body-group {
|
|
10
|
+
animation: bear-think-heavy-nod 1.6s ease-in-out infinite;
|
|
11
|
+
transform-origin: 128px 125px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* ── idle:比通用更慢更沉的浮动 ── */
|
|
15
|
+
@keyframes bear-idle-heavy-float {
|
|
16
|
+
0%, 100% { transform: translateY(0); }
|
|
17
|
+
50% { transform: translateY(-4px); }
|
|
18
|
+
}
|
|
19
|
+
.pet-idle #pet-body-group {
|
|
20
|
+
animation: bear-idle-heavy-float 4s ease-in-out infinite;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* ── tool_call:大幅左右晃身(代替双臂),动作慢但幅度大 ── */
|
|
24
|
+
@keyframes bear-tool-sway {
|
|
25
|
+
0%, 100% { transform: rotate(0deg); }
|
|
26
|
+
25% { transform: rotate(-8deg); }
|
|
27
|
+
75% { transform: rotate(8deg); }
|
|
28
|
+
}
|
|
29
|
+
.pet-tool #pet-body-group {
|
|
30
|
+
animation: bear-tool-sway 1s ease-in-out infinite;
|
|
31
|
+
transform-origin: 128px 125px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* ── mood-urging:熊式大甩头 ── */
|
|
35
|
+
@keyframes bear-urging-shake {
|
|
36
|
+
0%, 100% { transform: rotate(0deg); }
|
|
37
|
+
25% { transform: rotate(-10deg); }
|
|
38
|
+
75% { transform: rotate(10deg); }
|
|
39
|
+
}
|
|
40
|
+
.mood-urging #pet-body-group {
|
|
41
|
+
animation: bear-urging-shake 0.5s ease-in-out infinite;
|
|
42
|
+
transform-origin: 128px 125px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── mood-bored:慢悠悠的左右晃,像无聊到打哈欠 ── */
|
|
46
|
+
@keyframes bear-bored-sway {
|
|
47
|
+
0%, 100% { transform: rotate(0deg); }
|
|
48
|
+
50% { transform: rotate(5deg); }
|
|
49
|
+
}
|
|
50
|
+
.mood-bored #pet-body-group {
|
|
51
|
+
animation: bear-bored-sway 3.4s ease-in-out infinite;
|
|
52
|
+
transform-origin: 128px 125px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ── done:笨重但兴奋的小弹跳 ── */
|
|
56
|
+
@keyframes bear-done-stomp {
|
|
57
|
+
0% { transform: translateY(0) scale(1); }
|
|
58
|
+
40% { transform: translateY(0) scale(0.94); }
|
|
59
|
+
60% { transform: translateY(-10px) scale(1.06); }
|
|
60
|
+
100% { transform: translateY(0) scale(1); }
|
|
61
|
+
}
|
|
62
|
+
.pet-done #pet-body-group {
|
|
63
|
+
animation: bear-done-stomp 0.6s ease-out 1;
|
|
64
|
+
transform-origin: 128px 220px;
|
|
65
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* 机械企鹅(robo-penguin)专属演出:体现"企鹅"的摇摆与笨拙,所有动作以"左右晃"为核心。
|
|
2
|
+
* #pet-arm-left/right 是扁平鳍翼,这里当作鳍状手臂处理;pet-mouth 是橙色喙。 */
|
|
3
|
+
|
|
4
|
+
/* ── thinking:鳍翼小幅度拍打 + 身体轻摇 ── */
|
|
5
|
+
@keyframes penguin-think-flipper-left {
|
|
6
|
+
0%, 100% { transform: rotate(0deg); }
|
|
7
|
+
50% { transform: rotate(-10deg); }
|
|
8
|
+
}
|
|
9
|
+
@keyframes penguin-think-flipper-right {
|
|
10
|
+
0%, 100% { transform: rotate(0deg); }
|
|
11
|
+
50% { transform: rotate(10deg); }
|
|
12
|
+
}
|
|
13
|
+
.pet-thinking #pet-arm-left {
|
|
14
|
+
animation: penguin-think-flipper-left 0.9s ease-in-out infinite;
|
|
15
|
+
transform-origin: 42px 170px;
|
|
16
|
+
}
|
|
17
|
+
.pet-thinking #pet-arm-right {
|
|
18
|
+
animation: penguin-think-flipper-right 0.9s ease-in-out infinite 0.45s;
|
|
19
|
+
transform-origin: 214px 170px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* ── idle:站着轻微左右晃 ── */
|
|
23
|
+
@keyframes penguin-idle-wobble {
|
|
24
|
+
0%, 100% { transform: rotate(0deg); }
|
|
25
|
+
50% { transform: rotate(3deg); }
|
|
26
|
+
}
|
|
27
|
+
.pet-idle #pet-body-group {
|
|
28
|
+
animation: penguin-idle-wobble 2.2s ease-in-out infinite;
|
|
29
|
+
transform-origin: 128px 230px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* ── tool_call:企鹅招牌的左右摇摆(代替双臂摆动) + 鳍翼配合 ── */
|
|
33
|
+
@keyframes penguin-tool-waddle {
|
|
34
|
+
0%, 100% { transform: rotate(0deg); }
|
|
35
|
+
25% { transform: rotate(-7deg); }
|
|
36
|
+
75% { transform: rotate(7deg); }
|
|
37
|
+
}
|
|
38
|
+
@keyframes penguin-tool-flipper-left {
|
|
39
|
+
0%, 100% { transform: rotate(0deg); }
|
|
40
|
+
50% { transform: rotate(-18deg); }
|
|
41
|
+
}
|
|
42
|
+
@keyframes penguin-tool-flipper-right {
|
|
43
|
+
0%, 100% { transform: rotate(0deg); }
|
|
44
|
+
50% { transform: rotate(18deg); }
|
|
45
|
+
}
|
|
46
|
+
.pet-tool #pet-body-group {
|
|
47
|
+
animation: penguin-tool-waddle 0.55s ease-in-out infinite;
|
|
48
|
+
transform-origin: 128px 230px;
|
|
49
|
+
}
|
|
50
|
+
.pet-tool #pet-arm-left {
|
|
51
|
+
animation: penguin-tool-flipper-left 0.55s ease-in-out infinite;
|
|
52
|
+
transform-origin: 42px 170px;
|
|
53
|
+
}
|
|
54
|
+
.pet-tool #pet-arm-right {
|
|
55
|
+
animation: penguin-tool-flipper-right 0.55s ease-in-out infinite 0.27s;
|
|
56
|
+
transform-origin: 214px 170px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ── mood-urging:急促的鳍翼拍打 + 嘴部(喙)开合催促 ── */
|
|
60
|
+
@keyframes penguin-urging-flipper-left {
|
|
61
|
+
0%, 100% { transform: rotate(0deg); }
|
|
62
|
+
50% { transform: rotate(-22deg); }
|
|
63
|
+
}
|
|
64
|
+
@keyframes penguin-urging-flipper-right {
|
|
65
|
+
0%, 100% { transform: rotate(0deg); }
|
|
66
|
+
50% { transform: rotate(22deg); }
|
|
67
|
+
}
|
|
68
|
+
@keyframes penguin-urging-beak {
|
|
69
|
+
0%, 100% { transform: scaleY(1); }
|
|
70
|
+
50% { transform: scaleY(1.5); }
|
|
71
|
+
}
|
|
72
|
+
.mood-urging #pet-arm-left {
|
|
73
|
+
animation: penguin-urging-flipper-left 0.18s ease-in-out infinite;
|
|
74
|
+
transform-origin: 42px 170px;
|
|
75
|
+
}
|
|
76
|
+
.mood-urging #pet-arm-right {
|
|
77
|
+
animation: penguin-urging-flipper-right 0.18s ease-in-out infinite 0.09s;
|
|
78
|
+
transform-origin: 214px 170px;
|
|
79
|
+
}
|
|
80
|
+
.mood-urging #pet-mouth {
|
|
81
|
+
animation: penguin-urging-beak 0.18s ease-in-out infinite;
|
|
82
|
+
transform-origin: 128px 156px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ── done:小滑步式的弹跳 ── */
|
|
86
|
+
@keyframes penguin-done-slide {
|
|
87
|
+
0% { transform: translateX(0) scale(1); }
|
|
88
|
+
40% { transform: translateX(0) scale(1.08); }
|
|
89
|
+
100% { transform: translateX(0) scale(1); }
|
|
90
|
+
}
|
|
91
|
+
.pet-done #pet-body-group {
|
|
92
|
+
animation: penguin-done-slide 0.45s ease-out 1;
|
|
93
|
+
transform-origin: 128px 230px;
|
|
94
|
+
}
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
</g>
|
|
37
37
|
|
|
38
38
|
<!-- Beak -->
|
|
39
|
-
<path d="M116 156 L128 172 L140 156 Z" fill="#ffb74d"/>
|
|
39
|
+
<path id="pet-mouth" d="M116 156 L128 172 L140 156 Z" fill="#ffb74d"/>
|
|
40
40
|
|
|
41
41
|
<!-- Flipper arms(填充块面而非线条,贴身收成圆润小翼) -->
|
|
42
|
-
<path d="M42 146 Q16 162 22 190 Q26 204 42 202 Q50 200 46 188 Q40 168 46 150 Z" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2"/>
|
|
43
|
-
<path d="M214 146 Q240 162 234 190 Q230 204 214 202 Q206 200 210 188 Q216 168 210 150 Z" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2"/>
|
|
42
|
+
<path id="pet-arm-left" d="M42 146 Q16 162 22 190 Q26 204 42 202 Q50 200 46 188 Q40 168 46 150 Z" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2"/>
|
|
43
|
+
<path id="pet-arm-right" d="M214 146 Q240 162 234 190 Q230 204 214 202 Q206 200 210 188 Q216 168 210 150 Z" fill="url(#bodyGrad)" stroke="url(#accentGrad)" stroke-width="2"/>
|
|
44
44
|
|
|
45
45
|
<!-- Feet -->
|
|
46
46
|
<ellipse cx="104" cy="234" rx="16" ry="8" fill="#ffb74d"/>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* 机械龙(robo-dino)专属演出:体现"小龙"的凶猛与小只的暴躁,动作短促、节奏快、幅度大。
|
|
2
|
+
* #pet-arm-left/right 是两只小短手,只能用 rotate 模拟拍打;
|
|
3
|
+
* 嘴部 (#pet-mouth) 是锯齿状,适合用 scaleY 模拟咬合。 */
|
|
4
|
+
|
|
5
|
+
/* ── thinking:上下颌咬合(嘴部张合,模拟正在思考时"哼"的表情) ── */
|
|
6
|
+
@keyframes dino-think-jaw {
|
|
7
|
+
0%, 100% { transform: scaleY(1); }
|
|
8
|
+
50% { transform: scaleY(1.7); }
|
|
9
|
+
}
|
|
10
|
+
.pet-thinking #pet-mouth {
|
|
11
|
+
animation: dino-think-jaw 0.5s ease-in-out infinite;
|
|
12
|
+
transform-origin: 128px 148px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* ── idle:小幅度来回甩头(像小恐龙好动) ── */
|
|
16
|
+
@keyframes dino-idle-shake {
|
|
17
|
+
0%, 100% { transform: rotate(0deg); }
|
|
18
|
+
25% { transform: rotate(-3deg); }
|
|
19
|
+
75% { transform: rotate(3deg); }
|
|
20
|
+
}
|
|
21
|
+
.pet-idle #pet-body-group {
|
|
22
|
+
animation: dino-idle-shake 1.8s ease-in-out infinite;
|
|
23
|
+
transform-origin: 128px 125px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ── tool_call:小短手快速拍打 + 嘴部跟随咬合 ── */
|
|
27
|
+
@keyframes dino-tool-arm-left {
|
|
28
|
+
0%, 100% { transform: rotate(-34deg); }
|
|
29
|
+
50% { transform: rotate(-65deg); }
|
|
30
|
+
}
|
|
31
|
+
@keyframes dino-tool-arm-right {
|
|
32
|
+
0%, 100% { transform: rotate(34deg); }
|
|
33
|
+
50% { transform: rotate(65deg); }
|
|
34
|
+
}
|
|
35
|
+
@keyframes dino-tool-jaw {
|
|
36
|
+
0%, 100% { transform: scaleY(1); }
|
|
37
|
+
50% { transform: scaleY(1.4); }
|
|
38
|
+
}
|
|
39
|
+
.pet-tool #pet-arm-left {
|
|
40
|
+
animation: dino-tool-arm-left 0.25s ease-in-out infinite;
|
|
41
|
+
transform-origin: 31px 142px;
|
|
42
|
+
}
|
|
43
|
+
.pet-tool #pet-arm-right {
|
|
44
|
+
animation: dino-tool-arm-right 0.25s ease-in-out infinite 0.12s;
|
|
45
|
+
transform-origin: 223px 142px;
|
|
46
|
+
}
|
|
47
|
+
.pet-tool #pet-mouth {
|
|
48
|
+
animation: dino-tool-jaw 0.25s ease-in-out infinite;
|
|
49
|
+
transform-origin: 128px 148px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* ── mood-frustrated:暴躁甩头(替换通用 0.15s 平移抖动为更"角色化"的旋转甩头) ── */
|
|
53
|
+
@keyframes dino-frustrated-slam {
|
|
54
|
+
0%, 100% { transform: rotate(0deg) translateX(0); }
|
|
55
|
+
20% { transform: rotate(-6deg) translateX(-4px); }
|
|
56
|
+
60% { transform: rotate(6deg) translateX(4px); }
|
|
57
|
+
}
|
|
58
|
+
.mood-frustrated #pet-body-group {
|
|
59
|
+
animation: dino-frustrated-slam 0.18s ease-in-out infinite;
|
|
60
|
+
transform-origin: 128px 125px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── mood-urging:急躁跺脚 ── */
|
|
64
|
+
@keyframes dino-urging-stomp {
|
|
65
|
+
0%, 100% { transform: translateY(0) rotate(0deg); }
|
|
66
|
+
50% { transform: translateY(0) rotate(-5deg); }
|
|
67
|
+
}
|
|
68
|
+
@keyframes dino-urging-jaw {
|
|
69
|
+
0%, 100% { transform: scaleY(1); }
|
|
70
|
+
50% { transform: scaleY(1.8); }
|
|
71
|
+
}
|
|
72
|
+
.mood-urging #pet-body-group {
|
|
73
|
+
animation: dino-urging-stomp 0.35s ease-in-out infinite;
|
|
74
|
+
transform-origin: 128px 220px;
|
|
75
|
+
}
|
|
76
|
+
.mood-urging #pet-mouth {
|
|
77
|
+
animation: dino-urging-jaw 0.35s ease-in-out infinite;
|
|
78
|
+
transform-origin: 128px 148px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ── done:跺脚庆祝 ── */
|
|
82
|
+
@keyframes dino-done-stomp {
|
|
83
|
+
0% { transform: translateY(0) scale(1); }
|
|
84
|
+
30% { transform: translateY(0) scaleY(0.88) scaleX(1.1); }
|
|
85
|
+
60% { transform: translateY(-10px) scale(1.08); }
|
|
86
|
+
100% { transform: translateY(0) scale(1); }
|
|
87
|
+
}
|
|
88
|
+
.pet-done #pet-body-group {
|
|
89
|
+
animation: dino-done-stomp 0.5s ease-out 1;
|
|
90
|
+
transform-origin: 128px 220px;
|
|
91
|
+
}
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
</g>
|
|
40
40
|
|
|
41
41
|
<!-- Jagged mouth -->
|
|
42
|
-
<path d="M108 148 L118 156 L128 148 L138 156 L148 148" stroke="#69f0ae" stroke-width="4" fill="none" stroke-linecap="round" filter="url(#glow)"/>
|
|
42
|
+
<path id="pet-mouth" d="M108 148 L118 156 L128 148 L138 156 L148 148" stroke="#69f0ae" stroke-width="4" fill="none" stroke-linecap="round" filter="url(#glow)"/>
|
|
43
43
|
|
|
44
44
|
<!-- Small arms(填充块面而非线条,末端一颗圆球小手) -->
|
|
45
|
-
<ellipse cx="31" cy="142" rx="5.5" ry="15" fill="url(#accentGrad)" transform="rotate(-34 31 142)"/>
|
|
45
|
+
<ellipse id="pet-arm-left" cx="31" cy="142" rx="5.5" ry="15" fill="url(#accentGrad)" transform="rotate(-34 31 142)"/>
|
|
46
46
|
<circle cx="25" cy="156" r="5" fill="url(#accentGrad)"/>
|
|
47
|
-
<ellipse cx="223" cy="142" rx="5.5" ry="15" fill="url(#accentGrad)" transform="rotate(34 223 142)"/>
|
|
47
|
+
<ellipse id="pet-arm-right" cx="223" cy="142" rx="5.5" ry="15" fill="url(#accentGrad)" transform="rotate(34 223 142)"/>
|
|
48
48
|
<circle cx="231" cy="156" r="5" fill="url(#accentGrad)"/>
|
|
49
49
|
|
|
50
50
|
<!-- Legs / feet -->
|