@nice2dev/ui-graphics 1.0.0 → 1.0.3

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.
Files changed (146) hide show
  1. package/CHANGELOG.md +147 -1
  2. package/dist/cjs/animation/AnimatedPerson.js +2 -2
  3. package/dist/cjs/animation/AnimatedPerson.js.map +1 -1
  4. package/dist/cjs/animation/AnimationEditor.js +11 -6
  5. package/dist/cjs/animation/AnimationEditor.js.map +1 -1
  6. package/dist/cjs/animation/Audience.js +4 -3
  7. package/dist/cjs/animation/Audience.js.map +1 -1
  8. package/dist/cjs/animation/BodyRenderer.js +5 -2
  9. package/dist/cjs/animation/BodyRenderer.js.map +1 -1
  10. package/dist/cjs/animation/rig/RigPlayer.js +2 -2
  11. package/dist/cjs/animation/rig/RigPlayer.js.map +1 -1
  12. package/dist/cjs/animation/rig/RiggedBody.js +2 -2
  13. package/dist/cjs/animation/rig/RiggedBody.js.map +1 -1
  14. package/dist/cjs/animation/shapes/heads.js +4 -1
  15. package/dist/cjs/animation/shapes/heads.js.map +1 -1
  16. package/dist/cjs/core/LocalUI.js +1 -1
  17. package/dist/cjs/core/NiceBrushEngine.js +446 -0
  18. package/dist/cjs/core/NiceBrushEngine.js.map +1 -0
  19. package/dist/cjs/core/yjsCollaboration.js +292 -0
  20. package/dist/cjs/core/yjsCollaboration.js.map +1 -0
  21. package/dist/cjs/font/NiceFontEditor.js +89 -85
  22. package/dist/cjs/font/NiceFontEditor.js.map +1 -1
  23. package/dist/cjs/font/fontFormatUtils.js +468 -0
  24. package/dist/cjs/font/fontFormatUtils.js.map +1 -0
  25. package/dist/cjs/game/GameAsset2dEditor.js +38 -24
  26. package/dist/cjs/game/GameAsset2dEditor.js.map +1 -1
  27. package/dist/cjs/icon/NiceIconEditor.js +218 -133
  28. package/dist/cjs/icon/NiceIconEditor.js.map +1 -1
  29. package/dist/cjs/index.js +83 -1
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/nice2dev-ui-graphics.css +1 -1
  32. package/dist/cjs/photo/NiceAITools.js +446 -0
  33. package/dist/cjs/photo/NiceAITools.js.map +1 -0
  34. package/dist/cjs/photo/PhotoEditor.js +2 -2
  35. package/dist/cjs/photo/PhotoEditor.js.map +1 -1
  36. package/dist/cjs/pixel/PixelEditor.js +16 -5
  37. package/dist/cjs/pixel/PixelEditor.js.map +1 -1
  38. package/dist/cjs/pixel/PixelEditor.module.css.js +1 -1
  39. package/dist/cjs/pixel/PixelEditorMenuBar.js +2 -1
  40. package/dist/cjs/pixel/PixelEditorMenuBar.js.map +1 -1
  41. package/dist/cjs/pixel/PixelEditorRightPanel.js +3 -2
  42. package/dist/cjs/pixel/PixelEditorRightPanel.js.map +1 -1
  43. package/dist/cjs/pixel/PixelEditorTimeline.js +2 -1
  44. package/dist/cjs/pixel/PixelEditorTimeline.js.map +1 -1
  45. package/dist/cjs/pixel/PixelEditorToolbar.js +2 -1
  46. package/dist/cjs/pixel/PixelEditorToolbar.js.map +1 -1
  47. package/dist/cjs/pixel/SpriteGeneratorPanel.js +224 -0
  48. package/dist/cjs/pixel/SpriteGeneratorPanel.js.map +1 -0
  49. package/dist/cjs/pixel/animalGeneratorPresets.js +654 -0
  50. package/dist/cjs/pixel/animalGeneratorPresets.js.map +1 -0
  51. package/dist/cjs/pixel/buildingGeneratorPresets.js +573 -0
  52. package/dist/cjs/pixel/buildingGeneratorPresets.js.map +1 -0
  53. package/dist/cjs/pixel/characterGeneratorPresets.js +563 -0
  54. package/dist/cjs/pixel/characterGeneratorPresets.js.map +1 -0
  55. package/dist/cjs/pixel/spriteGeneratorCore.js +297 -0
  56. package/dist/cjs/pixel/spriteGeneratorCore.js.map +1 -0
  57. package/dist/cjs/pixel/usePixelEditor.js +16 -0
  58. package/dist/cjs/pixel/usePixelEditor.js.map +1 -1
  59. package/dist/cjs/texture/Nice3DTexturePainter.js +123 -79
  60. package/dist/cjs/texture/Nice3DTexturePainter.js.map +1 -1
  61. package/dist/cjs/ui/NiceUIDesigner.js +175 -62
  62. package/dist/cjs/ui/NiceUIDesigner.js.map +1 -1
  63. package/dist/cjs/ui/dist/index.js +50089 -0
  64. package/dist/cjs/ui/dist/index.js.map +1 -0
  65. package/dist/cjs/vector/NiceSvgToCode.js +427 -0
  66. package/dist/cjs/vector/NiceSvgToCode.js.map +1 -0
  67. package/dist/cjs/vector/VectorEditor.js +7 -3
  68. package/dist/cjs/vector/VectorEditor.js.map +1 -1
  69. package/dist/cjs/vector/VectorEditor.module.css.js +1 -1
  70. package/dist/cjs/vector/VectorEditorMenuBar.js +5 -1
  71. package/dist/cjs/vector/VectorEditorMenuBar.js.map +1 -1
  72. package/dist/cjs/vector/VectorEditorRightPanel.js +23 -19
  73. package/dist/cjs/vector/VectorEditorRightPanel.js.map +1 -1
  74. package/dist/esm/animation/AnimatedPerson.js +2 -2
  75. package/dist/esm/animation/AnimatedPerson.js.map +1 -1
  76. package/dist/esm/animation/AnimationEditor.js +12 -8
  77. package/dist/esm/animation/AnimationEditor.js.map +1 -1
  78. package/dist/esm/animation/Audience.js +5 -4
  79. package/dist/esm/animation/Audience.js.map +1 -1
  80. package/dist/esm/animation/BodyRenderer.js +4 -2
  81. package/dist/esm/animation/BodyRenderer.js.map +1 -1
  82. package/dist/esm/animation/rig/RigPlayer.js +4 -4
  83. package/dist/esm/animation/rig/RigPlayer.js.map +1 -1
  84. package/dist/esm/animation/rig/RiggedBody.js +2 -2
  85. package/dist/esm/animation/rig/RiggedBody.js.map +1 -1
  86. package/dist/esm/animation/shapes/heads.js +4 -2
  87. package/dist/esm/animation/shapes/heads.js.map +1 -1
  88. package/dist/esm/core/LocalUI.js +4 -4
  89. package/dist/esm/core/NiceBrushEngine.js +442 -0
  90. package/dist/esm/core/NiceBrushEngine.js.map +1 -0
  91. package/dist/esm/core/yjsCollaboration.js +283 -0
  92. package/dist/esm/core/yjsCollaboration.js.map +1 -0
  93. package/dist/esm/font/NiceFontEditor.js +89 -85
  94. package/dist/esm/font/NiceFontEditor.js.map +1 -1
  95. package/dist/esm/font/fontFormatUtils.js +461 -0
  96. package/dist/esm/font/fontFormatUtils.js.map +1 -0
  97. package/dist/esm/game/GameAsset2dEditor.js +38 -25
  98. package/dist/esm/game/GameAsset2dEditor.js.map +1 -1
  99. package/dist/esm/icon/NiceIconEditor.js +218 -133
  100. package/dist/esm/icon/NiceIconEditor.js.map +1 -1
  101. package/dist/esm/index.js +21 -11
  102. package/dist/esm/index.js.map +1 -1
  103. package/dist/esm/nice2dev-ui-graphics.css +1 -1
  104. package/dist/esm/photo/NiceAITools.js +439 -0
  105. package/dist/esm/photo/NiceAITools.js.map +1 -0
  106. package/dist/esm/photo/PhotoEditor.js +2 -2
  107. package/dist/esm/photo/PhotoEditor.js.map +1 -1
  108. package/dist/esm/pixel/PixelEditor.js +16 -6
  109. package/dist/esm/pixel/PixelEditor.js.map +1 -1
  110. package/dist/esm/pixel/PixelEditor.module.css.js +1 -1
  111. package/dist/esm/pixel/PixelEditorMenuBar.js +2 -1
  112. package/dist/esm/pixel/PixelEditorMenuBar.js.map +1 -1
  113. package/dist/esm/pixel/PixelEditorRightPanel.js +3 -2
  114. package/dist/esm/pixel/PixelEditorRightPanel.js.map +1 -1
  115. package/dist/esm/pixel/PixelEditorTimeline.js +2 -1
  116. package/dist/esm/pixel/PixelEditorTimeline.js.map +1 -1
  117. package/dist/esm/pixel/PixelEditorToolbar.js +2 -1
  118. package/dist/esm/pixel/PixelEditorToolbar.js.map +1 -1
  119. package/dist/esm/pixel/SpriteGeneratorPanel.js +222 -0
  120. package/dist/esm/pixel/SpriteGeneratorPanel.js.map +1 -0
  121. package/dist/esm/pixel/animalGeneratorPresets.js +647 -0
  122. package/dist/esm/pixel/animalGeneratorPresets.js.map +1 -0
  123. package/dist/esm/pixel/buildingGeneratorPresets.js +566 -0
  124. package/dist/esm/pixel/buildingGeneratorPresets.js.map +1 -0
  125. package/dist/esm/pixel/characterGeneratorPresets.js +556 -0
  126. package/dist/esm/pixel/characterGeneratorPresets.js.map +1 -0
  127. package/dist/esm/pixel/spriteGeneratorCore.js +279 -0
  128. package/dist/esm/pixel/spriteGeneratorCore.js.map +1 -0
  129. package/dist/esm/pixel/usePixelEditor.js +16 -0
  130. package/dist/esm/pixel/usePixelEditor.js.map +1 -1
  131. package/dist/esm/texture/Nice3DTexturePainter.js +123 -79
  132. package/dist/esm/texture/Nice3DTexturePainter.js.map +1 -1
  133. package/dist/esm/ui/NiceUIDesigner.js +175 -62
  134. package/dist/esm/ui/NiceUIDesigner.js.map +1 -1
  135. package/dist/esm/ui/dist/index.js +49686 -0
  136. package/dist/esm/ui/dist/index.js.map +1 -0
  137. package/dist/esm/vector/NiceSvgToCode.js +423 -0
  138. package/dist/esm/vector/NiceSvgToCode.js.map +1 -0
  139. package/dist/esm/vector/VectorEditor.js +7 -4
  140. package/dist/esm/vector/VectorEditor.js.map +1 -1
  141. package/dist/esm/vector/VectorEditor.module.css.js +1 -1
  142. package/dist/esm/vector/VectorEditorMenuBar.js +5 -1
  143. package/dist/esm/vector/VectorEditorMenuBar.js.map +1 -1
  144. package/dist/esm/vector/VectorEditorRightPanel.js +23 -19
  145. package/dist/esm/vector/VectorEditorRightPanel.js.map +1 -1
  146. package/package.json +3 -4
@@ -0,0 +1,647 @@
1
+ import { createPartData, generateMirroredDirections, registerParts } from './spriteGeneratorCore.js';
2
+
3
+ /**
4
+ * animalGeneratorPresets.ts — Modular animal sprite generator.
5
+ *
6
+ * Parts: heads (cat, dog, wolf, bird, dragon, rabbit, bear, horse),
7
+ * bodies, legs, tails, wings, manes.
8
+ * Integrates with quadruped skeleton template.
9
+ */
10
+ /* ════════════════════════════════════════════════════════════════
11
+ COLOUR PALETTES
12
+ ════════════════════════════════════════════════════════════════ */
13
+ const FUR_PALETTES = {
14
+ white: ['#f0f0f0', '#d0d0d0', '#b0b0b0', '#909090'],
15
+ black: ['#404040', '#303030', '#202020', '#101010'],
16
+ brown: ['#c08848', '#a06830', '#805020', '#603818'],
17
+ gray: ['#a0a0a0', '#808080', '#606060', '#404040'],
18
+ orange: ['#e09040', '#c07828', '#a06020', '#804818'],
19
+ golden: ['#f0d068', '#d0b048', '#b09030', '#907020'],
20
+ cream: ['#f0e8d0', '#d8d0b8', '#c0b8a0', '#a8a088'],
21
+ };
22
+ const SCALE_PALETTES = {
23
+ green: ['#40a040', '#308030', '#206020', '#104010'],
24
+ red: ['#c04040', '#a03030', '#802020', '#601010'],
25
+ blue: ['#4060c0', '#3048a0', '#203880', '#182060'],
26
+ gold: ['#f0d060', '#d0b040', '#a08020', '#806010'],
27
+ purple: ['#8040c0', '#6030a0', '#402080', '#301060'],
28
+ };
29
+ const FEATHER_PALETTES = {
30
+ brown: ['#a08040', '#806030', '#604020', '#402810'],
31
+ white: ['#f0f0f0', '#d8d8d8', '#c0c0c0', '#a0a0a0'],
32
+ blue: ['#4080d0', '#3060b0', '#204890', '#183070'],
33
+ red: ['#d04040', '#b03030', '#902020', '#701010'],
34
+ tropical: ['#40c040', '#f0d040', '#d06020', '#c03030'],
35
+ };
36
+ /* ════════════════════════════════════════════════════════════════
37
+ ANIMAL PARTS
38
+ ════════════════════════════════════════════════════════════════ */
39
+ const _ = -1;
40
+ /* ── Cat head ── */
41
+ const CAT_HEAD_S = createPartData(8, 7, [
42
+ [_, 0, _, _, _, _, 0, _],
43
+ [0, 0, 0, 0, 0, 0, 0, 0],
44
+ [0, 0, 0, 0, 0, 0, 0, 0],
45
+ [0, 0, 2, 0, 0, 2, 0, 0],
46
+ [0, 0, 0, 0, 0, 0, 0, 0],
47
+ [0, 0, 0, 3, 3, 0, 0, 0],
48
+ [_, 0, 0, 0, 0, 0, 0, _],
49
+ ], ['#e09040', '#c07828', '#40a040', '#f0a0a0']);
50
+ const CAT_HEAD_E = createPartData(6, 7, [
51
+ [_, _, _, _, 0, _],
52
+ [_, 0, 0, 0, 0, 0],
53
+ [0, 0, 0, 0, 0, 0],
54
+ [0, 0, 0, 2, 0, 0],
55
+ [0, 0, 0, 0, 0, 0],
56
+ [0, 0, 0, 0, 3, 0],
57
+ [_, 0, 0, 0, 0, _],
58
+ ], ['#e09040', '#c07828', '#40a040', '#f0a0a0']);
59
+ /* ── Dog head ── */
60
+ const DOG_HEAD_S = createPartData(8, 8, [
61
+ [_, _, 0, 0, 0, 0, _, _],
62
+ [_, 0, 0, 0, 0, 0, 0, _],
63
+ [0, 0, 0, 0, 0, 0, 0, 0],
64
+ [0, 0, 2, 0, 0, 2, 0, 0],
65
+ [0, 0, 0, 0, 0, 0, 0, 0],
66
+ [_, 0, 0, 3, 3, 0, 0, _],
67
+ [_, _, 0, 0, 0, 0, _, _],
68
+ [_, _, _, 0, 0, _, _, _],
69
+ ], ['#c08848', '#a06830', '#301818', '#301818']);
70
+ const DOG_HEAD_E = createPartData(7, 8, [
71
+ [_, _, 0, 0, 0, _, _],
72
+ [_, 0, 0, 0, 0, 0, _],
73
+ [0, 0, 0, 0, 0, 0, _],
74
+ [0, 0, 0, 0, 2, 0, _],
75
+ [0, 0, 0, 0, 0, 0, _],
76
+ [_, 0, 0, 0, 0, 3, 0],
77
+ [_, _, 0, 0, 0, 3, 0],
78
+ [_, _, _, 0, 0, 0, _],
79
+ ], ['#c08848', '#a06830', '#301818', '#301818']);
80
+ /* ── Wolf head ── */
81
+ const WOLF_HEAD_S = createPartData(10, 8, [
82
+ [_, 0, _, _, _, _, _, _, 0, _],
83
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
84
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
85
+ [0, 0, 0, 2, 0, 0, 2, 0, 0, 0],
86
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
87
+ [_, 0, 0, 0, 3, 3, 0, 0, 0, _],
88
+ [_, _, 0, 0, 0, 0, 0, 0, _, _],
89
+ [_, _, _, 0, 0, 0, 0, _, _, _],
90
+ ], ['#808080', '#606060', '#f0d060', '#301818']);
91
+ /* ── Bird head ── */
92
+ const BIRD_HEAD_S = createPartData(6, 6, [
93
+ [_, _, 0, 0, _, _],
94
+ [_, 0, 0, 0, 0, _],
95
+ [0, 0, 2, 2, 0, 0],
96
+ [0, 0, 0, 0, 0, 0],
97
+ [_, 0, 3, 3, 0, _],
98
+ [_, _, _, 3, _, _],
99
+ ], ['#a08040', '#806030', '#301818', '#f0a020']);
100
+ /* ── Dragon head ── */
101
+ const DRAGON_HEAD_S = createPartData(10, 9, [
102
+ [_, _, _, 0, _, _, 0, _, _, _],
103
+ [_, _, 0, 0, 0, 0, 0, 0, _, _],
104
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
105
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
106
+ [0, 0, 0, 2, 0, 0, 2, 0, 0, 0],
107
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
108
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
109
+ [_, _, 0, 0, 3, 3, 0, 0, _, _],
110
+ [_, _, _, 0, 0, 0, 0, _, _, _],
111
+ ], ['#40a040', '#308030', '#f0d060', '#301818']);
112
+ /* ── Rabbit head ── */
113
+ const RABBIT_HEAD_S = createPartData(8, 10, [
114
+ [_, _, 0, _, _, 0, _, _],
115
+ [_, _, 0, _, _, 0, _, _],
116
+ [_, _, 0, _, _, 0, _, _],
117
+ [_, 0, 0, 0, 0, 0, 0, _],
118
+ [0, 0, 0, 0, 0, 0, 0, 0],
119
+ [0, 0, 2, 0, 0, 2, 0, 0],
120
+ [0, 0, 0, 0, 0, 0, 0, 0],
121
+ [0, 0, 0, 3, 3, 0, 0, 0],
122
+ [_, 0, 0, 0, 0, 0, 0, _],
123
+ [_, _, 0, 0, 0, 0, _, _],
124
+ ], ['#f0e8d0', '#d8d0b8', '#d04040', '#f0a0a0']);
125
+ /* ── Bear head ── */
126
+ const BEAR_HEAD_S = createPartData(10, 9, [
127
+ [_, 0, 0, _, _, _, _, 0, 0, _],
128
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
129
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
130
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
131
+ [0, 0, 0, 2, 0, 0, 2, 0, 0, 0],
132
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
133
+ [0, 0, 0, 0, 3, 3, 0, 0, 0, 0],
134
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
135
+ [_, _, 0, 0, 0, 0, 0, 0, _, _],
136
+ ], ['#805020', '#603818', '#201010', '#402818']);
137
+ /* ── Horse head ── */
138
+ const HORSE_HEAD_S = createPartData(8, 10, [
139
+ [_, _, _, 0, 0, _, _, _],
140
+ [_, _, 0, 0, 0, 0, _, _],
141
+ [_, 0, 0, 0, 0, 0, 0, _],
142
+ [0, 0, 0, 0, 0, 0, 0, 0],
143
+ [0, 0, 2, 0, 0, 2, 0, 0],
144
+ [0, 0, 0, 0, 0, 0, 0, 0],
145
+ [_, 0, 0, 0, 0, 0, 0, _],
146
+ [_, _, 0, 0, 0, 0, _, _],
147
+ [_, _, 0, 0, 0, 0, _, _],
148
+ [_, _, _, 0, 0, _, _, _],
149
+ ], ['#c08848', '#a06830', '#301818']);
150
+ /* ── Bodies ── */
151
+ const BODY_SMALL = createPartData(8, 6, [
152
+ [_, _, 0, 0, 0, 0, _, _],
153
+ [_, 0, 0, 0, 0, 0, 0, _],
154
+ [0, 0, 0, 0, 0, 0, 0, 0],
155
+ [0, 0, 0, 0, 0, 0, 0, 0],
156
+ [_, 0, 0, 0, 0, 0, 0, _],
157
+ [_, _, 0, 0, 0, 0, _, _],
158
+ ], ['#e09040', '#c07828']);
159
+ const BODY_MEDIUM = createPartData(12, 8, [
160
+ [_, _, _, 0, 0, 0, 0, 0, 0, _, _, _],
161
+ [_, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _],
162
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
163
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
164
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
165
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
166
+ [_, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _],
167
+ [_, _, _, 0, 0, 0, 0, 0, 0, _, _, _],
168
+ ], ['#c08848', '#a06830']);
169
+ const BODY_LARGE = createPartData(14, 10, [
170
+ [_, _, _, _, 0, 0, 0, 0, 0, 0, _, _, _, _],
171
+ [_, _, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _, _],
172
+ [_, _, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _, _],
173
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
174
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
175
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
176
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
177
+ [_, _, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _, _],
178
+ [_, _, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _, _],
179
+ [_, _, _, _, 0, 0, 0, 0, 0, 0, _, _, _, _],
180
+ ], ['#805020', '#603818']);
181
+ const BODY_BIRD = createPartData(8, 7, [
182
+ [_, _, _, 0, 0, _, _, _],
183
+ [_, _, 0, 0, 0, 0, _, _],
184
+ [_, 0, 0, 0, 0, 0, 0, _],
185
+ [0, 0, 0, 0, 0, 0, 0, 0],
186
+ [_, 0, 0, 0, 0, 0, 0, _],
187
+ [_, _, 0, 0, 0, 0, _, _],
188
+ [_, _, _, 0, 0, _, _, _],
189
+ ], ['#a08040', '#806030']);
190
+ const BODY_DRAGON = createPartData(14, 10, [
191
+ [_, _, _, _, _, 0, 0, 0, 0, _, _, _, _, _],
192
+ [_, _, _, _, 0, 0, 0, 0, 0, 0, _, _, _, _],
193
+ [_, _, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _, _],
194
+ [_, _, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _, _],
195
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
196
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
197
+ [_, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, _],
198
+ [_, _, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, _, _],
199
+ [_, _, _, 0, 0, 0, 0, 0, 0, 0, 0, _, _, _],
200
+ [_, _, _, _, 0, 0, 0, 0, 0, 0, _, _, _, _],
201
+ ], ['#40a040', '#f0d060']);
202
+ /* ── Legs ── */
203
+ const LEG_THIN = createPartData(2, 5, [
204
+ [0, 0],
205
+ [0, 0],
206
+ [0, 0],
207
+ [0, 0],
208
+ [0, 1],
209
+ ], ['#c08848', '#a06830']);
210
+ const LEG_THICK = createPartData(3, 5, [
211
+ [0, 0, 0],
212
+ [0, 0, 0],
213
+ [0, 0, 0],
214
+ [0, 0, 0],
215
+ [0, 0, 1],
216
+ ], ['#805020', '#603818']);
217
+ const LEG_BIRD = createPartData(2, 5, [
218
+ [_, 0],
219
+ [_, 0],
220
+ [_, 0],
221
+ [0, 0],
222
+ [0, 0],
223
+ ], ['#f0a020', '#c08010']);
224
+ const LEG_DRAGON = createPartData(3, 6, [
225
+ [_, 0, 0],
226
+ [0, 0, 0],
227
+ [0, 0, 0],
228
+ [0, 0, 0],
229
+ [0, 0, 0],
230
+ [0, 1, 0],
231
+ ], ['#40a040', '#206020']);
232
+ /* ── Tails ── */
233
+ const TAIL_SHORT = createPartData(4, 3, [
234
+ [0, 0, _, _],
235
+ [_, 0, 0, _],
236
+ [_, _, 0, 0],
237
+ ], ['#e09040', '#c07828']);
238
+ const TAIL_LONG = createPartData(6, 4, [
239
+ [0, 0, _, _, _, _],
240
+ [_, 0, 0, _, _, _],
241
+ [_, _, 0, 0, _, _],
242
+ [_, _, _, 0, 0, 0],
243
+ ], ['#c08848', '#a06830']);
244
+ const TAIL_FLUFFY = createPartData(6, 5, [
245
+ [_, 0, 0, _, _, _],
246
+ [0, 0, 0, 0, _, _],
247
+ [_, 0, 0, 0, 0, _],
248
+ [_, _, 0, 0, 0, 0],
249
+ [_, _, _, 0, 0, _],
250
+ ], ['#808080', '#606060']);
251
+ const TAIL_DRAGON = createPartData(8, 4, [
252
+ [0, 0, _, _, _, _, _, _],
253
+ [_, 0, 0, 0, _, _, _, _],
254
+ [_, _, _, 0, 0, 0, _, _],
255
+ [_, _, _, _, _, 0, 1, 0],
256
+ ], ['#40a040', '#308030']);
257
+ const TAIL_BIRD = createPartData(5, 5, [
258
+ [_, _, 0, _, _],
259
+ [_, 0, 0, 0, _],
260
+ [0, 0, 0, 0, 0],
261
+ [_, 0, 0, 0, _],
262
+ [_, _, 0, _, _],
263
+ ], ['#a08040', '#806030']);
264
+ /* ── Wings ── */
265
+ const WING_SMALL = createPartData(6, 5, [
266
+ [_, _, _, _, 0, _],
267
+ [_, _, _, 0, 0, 0],
268
+ [_, _, 0, 0, 0, 0],
269
+ [_, 0, 0, 0, 0, 0],
270
+ [0, 0, 0, 0, 0, _],
271
+ ], ['#a08040', '#806030']);
272
+ const WING_LARGE = createPartData(10, 8, [
273
+ [_, _, _, _, _, _, _, _, 0, _],
274
+ [_, _, _, _, _, _, _, 0, 0, 0],
275
+ [_, _, _, _, _, _, 0, 0, 0, 0],
276
+ [_, _, _, _, _, 0, 0, 0, 0, 0],
277
+ [_, _, _, _, 0, 0, 0, 0, 0, 0],
278
+ [_, _, _, 0, 0, 0, 0, 0, 0, 0],
279
+ [_, _, 0, 0, 0, 0, 0, 0, 0, _],
280
+ [_, 0, 0, 0, 0, 0, 0, 0, _, _],
281
+ ], ['#40a040', '#308030']);
282
+ const WING_BAT = createPartData(10, 7, [
283
+ [_, _, 0, _, _, 0, _, _, 0, _],
284
+ [_, 0, 0, _, 0, 0, _, 0, 0, _],
285
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
286
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
287
+ [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
288
+ [_, _, 0, 0, 0, 0, 0, 0, _, _],
289
+ [_, _, _, 0, 0, 0, 0, _, _, _],
290
+ ], ['#404040', '#303030']);
291
+ /* ── Manes ── */
292
+ const MANE_SHORT = createPartData(6, 4, [
293
+ [_, _, 0, 0, _, _],
294
+ [_, 0, 0, 0, 0, _],
295
+ [0, 0, 0, 0, 0, 0],
296
+ [_, _, 0, 0, _, _],
297
+ ], ['#c08848', '#a06830']);
298
+ const MANE_LONG = createPartData(6, 8, [
299
+ [_, _, 0, 0, _, _],
300
+ [_, 0, 0, 0, 0, _],
301
+ [0, 0, 0, 0, 0, 0],
302
+ [0, 0, 0, 0, 0, 0],
303
+ [0, 0, 0, 0, 0, 0],
304
+ [_, 0, 0, 0, 0, _],
305
+ [_, 0, 0, 0, 0, _],
306
+ [_, _, 0, 0, _, _],
307
+ ], ['#c08848', '#a06830']);
308
+ /* ── Horns ── */
309
+ const HORNS_SMALL = createPartData(8, 3, [
310
+ [0, _, _, _, _, _, _, 0],
311
+ [0, 0, _, _, _, _, 0, 0],
312
+ [_, 0, _, _, _, _, 0, _],
313
+ ], ['#f0e8d0', '#d8d0b8']);
314
+ const HORNS_DRAGON = createPartData(10, 4, [
315
+ [0, _, _, _, _, _, _, _, _, 0],
316
+ [0, 0, _, _, _, _, _, _, 0, 0],
317
+ [_, 0, 0, _, _, _, _, 0, 0, _],
318
+ [_, _, 0, _, _, _, _, 0, _, _],
319
+ ], ['#805020', '#603818']);
320
+ /* ════════════════════════════════════════════════════════════════
321
+ REGISTER ALL ANIMAL PARTS
322
+ ════════════════════════════════════════════════════════════════ */
323
+ const ANIMAL_PARTS = [
324
+ // ── Heads ──
325
+ {
326
+ id: 'animal-head-cat', name: 'Cat Head', category: 'animalHead', slot: 'head',
327
+ anchorX: 4, anchorY: 6, zOrder: 10, tags: ['cat', 'small', 'pet'],
328
+ pixels: generateMirroredDirections({ S: CAT_HEAD_S, E: CAT_HEAD_E }),
329
+ recolorableIndices: [0, 1],
330
+ },
331
+ {
332
+ id: 'animal-head-dog', name: 'Dog Head', category: 'animalHead', slot: 'head',
333
+ anchorX: 4, anchorY: 7, zOrder: 10, tags: ['dog', 'medium', 'pet'],
334
+ pixels: generateMirroredDirections({ S: DOG_HEAD_S, E: DOG_HEAD_E }),
335
+ recolorableIndices: [0, 1],
336
+ },
337
+ {
338
+ id: 'animal-head-wolf', name: 'Wolf Head', category: 'animalHead', slot: 'head',
339
+ anchorX: 5, anchorY: 7, zOrder: 10, tags: ['wolf', 'wild', 'predator'],
340
+ pixels: { S: WOLF_HEAD_S },
341
+ recolorableIndices: [0, 1],
342
+ },
343
+ {
344
+ id: 'animal-head-bird', name: 'Bird Head', category: 'animalHead', slot: 'head',
345
+ anchorX: 3, anchorY: 5, zOrder: 10, tags: ['bird', 'small', 'flying'],
346
+ pixels: { S: BIRD_HEAD_S },
347
+ recolorableIndices: [0, 1],
348
+ },
349
+ {
350
+ id: 'animal-head-dragon', name: 'Dragon Head', category: 'animalHead', slot: 'head',
351
+ anchorX: 5, anchorY: 8, zOrder: 10, tags: ['dragon', 'fantasy', 'large'],
352
+ pixels: { S: DRAGON_HEAD_S },
353
+ recolorableIndices: [0, 1],
354
+ },
355
+ {
356
+ id: 'animal-head-rabbit', name: 'Rabbit Head', category: 'animalHead', slot: 'head',
357
+ anchorX: 4, anchorY: 9, zOrder: 10, tags: ['rabbit', 'small', 'pet'],
358
+ pixels: { S: RABBIT_HEAD_S },
359
+ recolorableIndices: [0, 1],
360
+ },
361
+ {
362
+ id: 'animal-head-bear', name: 'Bear Head', category: 'animalHead', slot: 'head',
363
+ anchorX: 5, anchorY: 8, zOrder: 10, tags: ['bear', 'large', 'wild'],
364
+ pixels: { S: BEAR_HEAD_S },
365
+ recolorableIndices: [0, 1],
366
+ },
367
+ {
368
+ id: 'animal-head-horse', name: 'Horse Head', category: 'animalHead', slot: 'head',
369
+ anchorX: 4, anchorY: 9, zOrder: 10, tags: ['horse', 'large', 'rideable'],
370
+ pixels: { S: HORSE_HEAD_S },
371
+ recolorableIndices: [0, 1],
372
+ },
373
+ // ── Bodies ──
374
+ {
375
+ id: 'animal-body-small', name: 'Small Body', category: 'animalBody', slot: 'body',
376
+ anchorX: 4, anchorY: 0, zOrder: 5, tags: ['small', 'cat', 'rabbit'],
377
+ pixels: { S: BODY_SMALL },
378
+ recolorableIndices: [0, 1],
379
+ },
380
+ {
381
+ id: 'animal-body-medium', name: 'Medium Body', category: 'animalBody', slot: 'body',
382
+ anchorX: 6, anchorY: 0, zOrder: 5, tags: ['medium', 'dog', 'wolf'],
383
+ pixels: { S: BODY_MEDIUM },
384
+ recolorableIndices: [0, 1],
385
+ },
386
+ {
387
+ id: 'animal-body-large', name: 'Large Body', category: 'animalBody', slot: 'body',
388
+ anchorX: 7, anchorY: 0, zOrder: 5, tags: ['large', 'bear', 'horse'],
389
+ pixels: { S: BODY_LARGE },
390
+ recolorableIndices: [0, 1],
391
+ },
392
+ {
393
+ id: 'animal-body-bird', name: 'Bird Body', category: 'animalBody', slot: 'body',
394
+ anchorX: 4, anchorY: 0, zOrder: 5, tags: ['bird', 'small', 'flying'],
395
+ pixels: { S: BODY_BIRD },
396
+ recolorableIndices: [0, 1],
397
+ },
398
+ {
399
+ id: 'animal-body-dragon', name: 'Dragon Body', category: 'animalBody', slot: 'body',
400
+ anchorX: 7, anchorY: 0, zOrder: 5, tags: ['dragon', 'fantasy', 'large'],
401
+ pixels: { S: BODY_DRAGON },
402
+ recolorableIndices: [0, 1],
403
+ },
404
+ // ── Legs ──
405
+ {
406
+ id: 'animal-leg-thin', name: 'Thin Leg', category: 'animalLeg', slot: 'leftLeg',
407
+ anchorX: 1, anchorY: 0, zOrder: 3, tags: ['thin', 'small', 'cat', 'dog'],
408
+ pixels: { S: LEG_THIN },
409
+ recolorableIndices: [0, 1],
410
+ },
411
+ {
412
+ id: 'animal-leg-thick', name: 'Thick Leg', category: 'animalLeg', slot: 'leftLeg',
413
+ anchorX: 1, anchorY: 0, zOrder: 3, tags: ['thick', 'large', 'bear', 'horse'],
414
+ pixels: { S: LEG_THICK },
415
+ recolorableIndices: [0, 1],
416
+ },
417
+ {
418
+ id: 'animal-leg-bird', name: 'Bird Leg', category: 'animalLeg', slot: 'leftLeg',
419
+ anchorX: 1, anchorY: 0, zOrder: 3, tags: ['bird', 'claw'],
420
+ pixels: { S: LEG_BIRD },
421
+ recolorableIndices: [0, 1],
422
+ },
423
+ {
424
+ id: 'animal-leg-dragon', name: 'Dragon Leg', category: 'animalLeg', slot: 'leftLeg',
425
+ anchorX: 1, anchorY: 0, zOrder: 3, tags: ['dragon', 'claw', 'large'],
426
+ pixels: { S: LEG_DRAGON },
427
+ recolorableIndices: [0, 1],
428
+ },
429
+ // ── Tails ──
430
+ {
431
+ id: 'animal-tail-short', name: 'Short Tail', category: 'animalTail', slot: 'tail',
432
+ anchorX: 0, anchorY: 1, zOrder: 2, tags: ['short', 'cat', 'dog'],
433
+ pixels: { S: TAIL_SHORT },
434
+ recolorableIndices: [0, 1],
435
+ },
436
+ {
437
+ id: 'animal-tail-long', name: 'Long Tail', category: 'animalTail', slot: 'tail',
438
+ anchorX: 0, anchorY: 1, zOrder: 2, tags: ['long', 'dog', 'wolf'],
439
+ pixels: { S: TAIL_LONG },
440
+ recolorableIndices: [0, 1],
441
+ },
442
+ {
443
+ id: 'animal-tail-fluffy', name: 'Fluffy Tail', category: 'animalTail', slot: 'tail',
444
+ anchorX: 0, anchorY: 2, zOrder: 2, tags: ['fluffy', 'fox', 'wolf'],
445
+ pixels: { S: TAIL_FLUFFY },
446
+ recolorableIndices: [0, 1],
447
+ },
448
+ {
449
+ id: 'animal-tail-dragon', name: 'Dragon Tail', category: 'animalTail', slot: 'tail',
450
+ anchorX: 0, anchorY: 1, zOrder: 2, tags: ['dragon', 'spiked'],
451
+ pixels: { S: TAIL_DRAGON },
452
+ recolorableIndices: [0, 1],
453
+ },
454
+ {
455
+ id: 'animal-tail-bird', name: 'Bird Tail', category: 'animalTail', slot: 'tail',
456
+ anchorX: 2, anchorY: 0, zOrder: 2, tags: ['bird', 'feather'],
457
+ pixels: { S: TAIL_BIRD },
458
+ recolorableIndices: [0, 1],
459
+ },
460
+ // ── Wings ──
461
+ {
462
+ id: 'animal-wing-small', name: 'Small Wing', category: 'animalWing', slot: 'wing',
463
+ anchorX: 0, anchorY: 4, zOrder: 8, tags: ['small', 'bird'],
464
+ pixels: { S: WING_SMALL },
465
+ recolorableIndices: [0, 1],
466
+ },
467
+ {
468
+ id: 'animal-wing-large', name: 'Large Wing', category: 'animalWing', slot: 'wing',
469
+ anchorX: 0, anchorY: 7, zOrder: 8, tags: ['large', 'dragon'],
470
+ pixels: { S: WING_LARGE },
471
+ recolorableIndices: [0, 1],
472
+ },
473
+ {
474
+ id: 'animal-wing-bat', name: 'Bat Wing', category: 'animalWing', slot: 'wing',
475
+ anchorX: 0, anchorY: 6, zOrder: 8, tags: ['bat', 'dragon', 'dark'],
476
+ pixels: { S: WING_BAT },
477
+ recolorableIndices: [0, 1],
478
+ },
479
+ // ── Manes ──
480
+ {
481
+ id: 'animal-mane-short', name: 'Short Mane', category: 'animalMane', slot: 'mane',
482
+ anchorX: 3, anchorY: 0, zOrder: 9, tags: ['short', 'horse'],
483
+ pixels: { S: MANE_SHORT },
484
+ recolorableIndices: [0, 1],
485
+ },
486
+ {
487
+ id: 'animal-mane-long', name: 'Long Mane', category: 'animalMane', slot: 'mane',
488
+ anchorX: 3, anchorY: 0, zOrder: 9, tags: ['long', 'lion', 'horse'],
489
+ pixels: { S: MANE_LONG },
490
+ recolorableIndices: [0, 1],
491
+ },
492
+ // ── Horns ──
493
+ {
494
+ id: 'animal-horns-small', name: 'Small Horns', category: 'animalHead', slot: 'head',
495
+ anchorX: 4, anchorY: 2, zOrder: 12, tags: ['horns', 'small', 'goat'],
496
+ pixels: { S: HORNS_SMALL },
497
+ recolorableIndices: [0, 1],
498
+ },
499
+ {
500
+ id: 'animal-horns-dragon', name: 'Dragon Horns', category: 'animalHead', slot: 'head',
501
+ anchorX: 5, anchorY: 3, zOrder: 12, tags: ['horns', 'dragon', 'large'],
502
+ pixels: { S: HORNS_DRAGON },
503
+ recolorableIndices: [0, 1],
504
+ },
505
+ ];
506
+ function animalAssembly(name, parts, w = 32, h = 32) {
507
+ return {
508
+ id: `animal-${name.toLowerCase().replace(/\s+/g, '-')}`,
509
+ name,
510
+ parts,
511
+ skeletonId: 'quadruped',
512
+ canvasWidth: w,
513
+ canvasHeight: h,
514
+ projection: 'sideView',
515
+ };
516
+ }
517
+ const ANIMAL_PRESETS = [
518
+ {
519
+ id: 'preset-cat', name: 'Cat', description: 'Small domestic cat',
520
+ tags: ['cat', 'pet', 'small'],
521
+ assembly: animalAssembly('Cat', [
522
+ { partId: 'animal-leg-thin', offsetX: 8, offsetY: 22 },
523
+ { partId: 'animal-leg-thin', offsetX: 12, offsetY: 22 },
524
+ { partId: 'animal-leg-thin', offsetX: 18, offsetY: 22 },
525
+ { partId: 'animal-leg-thin', offsetX: 22, offsetY: 22 },
526
+ { partId: 'animal-body-small', offsetX: 10, offsetY: 16 },
527
+ { partId: 'animal-head-cat', offsetX: 6, offsetY: 9 },
528
+ { partId: 'animal-tail-short', offsetX: 22, offsetY: 15 },
529
+ ]),
530
+ },
531
+ {
532
+ id: 'preset-dog', name: 'Dog', description: 'Medium-sized dog',
533
+ tags: ['dog', 'pet', 'medium'],
534
+ assembly: animalAssembly('Dog', [
535
+ { partId: 'animal-leg-thin', offsetX: 6, offsetY: 22 },
536
+ { partId: 'animal-leg-thin', offsetX: 10, offsetY: 22 },
537
+ { partId: 'animal-leg-thin', offsetX: 18, offsetY: 22 },
538
+ { partId: 'animal-leg-thin', offsetX: 22, offsetY: 22 },
539
+ { partId: 'animal-body-medium', offsetX: 6, offsetY: 14 },
540
+ { partId: 'animal-head-dog', offsetX: 2, offsetY: 6 },
541
+ { partId: 'animal-tail-long', offsetX: 22, offsetY: 13 },
542
+ ]),
543
+ },
544
+ {
545
+ id: 'preset-wolf', name: 'Wolf', description: 'Wild wolf with fluffy tail',
546
+ tags: ['wolf', 'wild', 'predator'],
547
+ assembly: animalAssembly('Wolf', [
548
+ { partId: 'animal-leg-thin', offsetX: 5, offsetY: 22 },
549
+ { partId: 'animal-leg-thin', offsetX: 9, offsetY: 22 },
550
+ { partId: 'animal-leg-thin', offsetX: 18, offsetY: 22 },
551
+ { partId: 'animal-leg-thin', offsetX: 22, offsetY: 22 },
552
+ { partId: 'animal-body-medium', offsetX: 5, offsetY: 14 },
553
+ { partId: 'animal-head-wolf', offsetX: 1, offsetY: 6 },
554
+ { partId: 'animal-tail-fluffy', offsetX: 22, offsetY: 12 },
555
+ ]),
556
+ },
557
+ {
558
+ id: 'preset-bird', name: 'Bird', description: 'Small bird with wings',
559
+ tags: ['bird', 'flying', 'small'],
560
+ assembly: animalAssembly('Bird', [
561
+ { partId: 'animal-leg-bird', offsetX: 12, offsetY: 24 },
562
+ { partId: 'animal-leg-bird', offsetX: 16, offsetY: 24 },
563
+ { partId: 'animal-body-bird', offsetX: 10, offsetY: 17 },
564
+ { partId: 'animal-head-bird', offsetX: 9, offsetY: 11 },
565
+ { partId: 'animal-wing-small', offsetX: 18, offsetY: 14 },
566
+ { partId: 'animal-tail-bird', offsetX: 6, offsetY: 19 },
567
+ ]),
568
+ },
569
+ {
570
+ id: 'preset-dragon', name: 'Dragon', description: 'Fire-breathing dragon with wings',
571
+ tags: ['dragon', 'fantasy', 'large'],
572
+ assembly: animalAssembly('Dragon', [
573
+ { partId: 'animal-leg-dragon', offsetX: 4, offsetY: 24 },
574
+ { partId: 'animal-leg-dragon', offsetX: 9, offsetY: 24 },
575
+ { partId: 'animal-leg-dragon', offsetX: 18, offsetY: 24 },
576
+ { partId: 'animal-leg-dragon', offsetX: 23, offsetY: 24 },
577
+ { partId: 'animal-body-dragon', offsetX: 4, offsetY: 14 },
578
+ { partId: 'animal-head-dragon', offsetX: 0, offsetY: 4 },
579
+ { partId: 'animal-horns-dragon', offsetX: 0, offsetY: 1 },
580
+ { partId: 'animal-wing-large', offsetX: 18, offsetY: 4 },
581
+ { partId: 'animal-tail-dragon', offsetX: 22, offsetY: 18 },
582
+ ], 32, 32),
583
+ },
584
+ {
585
+ id: 'preset-rabbit', name: 'Rabbit', description: 'Small fluffy rabbit',
586
+ tags: ['rabbit', 'pet', 'small'],
587
+ assembly: animalAssembly('Rabbit', [
588
+ { partId: 'animal-leg-thin', offsetX: 10, offsetY: 24 },
589
+ { partId: 'animal-leg-thin', offsetX: 14, offsetY: 24 },
590
+ { partId: 'animal-leg-thin', offsetX: 18, offsetY: 24 },
591
+ { partId: 'animal-leg-thin', offsetX: 22, offsetY: 24 },
592
+ { partId: 'animal-body-small', offsetX: 10, offsetY: 18 },
593
+ { partId: 'animal-head-rabbit', offsetX: 6, offsetY: 8 },
594
+ { partId: 'animal-tail-short', offsetX: 22, offsetY: 18 },
595
+ ]),
596
+ },
597
+ {
598
+ id: 'preset-bear', name: 'Bear', description: 'Large bear',
599
+ tags: ['bear', 'wild', 'large'],
600
+ assembly: animalAssembly('Bear', [
601
+ { partId: 'animal-leg-thick', offsetX: 4, offsetY: 22 },
602
+ { partId: 'animal-leg-thick', offsetX: 9, offsetY: 22 },
603
+ { partId: 'animal-leg-thick', offsetX: 18, offsetY: 22 },
604
+ { partId: 'animal-leg-thick', offsetX: 23, offsetY: 22 },
605
+ { partId: 'animal-body-large', offsetX: 3, offsetY: 12 },
606
+ { partId: 'animal-head-bear', offsetX: 0, offsetY: 3 },
607
+ { partId: 'animal-tail-short', offsetX: 22, offsetY: 14 },
608
+ ]),
609
+ },
610
+ {
611
+ id: 'preset-horse', name: 'Horse', description: 'Horse with mane',
612
+ tags: ['horse', 'rideable', 'large'],
613
+ assembly: animalAssembly('Horse', [
614
+ { partId: 'animal-leg-thick', offsetX: 4, offsetY: 22 },
615
+ { partId: 'animal-leg-thick', offsetX: 9, offsetY: 22 },
616
+ { partId: 'animal-leg-thick', offsetX: 18, offsetY: 22 },
617
+ { partId: 'animal-leg-thick', offsetX: 23, offsetY: 22 },
618
+ { partId: 'animal-body-large', offsetX: 3, offsetY: 12 },
619
+ { partId: 'animal-head-horse', offsetX: 0, offsetY: 2 },
620
+ { partId: 'animal-mane-long', offsetX: 4, offsetY: 4 },
621
+ { partId: 'animal-tail-long', offsetX: 22, offsetY: 14 },
622
+ ]),
623
+ },
624
+ {
625
+ id: 'preset-phoenix', name: 'Phoenix', description: 'Mythical fire bird',
626
+ tags: ['phoenix', 'fantasy', 'bird', 'fire'],
627
+ assembly: animalAssembly('Phoenix', [
628
+ { partId: 'animal-leg-bird', offsetX: 12, offsetY: 24 },
629
+ { partId: 'animal-leg-bird', offsetX: 16, offsetY: 24 },
630
+ { partId: 'animal-body-bird', offsetX: 10, offsetY: 17,
631
+ colorOverrides: { 0: '#f06020', 1: '#c04010' } },
632
+ { partId: 'animal-head-bird', offsetX: 9, offsetY: 11,
633
+ colorOverrides: { 0: '#f06020', 1: '#c04010', 3: '#f0d060' } },
634
+ { partId: 'animal-wing-large', offsetX: 18, offsetY: 10,
635
+ colorOverrides: { 0: '#f0a020', 1: '#d06010' } },
636
+ { partId: 'animal-tail-bird', offsetX: 4, offsetY: 19,
637
+ colorOverrides: { 0: '#f07030', 1: '#d05020' } },
638
+ ]),
639
+ },
640
+ ];
641
+ /** Initialize: register all animal parts */
642
+ function initAnimalParts() {
643
+ registerParts(ANIMAL_PARTS);
644
+ }
645
+
646
+ export { ANIMAL_PARTS, ANIMAL_PRESETS, FEATHER_PALETTES, FUR_PALETTES, SCALE_PALETTES, initAnimalParts };
647
+ //# sourceMappingURL=animalGeneratorPresets.js.map