@guinetik/gcanvas 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/dist/gcanvas.es.js +25656 -0
  2. package/dist/gcanvas.es.min.js +1 -0
  3. package/dist/gcanvas.umd.js +1 -0
  4. package/dist/gcanvas.umd.min.js +1 -0
  5. package/package.json +23 -6
  6. package/src/game/objects/index.js +1 -0
  7. package/src/game/objects/spritesheet.js +260 -0
  8. package/src/game/ui/theme.js +6 -0
  9. package/src/io/keys.js +9 -1
  10. package/src/math/boolean.js +481 -0
  11. package/src/math/index.js +1 -0
  12. package/.github/workflows/release.yaml +0 -70
  13. package/.jshintrc +0 -4
  14. package/.vscode/settings.json +0 -22
  15. package/CLAUDE.md +0 -310
  16. package/blackhole.jpg +0 -0
  17. package/demo.png +0 -0
  18. package/demos/CNAME +0 -1
  19. package/demos/animations.html +0 -31
  20. package/demos/basic.html +0 -38
  21. package/demos/baskara.html +0 -31
  22. package/demos/bezier.html +0 -35
  23. package/demos/beziersignature.html +0 -29
  24. package/demos/blackhole.html +0 -28
  25. package/demos/blob.html +0 -35
  26. package/demos/coordinates.html +0 -698
  27. package/demos/cube3d.html +0 -23
  28. package/demos/demos.css +0 -303
  29. package/demos/dino.html +0 -42
  30. package/demos/easing.html +0 -28
  31. package/demos/events.html +0 -195
  32. package/demos/fluent.html +0 -647
  33. package/demos/fluid-simple.html +0 -22
  34. package/demos/fluid.html +0 -37
  35. package/demos/fractals.html +0 -36
  36. package/demos/gameobjects.html +0 -626
  37. package/demos/genart.html +0 -26
  38. package/demos/gendream.html +0 -26
  39. package/demos/group.html +0 -36
  40. package/demos/home.html +0 -587
  41. package/demos/index.html +0 -376
  42. package/demos/isometric.html +0 -34
  43. package/demos/js/animations.js +0 -452
  44. package/demos/js/basic.js +0 -204
  45. package/demos/js/baskara.js +0 -751
  46. package/demos/js/bezier.js +0 -692
  47. package/demos/js/beziersignature.js +0 -241
  48. package/demos/js/blackhole/accretiondisk.obj.js +0 -379
  49. package/demos/js/blackhole/blackhole.obj.js +0 -318
  50. package/demos/js/blackhole/index.js +0 -409
  51. package/demos/js/blackhole/particle.js +0 -56
  52. package/demos/js/blackhole/starfield.obj.js +0 -218
  53. package/demos/js/blob.js +0 -2276
  54. package/demos/js/coordinates.js +0 -840
  55. package/demos/js/cube3d.js +0 -789
  56. package/demos/js/dino.js +0 -1420
  57. package/demos/js/easing.js +0 -477
  58. package/demos/js/fluent.js +0 -183
  59. package/demos/js/fluid-simple.js +0 -253
  60. package/demos/js/fluid.js +0 -527
  61. package/demos/js/fractals.js +0 -931
  62. package/demos/js/fractalworker.js +0 -93
  63. package/demos/js/gameobjects.js +0 -176
  64. package/demos/js/genart.js +0 -268
  65. package/demos/js/gendream.js +0 -209
  66. package/demos/js/group.js +0 -140
  67. package/demos/js/info-toggle.js +0 -25
  68. package/demos/js/isometric.js +0 -863
  69. package/demos/js/kerr.js +0 -1556
  70. package/demos/js/lavalamp.js +0 -590
  71. package/demos/js/layout.js +0 -354
  72. package/demos/js/mondrian.js +0 -285
  73. package/demos/js/opacity.js +0 -275
  74. package/demos/js/painter.js +0 -484
  75. package/demos/js/particles-showcase.js +0 -514
  76. package/demos/js/particles.js +0 -299
  77. package/demos/js/patterns.js +0 -397
  78. package/demos/js/penrose/artifact.js +0 -69
  79. package/demos/js/penrose/blackhole.js +0 -121
  80. package/demos/js/penrose/constants.js +0 -73
  81. package/demos/js/penrose/game.js +0 -943
  82. package/demos/js/penrose/lore.js +0 -278
  83. package/demos/js/penrose/penrosescene.js +0 -892
  84. package/demos/js/penrose/ship.js +0 -216
  85. package/demos/js/penrose/sounds.js +0 -211
  86. package/demos/js/penrose/voidparticle.js +0 -55
  87. package/demos/js/penrose/voidscene.js +0 -258
  88. package/demos/js/penrose/voidship.js +0 -144
  89. package/demos/js/penrose/wormhole.js +0 -46
  90. package/demos/js/pipeline.js +0 -555
  91. package/demos/js/plane3d.js +0 -256
  92. package/demos/js/platformer.js +0 -1579
  93. package/demos/js/scene.js +0 -304
  94. package/demos/js/scenes.js +0 -320
  95. package/demos/js/schrodinger.js +0 -410
  96. package/demos/js/schwarzschild.js +0 -1023
  97. package/demos/js/shapes.js +0 -628
  98. package/demos/js/space/alien.js +0 -171
  99. package/demos/js/space/boom.js +0 -98
  100. package/demos/js/space/boss.js +0 -353
  101. package/demos/js/space/buff.js +0 -73
  102. package/demos/js/space/bullet.js +0 -102
  103. package/demos/js/space/constants.js +0 -85
  104. package/demos/js/space/game.js +0 -1884
  105. package/demos/js/space/hud.js +0 -112
  106. package/demos/js/space/laserbeam.js +0 -179
  107. package/demos/js/space/lightning.js +0 -277
  108. package/demos/js/space/minion.js +0 -192
  109. package/demos/js/space/missile.js +0 -212
  110. package/demos/js/space/player.js +0 -430
  111. package/demos/js/space/powerup.js +0 -90
  112. package/demos/js/space/starfield.js +0 -58
  113. package/demos/js/space/starpower.js +0 -90
  114. package/demos/js/spacetime.js +0 -559
  115. package/demos/js/sphere3d.js +0 -229
  116. package/demos/js/sprite.js +0 -473
  117. package/demos/js/svgtween.js +0 -204
  118. package/demos/js/tde/accretiondisk.js +0 -471
  119. package/demos/js/tde/blackhole.js +0 -219
  120. package/demos/js/tde/blackholescene.js +0 -209
  121. package/demos/js/tde/config.js +0 -59
  122. package/demos/js/tde/index.js +0 -820
  123. package/demos/js/tde/jets.js +0 -290
  124. package/demos/js/tde/lensedstarfield.js +0 -154
  125. package/demos/js/tde/tdestar.js +0 -297
  126. package/demos/js/tde/tidalstream.js +0 -372
  127. package/demos/js/tde_old/blackhole.obj.js +0 -354
  128. package/demos/js/tde_old/debris.obj.js +0 -791
  129. package/demos/js/tde_old/flare.obj.js +0 -239
  130. package/demos/js/tde_old/index.js +0 -448
  131. package/demos/js/tde_old/star.obj.js +0 -812
  132. package/demos/js/tiles.js +0 -312
  133. package/demos/js/tweendemo.js +0 -79
  134. package/demos/js/visibility.js +0 -102
  135. package/demos/kerr.html +0 -28
  136. package/demos/lavalamp.html +0 -27
  137. package/demos/layouts.html +0 -37
  138. package/demos/logo.svg +0 -4
  139. package/demos/loop.html +0 -84
  140. package/demos/mondrian.html +0 -32
  141. package/demos/og_image.png +0 -0
  142. package/demos/opacity.html +0 -36
  143. package/demos/painter.html +0 -39
  144. package/demos/particles-showcase.html +0 -28
  145. package/demos/particles.html +0 -24
  146. package/demos/patterns.html +0 -33
  147. package/demos/penrose-game.html +0 -31
  148. package/demos/pipeline.html +0 -737
  149. package/demos/plane3d.html +0 -24
  150. package/demos/platformer.html +0 -43
  151. package/demos/scene.html +0 -33
  152. package/demos/scenes.html +0 -96
  153. package/demos/schrodinger.html +0 -27
  154. package/demos/schwarzschild.html +0 -27
  155. package/demos/shapes.html +0 -16
  156. package/demos/space.html +0 -85
  157. package/demos/spacetime.html +0 -27
  158. package/demos/sphere3d.html +0 -24
  159. package/demos/sprite.html +0 -18
  160. package/demos/svgtween.html +0 -29
  161. package/demos/tde.html +0 -28
  162. package/demos/tiles.html +0 -28
  163. package/demos/transforms.html +0 -400
  164. package/demos/tween.html +0 -45
  165. package/demos/visibility.html +0 -33
  166. package/docs/README.md +0 -230
  167. package/docs/api/FluidSystem.md +0 -173
  168. package/docs/concepts/architecture-overview.md +0 -204
  169. package/docs/concepts/coordinate-system.md +0 -384
  170. package/docs/concepts/lifecycle.md +0 -255
  171. package/docs/concepts/rendering-pipeline.md +0 -279
  172. package/docs/concepts/shapes-vs-gameobjects.md +0 -187
  173. package/docs/concepts/tde-zorder.md +0 -106
  174. package/docs/concepts/two-layer-architecture.md +0 -229
  175. package/docs/fluid-dynamics.md +0 -99
  176. package/docs/getting-started/first-game.md +0 -354
  177. package/docs/getting-started/hello-world.md +0 -269
  178. package/docs/getting-started/installation.md +0 -175
  179. package/docs/modules/collision/README.md +0 -453
  180. package/docs/modules/fluent/README.md +0 -1075
  181. package/docs/modules/game/README.md +0 -303
  182. package/docs/modules/isometric-camera.md +0 -210
  183. package/docs/modules/isometric.md +0 -275
  184. package/docs/modules/painter/README.md +0 -328
  185. package/docs/modules/particle/README.md +0 -559
  186. package/docs/modules/shapes/README.md +0 -221
  187. package/docs/modules/shapes/base/euclidian.md +0 -123
  188. package/docs/modules/shapes/base/geometry2d.md +0 -204
  189. package/docs/modules/shapes/base/renderable.md +0 -215
  190. package/docs/modules/shapes/base/shape.md +0 -262
  191. package/docs/modules/shapes/base/transformable.md +0 -243
  192. package/docs/modules/shapes/hierarchy.md +0 -218
  193. package/docs/modules/state/README.md +0 -577
  194. package/docs/modules/util/README.md +0 -99
  195. package/docs/modules/util/camera3d.md +0 -412
  196. package/docs/modules/util/scene3d.md +0 -395
  197. package/index.html +0 -17
  198. package/jsdoc.json +0 -50
  199. package/scripts/build-demo.js +0 -69
  200. package/scripts/bundle4llm.js +0 -276
  201. package/scripts/clearconsole.js +0 -48
  202. package/test/math/orbital.test.js +0 -61
  203. package/test/math/tensor.test.js +0 -114
  204. package/test/particle/emitter.test.js +0 -204
  205. package/test/particle/particle-system.test.js +0 -310
  206. package/test/particle/particle.test.js +0 -116
  207. package/test/particle/updaters.test.js +0 -386
  208. package/test/setup.js +0 -120
  209. package/test/shapes/euclidian.test.js +0 -44
  210. package/test/shapes/geometry.test.js +0 -86
  211. package/test/shapes/group.test.js +0 -86
  212. package/test/shapes/rectangle.test.js +0 -64
  213. package/test/shapes/transform.test.js +0 -379
  214. package/test/util/camera3d.test.js +0 -428
  215. package/test/util/scene3d.test.js +0 -352
  216. package/vite.config.js +0 -50
  217. package/vitest.config.js +0 -13
@@ -1,215 +0,0 @@
1
- # Renderable
2
-
3
- > Visibility, opacity, shadows, and the render lifecycle.
4
-
5
- **Module:** [shapes](../README.md) | **Extends:** `Traceable` | **Source:** `src/shapes/renderable.js`
6
-
7
- ## Overview
8
-
9
- Renderable introduces the core rendering lifecycle. It knows when to draw, how to draw, and when **not** to draw (invisible, opacity = 0).
10
-
11
- This class adds:
12
- - **Rendering lifecycle control** (`render()`)
13
- - **Canvas state management** (save/restore)
14
- - **Visual properties** (opacity, visibility)
15
- - **Shadow styling** support
16
-
17
- ## Constructor
18
-
19
- ```js
20
- new Renderable(options)
21
- ```
22
-
23
- ### Options
24
-
25
- | Option | Type | Default | Description |
26
- |--------|------|---------|-------------|
27
- | `visible` | `boolean` | `true` | Whether to draw this object |
28
- | `opacity` | `number` | `1` | Alpha transparency (0–1) |
29
- | `active` | `boolean` | `true` | Whether to receive updates |
30
- | `zIndex` | `number` | `0` | Stacking order |
31
- | `blendMode` | `string` | `"source-over"` | Canvas composite operation |
32
- | `shadowColor` | `string` | `undefined` | Shadow color |
33
- | `shadowBlur` | `number` | `0` | Shadow blur radius |
34
- | `shadowOffsetX` | `number` | `0` | Shadow X offset |
35
- | `shadowOffsetY` | `number` | `0` | Shadow Y offset |
36
-
37
- Plus all options from [Geometry2d](./geometry2d.md).
38
-
39
- ## Properties
40
-
41
- ### Inherited
42
-
43
- From Euclidian: `x`, `y`, `width`, `height`, `debug`, `debugColor`
44
-
45
- From Geometry2d: `minX`, `maxX`, `minY`, `maxY`, `crisp`, `boundsDirty`
46
-
47
- ### Own Properties
48
-
49
- | Property | Type | Description |
50
- |----------|------|-------------|
51
- | `visible` | `boolean` | Show/hide the object |
52
- | `opacity` | `number` | Transparency (0 = invisible, 1 = opaque) |
53
- | `active` | `boolean` | Whether to call `update()` |
54
- | `zIndex` | `number` | Stacking order (higher = on top) |
55
- | `shadowColor` | `string \| undefined` | CSS color for shadow |
56
- | `shadowBlur` | `number` | Shadow blur radius in pixels |
57
- | `shadowOffsetX` | `number` | Horizontal shadow offset |
58
- | `shadowOffsetY` | `number` | Vertical shadow offset |
59
- | `tick` | `number` | Total time object has been alive (readonly) |
60
-
61
- ## Methods
62
-
63
- ### render()
64
-
65
- Main rendering lifecycle method. Handles canvas state, applies effects, and calls `draw()`.
66
-
67
- ```js
68
- shape.render();
69
- ```
70
-
71
- **Render flow:**
72
-
73
- ```
74
- render()
75
- ├── Check visible && opacity > 0
76
- ├── Painter.save()
77
- ├── Set blend mode
78
- ├── Push opacity
79
- ├── Translate to (x, y)
80
- ├── Apply shadows
81
- ├── draw() ← subclass implements this
82
- ├── Pop opacity
83
- └── Painter.restore()
84
- ```
85
-
86
- ### draw()
87
-
88
- Called by `render()` to do actual drawing. Override in subclasses.
89
-
90
- ```js
91
- class MyShape extends Renderable {
92
- draw() {
93
- // Custom drawing logic
94
- Painter.shapes.fillCircle(0, 0, 50, 'red');
95
- }
96
- }
97
- ```
98
-
99
- ### update(dt)
100
-
101
- Called once per frame if the object is active.
102
-
103
- ```js
104
- shape.update(0.016); // dt in seconds
105
-
106
- // Override in subclasses
107
- update(dt) {
108
- this.x += 100 * dt; // Move 100 pixels per second
109
- super.update(dt);
110
- }
111
- ```
112
-
113
- **Parameters:**
114
- - `dt` (`number`): Time since last frame in seconds
115
-
116
- ### applyShadow(ctx)
117
-
118
- Applies shadow styles to the canvas context.
119
-
120
- ```js
121
- shape.applyShadow(Painter.ctx);
122
- ```
123
-
124
- ## Visibility Control
125
-
126
- ```js
127
- // Hide the shape (won't render)
128
- shape.visible = false;
129
-
130
- // Show the shape
131
- shape.visible = true;
132
-
133
- // Make semi-transparent
134
- shape.opacity = 0.5;
135
-
136
- // Fully transparent (same as invisible)
137
- shape.opacity = 0;
138
- ```
139
-
140
- ## Shadow Effects
141
-
142
- ```js
143
- const shape = new Circle(50, {
144
- x: 200,
145
- y: 200,
146
- color: '#4ecdc4',
147
- shadowColor: 'rgba(0,0,0,0.5)',
148
- shadowBlur: 15,
149
- shadowOffsetX: 5,
150
- shadowOffsetY: 5
151
- });
152
- ```
153
-
154
- ## Z-Index Ordering
155
-
156
- Objects are rendered in z-index order (low to high):
157
-
158
- ```js
159
- const background = new Rectangle({ zIndex: 0 });
160
- const player = new Circle({ zIndex: 10 });
161
- const ui = new Rectangle({ zIndex: 100 });
162
-
163
- // Render order: background → player → ui
164
- ```
165
-
166
- ## Active vs Visible
167
-
168
- | Property | Effect |
169
- |----------|--------|
170
- | `visible = false` | Skips `render()`, still calls `update()` |
171
- | `active = false` | Skips `update()`, still calls `render()` |
172
- | Both `false` | Object is completely dormant |
173
-
174
- ```js
175
- // Pause updates but keep drawing
176
- shape.active = false;
177
-
178
- // Pause everything
179
- shape.active = false;
180
- shape.visible = false;
181
- ```
182
-
183
- ## Blend Modes
184
-
185
- GCanvas supports standard canvas composite operations:
186
-
187
- ```js
188
- shape.blendMode = 'multiply';
189
- shape.blendMode = 'screen';
190
- shape.blendMode = 'overlay';
191
- // etc.
192
- ```
193
-
194
- Common values: `source-over` (default), `multiply`, `screen`, `overlay`, `darken`, `lighten`
195
-
196
- ## Inheritance
197
-
198
- ```
199
- Geometry2d
200
- └── Traceable
201
- └── Renderable <── You are here
202
- └── Transformable
203
- └── Shape
204
- ```
205
-
206
- ## Related
207
-
208
- - [Geometry2d](./geometry2d.md) - Parent class
209
- - [Transformable](./transformable.md) - Adds rotation/scale
210
- - [Shape Hierarchy](../hierarchy.md) - Full inheritance diagram
211
-
212
- ## See Also
213
-
214
- - [Shapes Module](../README.md)
215
- - [Game Lifecycle](../../../concepts/lifecycle.md) - Update/render cycle
@@ -1,262 +0,0 @@
1
- # Shape
2
-
3
- > Fill color, stroke, and line styling for drawable primitives.
4
-
5
- **Module:** [shapes](../README.md) | **Extends:** [Transformable](./transformable.md) | **Source:** `src/shapes/shape.js`
6
-
7
- ## Overview
8
-
9
- Shape is the base class for all drawable geometric primitives. It's the first class in the hierarchy to express **canvas styling intent**:
10
-
11
- - Fill & stroke colors
12
- - Line width & join styles
13
- - Line cap styles
14
-
15
- Shape does not define geometry — that's up to subclasses like Circle, Rectangle, etc.
16
-
17
- ## Constructor
18
-
19
- ```js
20
- new Shape(options)
21
- ```
22
-
23
- ### Options
24
-
25
- | Option | Type | Default | Description |
26
- |--------|------|---------|-------------|
27
- | `color` | `string \| null` | `null` | Fill color (CSS color) |
28
- | `stroke` | `string \| null` | `null` | Stroke color (CSS color) |
29
- | `lineWidth` | `number` | `1` | Stroke width in pixels |
30
- | `lineJoin` | `string` | `"miter"` | Line join style |
31
- | `lineCap` | `string` | `"butt"` | Line cap style |
32
- | `miterLimit` | `number` | `10` | Maximum miter length |
33
-
34
- Plus all options from [Transformable](./transformable.md).
35
-
36
- ## Properties
37
-
38
- ### Inherited
39
-
40
- From Euclidian: `x`, `y`, `width`, `height`, `debug`, `debugColor`
41
-
42
- From Geometry2d: `minX`, `maxX`, `minY`, `maxY`, `crisp`
43
-
44
- From Renderable: `visible`, `opacity`, `active`, `zIndex`, `shadowColor`, `shadowBlur`, `shadowOffsetX`, `shadowOffsetY`
45
-
46
- From Transformable: `rotation`, `scaleX`, `scaleY`
47
-
48
- ### Own Properties
49
-
50
- | Property | Type | Description |
51
- |----------|------|-------------|
52
- | `color` | `string \| null` | Fill color (CSS color string) |
53
- | `stroke` | `string \| null` | Stroke color (CSS color string) |
54
- | `lineWidth` | `number` | Width of stroke in pixels |
55
- | `lineJoin` | `"miter" \| "round" \| "bevel"` | Line join style |
56
- | `lineCap` | `"butt" \| "round" \| "square"` | Line cap style |
57
- | `miterLimit` | `number` | Maximum miter length before bevel |
58
-
59
- ## Fill and Stroke
60
-
61
- ```js
62
- // Fill only
63
- const filled = new Circle(50, {
64
- color: 'red'
65
- });
66
-
67
- // Stroke only
68
- const outlined = new Circle(50, {
69
- stroke: 'blue',
70
- lineWidth: 2
71
- });
72
-
73
- // Both fill and stroke
74
- const both = new Circle(50, {
75
- color: 'red',
76
- stroke: 'black',
77
- lineWidth: 2
78
- });
79
- ```
80
-
81
- ## Color Formats
82
-
83
- Any valid CSS color string:
84
-
85
- ```js
86
- shape.color = 'red'; // Named color
87
- shape.color = '#ff0000'; // Hex
88
- shape.color = '#f00'; // Short hex
89
- shape.color = 'rgb(255, 0, 0)'; // RGB
90
- shape.color = 'rgba(255, 0, 0, 0.5)'; // RGBA
91
- shape.color = 'hsl(0, 100%, 50%)'; // HSL
92
- ```
93
-
94
- ## Line Join Styles
95
-
96
- Controls how lines meet at corners:
97
-
98
- ```js
99
- shape.lineJoin = 'miter'; // Sharp corners (default)
100
- shape.lineJoin = 'round'; // Rounded corners
101
- shape.lineJoin = 'bevel'; // Beveled corners
102
- ```
103
-
104
- ```
105
- miter round bevel
106
- ╱ ╱ ╱
107
- ╱ ╱ ╱
108
- ──┼── ──╲── ──┘──
109
- ╲ ╲ ╲
110
- ╲ ╲ ╲
111
- ```
112
-
113
- ## Line Cap Styles
114
-
115
- Controls how line endpoints look:
116
-
117
- ```js
118
- shape.lineCap = 'butt'; // Flat end at endpoint (default)
119
- shape.lineCap = 'round'; // Rounded end
120
- shape.lineCap = 'square'; // Square end extending past endpoint
121
- ```
122
-
123
- ```
124
- butt round square
125
- │ │ │
126
- ───┤ ───● ───┤
127
- │ │ │
128
- ```
129
-
130
- ## Miter Limit
131
-
132
- When `lineJoin` is `"miter"`, very sharp angles can create very long miter points. `miterLimit` caps this:
133
-
134
- ```js
135
- shape.lineJoin = 'miter';
136
- shape.miterLimit = 10; // Default, reasonable for most cases
137
- shape.miterLimit = 2; // Shorter miters, more beveling
138
- ```
139
-
140
- ## Subclassing
141
-
142
- Shape is abstract. Subclasses implement `draw()`:
143
-
144
- ```js
145
- import { Shape, Painter } from '@guinetik/gcanvas';
146
-
147
- class CustomShape extends Shape {
148
- constructor(options = {}) {
149
- super(options);
150
- // Custom initialization
151
- }
152
-
153
- draw() {
154
- super.draw(); // Apply transforms
155
-
156
- // Use this.color, this.stroke, this.lineWidth, etc.
157
- if (this.color) {
158
- Painter.colors.fill(this.color);
159
- // Custom fill drawing
160
- }
161
-
162
- if (this.stroke) {
163
- Painter.colors.stroke(this.stroke, this.lineWidth);
164
- // Custom stroke drawing
165
- }
166
- }
167
- }
168
- ```
169
-
170
- ## Concrete Shape Classes
171
-
172
- These classes extend Shape:
173
-
174
- | Class | Description |
175
- |-------|-------------|
176
- | `Circle` | Circle with radius |
177
- | `Rectangle` | Centered rectangle |
178
- | `Triangle` | Three-sided polygon |
179
- | `Star` | Star with n points |
180
- | `Polygon` | N-sided polygon |
181
- | `Line` | Line segment |
182
- | `Arc` | Curved arc |
183
- | `Heart` | Heart shape |
184
- | `Diamond` | Diamond/rhombus |
185
- | ... | And many more |
186
-
187
- ## Example
188
-
189
- ```js
190
- import { Rectangle, Painter } from '@guinetik/gcanvas';
191
-
192
- const rect = new Rectangle({
193
- x: 200,
194
- y: 150,
195
- width: 100,
196
- height: 60,
197
- color: '#4ecdc4',
198
- stroke: '#2a9d8f',
199
- lineWidth: 3,
200
- lineJoin: 'round'
201
- });
202
-
203
- rect.draw();
204
- ```
205
-
206
- ## Complete Property Example
207
-
208
- ```js
209
- const shape = new Circle(50, {
210
- // Position (Euclidian)
211
- x: 400,
212
- y: 300,
213
-
214
- // Constraints (Geometry2d)
215
- minX: 50,
216
- maxX: 750,
217
-
218
- // Visibility (Renderable)
219
- visible: true,
220
- opacity: 0.9,
221
- shadowColor: 'rgba(0,0,0,0.3)',
222
- shadowBlur: 10,
223
- shadowOffsetX: 5,
224
- shadowOffsetY: 5,
225
-
226
- // Transforms (Transformable)
227
- rotation: 0,
228
- scaleX: 1,
229
- scaleY: 1,
230
-
231
- // Styling (Shape)
232
- color: '#ff6b6b',
233
- stroke: '#c92a2a',
234
- lineWidth: 2,
235
- lineJoin: 'round',
236
- lineCap: 'round'
237
- });
238
- ```
239
-
240
- ## Inheritance
241
-
242
- ```
243
- Transformable
244
- └── Shape <── You are here
245
- ├── Circle
246
- ├── Rectangle
247
- ├── Triangle
248
- ├── Star
249
- ├── Polygon
250
- └── ... (40+ shapes)
251
- ```
252
-
253
- ## Related
254
-
255
- - [Transformable](./transformable.md) - Parent class
256
- - [Shape Hierarchy](../hierarchy.md) - Full inheritance diagram
257
- - [Shapes Module](../README.md) - All available shapes
258
-
259
- ## See Also
260
-
261
- - [Rendering Pipeline](../../../concepts/rendering-pipeline.md)
262
- - [Hello World](../../../getting-started/hello-world.md)
@@ -1,243 +0,0 @@
1
- # Transformable
2
-
3
- > Rotation and scaling with transformed bounding boxes.
4
-
5
- **Module:** [shapes](../README.md) | **Extends:** [Renderable](./renderable.md) | **Source:** `src/shapes/transformable.js`
6
-
7
- ## Overview
8
-
9
- Transformable adds canvas transformation support:
10
- - **Rotation** in degrees
11
- - **Scaling** (horizontal and vertical)
12
- - **Transformed bounds** calculation
13
-
14
- This is the final base layer before custom shape styling is introduced.
15
-
16
- ## Constructor
17
-
18
- ```js
19
- new Transformable(options)
20
- ```
21
-
22
- ### Options
23
-
24
- | Option | Type | Default | Description |
25
- |--------|------|---------|-------------|
26
- | `rotation` | `number` | `0` | Rotation in degrees (clockwise) |
27
- | `scaleX` | `number` | `1` | Horizontal scale factor |
28
- | `scaleY` | `number` | `1` | Vertical scale factor |
29
-
30
- Plus all options from [Renderable](./renderable.md).
31
-
32
- ## Properties
33
-
34
- ### Inherited
35
-
36
- From Euclidian: `x`, `y`, `width`, `height`, `debug`, `debugColor`
37
-
38
- From Geometry2d: `minX`, `maxX`, `minY`, `maxY`, `crisp`, `boundsDirty`
39
-
40
- From Renderable: `visible`, `opacity`, `active`, `zIndex`, `shadowColor`, `shadowBlur`, `shadowOffsetX`, `shadowOffsetY`, `tick`
41
-
42
- ### Own Properties
43
-
44
- | Property | Type | Description |
45
- |----------|------|-------------|
46
- | `rotation` | `number` | Rotation angle in degrees |
47
- | `scaleX` | `number` | Horizontal scale (1 = normal) |
48
- | `scaleY` | `number` | Vertical scale (1 = normal) |
49
-
50
- ## Methods
51
-
52
- ### draw()
53
-
54
- Applies transforms before subclass drawing. Always call `super.draw()` in subclasses.
55
-
56
- ```js
57
- class MyShape extends Transformable {
58
- draw() {
59
- super.draw(); // Apply transforms
60
- // Custom drawing (in transformed space)
61
- }
62
- }
63
- ```
64
-
65
- ### applyTransforms()
66
-
67
- Applies rotation and scale to the canvas context. Called by `draw()`.
68
-
69
- ```js
70
- applyTransforms() {
71
- Painter.rotate(this._rotation);
72
- Painter.scale(this._scaleX, this._scaleY);
73
- }
74
- ```
75
-
76
- Transform order: **rotate → scale**
77
-
78
- ### calculateBounds()
79
-
80
- Returns the bounding box after applying rotation and scale.
81
-
82
- ```js
83
- const bounds = shape.getBounds();
84
- // Returns axis-aligned bounding box of the rotated/scaled shape
85
- ```
86
-
87
- ## Rotation
88
-
89
- Rotation is specified in **degrees** (converted to radians internally):
90
-
91
- ```js
92
- const shape = new Rectangle({
93
- width: 100,
94
- height: 50,
95
- rotation: 45 // 45 degrees clockwise
96
- });
97
-
98
- // Update rotation
99
- shape.rotation = 90; // 90 degrees
100
- shape.rotation = -30; // 30 degrees counter-clockwise
101
- ```
102
-
103
- ## Scaling
104
-
105
- Scale factors multiply the shape's dimensions:
106
-
107
- ```js
108
- const shape = new Circle(50, {
109
- scaleX: 2, // Twice as wide
110
- scaleY: 0.5 // Half as tall
111
- });
112
-
113
- // Result: ellipse 200 wide, 50 tall
114
- ```
115
-
116
- Common patterns:
117
-
118
- ```js
119
- // Uniform scale
120
- shape.scaleX = 2;
121
- shape.scaleY = 2; // 2x size in both dimensions
122
-
123
- // Flip horizontally
124
- shape.scaleX = -1;
125
-
126
- // Flip vertically
127
- shape.scaleY = -1;
128
- ```
129
-
130
- ## Transform Order
131
-
132
- Transforms are applied in this order:
133
-
134
- 1. **Translate** to (x, y) — from Renderable
135
- 2. **Rotate** by rotation angle
136
- 3. **Scale** by scaleX, scaleY
137
-
138
- ```js
139
- // Canvas transform stack:
140
- ctx.translate(x, y); // Move to position
141
- ctx.rotate(rotation); // Rotate around position
142
- ctx.scale(scaleX, scaleY); // Scale from position
143
- ```
144
-
145
- ## Transformed Bounds
146
-
147
- `getBounds()` returns the axis-aligned bounding box that contains the rotated/scaled shape:
148
-
149
- ```js
150
- const rect = new Rectangle({
151
- x: 100,
152
- y: 100,
153
- width: 100,
154
- height: 50,
155
- rotation: 45
156
- });
157
-
158
- const bounds = rect.getBounds();
159
- // Returns AABB that contains the rotated rectangle
160
- // bounds.width and bounds.height will be larger than original
161
- ```
162
-
163
- ```
164
- Original: Rotated 45°:
165
- ┌──────────┐ ◇
166
- │ │ ╱ ╲
167
- │ ● │ ╱ ╲
168
- │ │ ◇ ● ◇
169
- └──────────┘ ╲ ╱
170
- ╲ ╱
171
-
172
- ┌───────┐
173
- │ AABB │
174
- └───────┘
175
- ```
176
-
177
- ## Example: Spinning Shape
178
-
179
- ```js
180
- import { Rectangle, Painter } from '@guinetik/gcanvas';
181
-
182
- const canvas = document.getElementById('canvas');
183
- Painter.init(canvas.getContext('2d'));
184
-
185
- const rect = new Rectangle({
186
- x: 400,
187
- y: 300,
188
- width: 100,
189
- height: 60,
190
- color: '#4ecdc4'
191
- });
192
-
193
- function animate() {
194
- Painter.clear();
195
-
196
- // Rotate 1 degree per frame
197
- rect.rotation += 1;
198
-
199
- rect.draw();
200
- requestAnimationFrame(animate);
201
- }
202
-
203
- animate();
204
- ```
205
-
206
- ## Example: Pulsing Scale
207
-
208
- ```js
209
- let time = 0;
210
-
211
- function animate() {
212
- Painter.clear();
213
- time += 0.05;
214
-
215
- // Pulse between 0.8x and 1.2x
216
- const scale = 1 + Math.sin(time) * 0.2;
217
- shape.scaleX = scale;
218
- shape.scaleY = scale;
219
-
220
- shape.draw();
221
- requestAnimationFrame(animate);
222
- }
223
- ```
224
-
225
- ## Inheritance
226
-
227
- ```
228
- Renderable
229
- └── Transformable <── You are here
230
- └── Shape
231
- └── Circle, Rectangle, Star, ...
232
- ```
233
-
234
- ## Related
235
-
236
- - [Renderable](./renderable.md) - Parent class
237
- - [Shape](./shape.md) - Adds fill/stroke styling
238
- - [Shape Hierarchy](../hierarchy.md) - Full inheritance diagram
239
-
240
- ## See Also
241
-
242
- - [Shapes Module](../README.md)
243
- - [Rendering Pipeline](../../../concepts/rendering-pipeline.md)