@guinetik/gcanvas 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/.github/workflows/release.yaml +70 -0
  2. package/.jshintrc +4 -0
  3. package/.vscode/settings.json +22 -0
  4. package/CLAUDE.md +310 -0
  5. package/blackhole.jpg +0 -0
  6. package/demo.png +0 -0
  7. package/demos/CNAME +1 -0
  8. package/demos/animations.html +31 -0
  9. package/demos/basic.html +38 -0
  10. package/demos/baskara.html +31 -0
  11. package/demos/bezier.html +35 -0
  12. package/demos/beziersignature.html +29 -0
  13. package/demos/blackhole.html +28 -0
  14. package/demos/blob.html +35 -0
  15. package/demos/demos.css +289 -0
  16. package/demos/easing.html +28 -0
  17. package/demos/events.html +195 -0
  18. package/demos/fluent.html +647 -0
  19. package/demos/fractals.html +36 -0
  20. package/demos/genart.html +26 -0
  21. package/demos/gendream.html +26 -0
  22. package/demos/group.html +36 -0
  23. package/demos/home.html +587 -0
  24. package/demos/index.html +364 -0
  25. package/demos/isometric.html +34 -0
  26. package/demos/js/animations.js +452 -0
  27. package/demos/js/basic.js +204 -0
  28. package/demos/js/baskara.js +751 -0
  29. package/demos/js/bezier.js +692 -0
  30. package/demos/js/beziersignature.js +241 -0
  31. package/demos/js/blackhole/accretiondisk.obj.js +379 -0
  32. package/demos/js/blackhole/blackhole.obj.js +318 -0
  33. package/demos/js/blackhole/index.js +409 -0
  34. package/demos/js/blackhole/particle.js +56 -0
  35. package/demos/js/blackhole/starfield.obj.js +218 -0
  36. package/demos/js/blob.js +2263 -0
  37. package/demos/js/easing.js +477 -0
  38. package/demos/js/fluent.js +183 -0
  39. package/demos/js/fractals.js +931 -0
  40. package/demos/js/fractalworker.js +93 -0
  41. package/demos/js/genart.js +268 -0
  42. package/demos/js/gendream.js +209 -0
  43. package/demos/js/group.js +140 -0
  44. package/demos/js/info-toggle.js +25 -0
  45. package/demos/js/isometric.js +863 -0
  46. package/demos/js/kerr.js +1556 -0
  47. package/demos/js/lavalamp.js +590 -0
  48. package/demos/js/layout.js +354 -0
  49. package/demos/js/mondrian.js +285 -0
  50. package/demos/js/opacity.js +275 -0
  51. package/demos/js/painter.js +484 -0
  52. package/demos/js/particles-showcase.js +514 -0
  53. package/demos/js/particles.js +299 -0
  54. package/demos/js/patterns.js +397 -0
  55. package/demos/js/penrose/artifact.js +69 -0
  56. package/demos/js/penrose/blackhole.js +121 -0
  57. package/demos/js/penrose/constants.js +73 -0
  58. package/demos/js/penrose/game.js +943 -0
  59. package/demos/js/penrose/lore.js +278 -0
  60. package/demos/js/penrose/penrosescene.js +892 -0
  61. package/demos/js/penrose/ship.js +216 -0
  62. package/demos/js/penrose/sounds.js +211 -0
  63. package/demos/js/penrose/voidparticle.js +55 -0
  64. package/demos/js/penrose/voidscene.js +258 -0
  65. package/demos/js/penrose/voidship.js +144 -0
  66. package/demos/js/penrose/wormhole.js +46 -0
  67. package/demos/js/pipeline.js +555 -0
  68. package/demos/js/scene.js +304 -0
  69. package/demos/js/scenes.js +320 -0
  70. package/demos/js/schrodinger.js +410 -0
  71. package/demos/js/schwarzschild.js +1023 -0
  72. package/demos/js/shapes.js +628 -0
  73. package/demos/js/space/alien.js +171 -0
  74. package/demos/js/space/boom.js +98 -0
  75. package/demos/js/space/boss.js +353 -0
  76. package/demos/js/space/buff.js +73 -0
  77. package/demos/js/space/bullet.js +102 -0
  78. package/demos/js/space/constants.js +85 -0
  79. package/demos/js/space/game.js +1884 -0
  80. package/demos/js/space/hud.js +112 -0
  81. package/demos/js/space/laserbeam.js +179 -0
  82. package/demos/js/space/lightning.js +277 -0
  83. package/demos/js/space/minion.js +192 -0
  84. package/demos/js/space/missile.js +212 -0
  85. package/demos/js/space/player.js +430 -0
  86. package/demos/js/space/powerup.js +90 -0
  87. package/demos/js/space/starfield.js +58 -0
  88. package/demos/js/space/starpower.js +90 -0
  89. package/demos/js/spacetime.js +559 -0
  90. package/demos/js/svgtween.js +204 -0
  91. package/demos/js/tde/accretiondisk.js +418 -0
  92. package/demos/js/tde/blackhole.js +219 -0
  93. package/demos/js/tde/blackholescene.js +209 -0
  94. package/demos/js/tde/config.js +59 -0
  95. package/demos/js/tde/index.js +695 -0
  96. package/demos/js/tde/jets.js +290 -0
  97. package/demos/js/tde/lensedstarfield.js +147 -0
  98. package/demos/js/tde/tdestar.js +317 -0
  99. package/demos/js/tde/tidalstream.js +356 -0
  100. package/demos/js/tde_old/blackhole.obj.js +354 -0
  101. package/demos/js/tde_old/debris.obj.js +791 -0
  102. package/demos/js/tde_old/flare.obj.js +239 -0
  103. package/demos/js/tde_old/index.js +448 -0
  104. package/demos/js/tde_old/star.obj.js +812 -0
  105. package/demos/js/tiles.js +312 -0
  106. package/demos/js/tweendemo.js +79 -0
  107. package/demos/js/visibility.js +102 -0
  108. package/demos/kerr.html +28 -0
  109. package/demos/lavalamp.html +27 -0
  110. package/demos/layouts.html +37 -0
  111. package/demos/logo.svg +4 -0
  112. package/demos/loop.html +84 -0
  113. package/demos/mondrian.html +32 -0
  114. package/demos/og_image.png +0 -0
  115. package/demos/opacity.html +36 -0
  116. package/demos/painter.html +39 -0
  117. package/demos/particles-showcase.html +28 -0
  118. package/demos/particles.html +24 -0
  119. package/demos/patterns.html +33 -0
  120. package/demos/penrose-game.html +31 -0
  121. package/demos/pipeline.html +737 -0
  122. package/demos/scene.html +33 -0
  123. package/demos/scenes.html +96 -0
  124. package/demos/schrodinger.html +27 -0
  125. package/demos/schwarzschild.html +27 -0
  126. package/demos/shapes.html +16 -0
  127. package/demos/space.html +85 -0
  128. package/demos/spacetime.html +27 -0
  129. package/demos/svgtween.html +29 -0
  130. package/demos/tde.html +28 -0
  131. package/demos/tiles.html +28 -0
  132. package/demos/transforms.html +400 -0
  133. package/demos/tween.html +45 -0
  134. package/demos/visibility.html +33 -0
  135. package/disk_example.png +0 -0
  136. package/docs/README.md +222 -0
  137. package/docs/concepts/architecture-overview.md +204 -0
  138. package/docs/concepts/lifecycle.md +255 -0
  139. package/docs/concepts/rendering-pipeline.md +279 -0
  140. package/docs/concepts/tde-zorder.md +106 -0
  141. package/docs/concepts/two-layer-architecture.md +229 -0
  142. package/docs/getting-started/first-game.md +354 -0
  143. package/docs/getting-started/hello-world.md +269 -0
  144. package/docs/getting-started/installation.md +157 -0
  145. package/docs/modules/collision/README.md +453 -0
  146. package/docs/modules/fluent/README.md +1075 -0
  147. package/docs/modules/game/README.md +303 -0
  148. package/docs/modules/isometric-camera.md +210 -0
  149. package/docs/modules/isometric.md +275 -0
  150. package/docs/modules/painter/README.md +328 -0
  151. package/docs/modules/particle/README.md +559 -0
  152. package/docs/modules/shapes/README.md +221 -0
  153. package/docs/modules/shapes/base/euclidian.md +123 -0
  154. package/docs/modules/shapes/base/geometry2d.md +204 -0
  155. package/docs/modules/shapes/base/renderable.md +215 -0
  156. package/docs/modules/shapes/base/shape.md +262 -0
  157. package/docs/modules/shapes/base/transformable.md +243 -0
  158. package/docs/modules/shapes/hierarchy.md +218 -0
  159. package/docs/modules/state/README.md +577 -0
  160. package/docs/modules/util/README.md +99 -0
  161. package/docs/modules/util/camera3d.md +412 -0
  162. package/docs/modules/util/scene3d.md +395 -0
  163. package/index.html +17 -0
  164. package/jsdoc.json +50 -0
  165. package/package.json +55 -0
  166. package/readme.md +599 -0
  167. package/scripts/build-demo.js +69 -0
  168. package/scripts/bundle4llm.js +276 -0
  169. package/scripts/clearconsole.js +48 -0
  170. package/src/collision/collision-system.js +332 -0
  171. package/src/collision/collision.js +303 -0
  172. package/src/collision/index.js +10 -0
  173. package/src/fluent/fluent-game.js +430 -0
  174. package/src/fluent/fluent-go.js +1060 -0
  175. package/src/fluent/fluent-layer.js +152 -0
  176. package/src/fluent/fluent-scene.js +291 -0
  177. package/src/fluent/index.js +98 -0
  178. package/src/fluent/sketch.js +380 -0
  179. package/src/game/game.js +467 -0
  180. package/src/game/index.js +49 -0
  181. package/src/game/objects/go.js +220 -0
  182. package/src/game/objects/imagego.js +30 -0
  183. package/src/game/objects/index.js +54 -0
  184. package/src/game/objects/isometric-scene.js +260 -0
  185. package/src/game/objects/layoutscene.js +549 -0
  186. package/src/game/objects/scene.js +175 -0
  187. package/src/game/objects/scene3d.js +118 -0
  188. package/src/game/objects/text.js +221 -0
  189. package/src/game/objects/wrapper.js +232 -0
  190. package/src/game/pipeline.js +243 -0
  191. package/src/game/ui/button.js +396 -0
  192. package/src/game/ui/cursor.js +93 -0
  193. package/src/game/ui/fps.js +91 -0
  194. package/src/game/ui/index.js +5 -0
  195. package/src/game/ui/togglebutton.js +93 -0
  196. package/src/game/ui/tooltip.js +249 -0
  197. package/src/index.js +25 -0
  198. package/src/io/events.js +20 -0
  199. package/src/io/index.js +86 -0
  200. package/src/io/input.js +70 -0
  201. package/src/io/keys.js +152 -0
  202. package/src/io/mouse.js +61 -0
  203. package/src/io/touch.js +39 -0
  204. package/src/logger/debugtab.js +138 -0
  205. package/src/logger/index.js +3 -0
  206. package/src/logger/loggable.js +47 -0
  207. package/src/logger/logger.js +113 -0
  208. package/src/math/complex.js +37 -0
  209. package/src/math/constants.js +1 -0
  210. package/src/math/fractal.js +1271 -0
  211. package/src/math/gr.js +201 -0
  212. package/src/math/heat.js +202 -0
  213. package/src/math/index.js +12 -0
  214. package/src/math/noise.js +433 -0
  215. package/src/math/orbital.js +191 -0
  216. package/src/math/patterns.js +1339 -0
  217. package/src/math/penrose.js +259 -0
  218. package/src/math/quantum.js +115 -0
  219. package/src/math/random.js +195 -0
  220. package/src/math/tensor.js +1009 -0
  221. package/src/mixins/anchor.js +131 -0
  222. package/src/mixins/draggable.js +72 -0
  223. package/src/mixins/index.js +2 -0
  224. package/src/motion/bezier.js +132 -0
  225. package/src/motion/bounce.js +58 -0
  226. package/src/motion/easing.js +349 -0
  227. package/src/motion/float.js +130 -0
  228. package/src/motion/follow.js +125 -0
  229. package/src/motion/hop.js +52 -0
  230. package/src/motion/index.js +82 -0
  231. package/src/motion/motion.js +1124 -0
  232. package/src/motion/orbit.js +49 -0
  233. package/src/motion/oscillate.js +39 -0
  234. package/src/motion/parabolic.js +141 -0
  235. package/src/motion/patrol.js +147 -0
  236. package/src/motion/pendulum.js +48 -0
  237. package/src/motion/pulse.js +88 -0
  238. package/src/motion/shake.js +83 -0
  239. package/src/motion/spiral.js +144 -0
  240. package/src/motion/spring.js +150 -0
  241. package/src/motion/swing.js +47 -0
  242. package/src/motion/tween.js +92 -0
  243. package/src/motion/tweenetik.js +139 -0
  244. package/src/motion/waypoint.js +210 -0
  245. package/src/painter/index.js +8 -0
  246. package/src/painter/painter.colors.js +331 -0
  247. package/src/painter/painter.effects.js +230 -0
  248. package/src/painter/painter.img.js +229 -0
  249. package/src/painter/painter.js +295 -0
  250. package/src/painter/painter.lines.js +189 -0
  251. package/src/painter/painter.opacity.js +41 -0
  252. package/src/painter/painter.shapes.js +277 -0
  253. package/src/painter/painter.text.js +273 -0
  254. package/src/particle/emitter.js +124 -0
  255. package/src/particle/index.js +11 -0
  256. package/src/particle/particle-system.js +322 -0
  257. package/src/particle/particle.js +71 -0
  258. package/src/particle/updaters.js +170 -0
  259. package/src/shapes/arc.js +43 -0
  260. package/src/shapes/arrow.js +33 -0
  261. package/src/shapes/bezier.js +42 -0
  262. package/src/shapes/circle.js +62 -0
  263. package/src/shapes/clouds.js +56 -0
  264. package/src/shapes/cone.js +219 -0
  265. package/src/shapes/cross.js +70 -0
  266. package/src/shapes/cube.js +244 -0
  267. package/src/shapes/cylinder.js +254 -0
  268. package/src/shapes/diamond.js +48 -0
  269. package/src/shapes/euclidian.js +111 -0
  270. package/src/shapes/figure.js +115 -0
  271. package/src/shapes/geometry.js +220 -0
  272. package/src/shapes/group.js +375 -0
  273. package/src/shapes/heart.js +42 -0
  274. package/src/shapes/hexagon.js +26 -0
  275. package/src/shapes/image.js +192 -0
  276. package/src/shapes/index.js +111 -0
  277. package/src/shapes/line.js +29 -0
  278. package/src/shapes/pattern.js +90 -0
  279. package/src/shapes/pin.js +44 -0
  280. package/src/shapes/poly.js +31 -0
  281. package/src/shapes/prism.js +226 -0
  282. package/src/shapes/rect.js +35 -0
  283. package/src/shapes/renderable.js +333 -0
  284. package/src/shapes/ring.js +26 -0
  285. package/src/shapes/roundrect.js +95 -0
  286. package/src/shapes/shape.js +117 -0
  287. package/src/shapes/slice.js +26 -0
  288. package/src/shapes/sphere.js +314 -0
  289. package/src/shapes/sphere3d.js +537 -0
  290. package/src/shapes/square.js +15 -0
  291. package/src/shapes/star.js +99 -0
  292. package/src/shapes/svg.js +408 -0
  293. package/src/shapes/text.js +553 -0
  294. package/src/shapes/traceable.js +83 -0
  295. package/src/shapes/transform.js +357 -0
  296. package/src/shapes/transformable.js +172 -0
  297. package/src/shapes/triangle.js +26 -0
  298. package/src/sound/index.js +17 -0
  299. package/src/sound/sound.js +473 -0
  300. package/src/sound/synth.analyzer.js +149 -0
  301. package/src/sound/synth.effects.js +207 -0
  302. package/src/sound/synth.envelope.js +59 -0
  303. package/src/sound/synth.js +229 -0
  304. package/src/sound/synth.musical.js +160 -0
  305. package/src/sound/synth.noise.js +85 -0
  306. package/src/sound/synth.oscillators.js +293 -0
  307. package/src/state/index.js +10 -0
  308. package/src/state/state-machine.js +371 -0
  309. package/src/util/camera3d.js +438 -0
  310. package/src/util/index.js +6 -0
  311. package/src/util/isometric-camera.js +235 -0
  312. package/src/util/layout.js +317 -0
  313. package/src/util/position.js +147 -0
  314. package/src/util/tasks.js +47 -0
  315. package/src/util/zindex.js +287 -0
  316. package/src/webgl/index.js +9 -0
  317. package/src/webgl/shaders/sphere-shaders.js +994 -0
  318. package/src/webgl/webgl-renderer.js +388 -0
  319. package/tde.png +0 -0
  320. package/test/math/orbital.test.js +61 -0
  321. package/test/math/tensor.test.js +114 -0
  322. package/test/particle/emitter.test.js +204 -0
  323. package/test/particle/particle-system.test.js +310 -0
  324. package/test/particle/particle.test.js +116 -0
  325. package/test/particle/updaters.test.js +386 -0
  326. package/test/setup.js +120 -0
  327. package/test/shapes/euclidian.test.js +44 -0
  328. package/test/shapes/geometry.test.js +86 -0
  329. package/test/shapes/group.test.js +86 -0
  330. package/test/shapes/rectangle.test.js +64 -0
  331. package/test/shapes/transform.test.js +379 -0
  332. package/test/util/camera3d.test.js +428 -0
  333. package/test/util/scene3d.test.js +352 -0
  334. package/types/collision.d.ts +249 -0
  335. package/types/common.d.ts +155 -0
  336. package/types/game.d.ts +497 -0
  337. package/types/index.d.ts +309 -0
  338. package/types/io.d.ts +188 -0
  339. package/types/logger.d.ts +127 -0
  340. package/types/math.d.ts +268 -0
  341. package/types/mixins.d.ts +92 -0
  342. package/types/motion.d.ts +678 -0
  343. package/types/painter.d.ts +378 -0
  344. package/types/shapes.d.ts +864 -0
  345. package/types/sound.d.ts +672 -0
  346. package/types/state.d.ts +251 -0
  347. package/types/util.d.ts +253 -0
  348. package/vite.config.js +50 -0
  349. package/vitest.config.js +13 -0
@@ -0,0 +1,221 @@
1
+ # Shapes Module
2
+
3
+ > 40+ drawable primitives and the shape inheritance hierarchy.
4
+
5
+ ## Overview
6
+
7
+ The shapes module provides all visual primitives in GCanvas. Every shape inherits from a chain of base classes that add progressively more functionality.
8
+
9
+ ## Quick Start
10
+
11
+ ```js
12
+ import { Circle, Rectangle, Star, Group } from 'gcanvas';
13
+
14
+ // Create shapes
15
+ const circle = new Circle(50, { x: 100, y: 100, color: 'red' });
16
+ const rect = new Rectangle({ width: 80, height: 40, color: 'blue' });
17
+
18
+ // Draw
19
+ circle.draw();
20
+ rect.draw();
21
+
22
+ // Group shapes together
23
+ const group = new Group({ x: 400, y: 300 });
24
+ group.add(circle);
25
+ group.add(rect);
26
+ group.draw();
27
+ ```
28
+
29
+ ## Class Hierarchy
30
+
31
+ ```
32
+ Euclidian ─────────── Position & size
33
+
34
+ Geometry2d ────────── Bounding boxes & constraints
35
+
36
+ Traceable ─────────── Debug visualization
37
+
38
+ Renderable ────────── Visibility, opacity, shadows
39
+
40
+ Transformable ─────── Rotation & scaling
41
+
42
+ Shape ─────────────── Fill & stroke styling
43
+
44
+ ├── Circle
45
+ ├── Rectangle
46
+ ├── Star
47
+ ├── Triangle
48
+ ├── Polygon
49
+ ├── ... (40+ shapes)
50
+ └── Group (container)
51
+ ```
52
+
53
+ [View detailed hierarchy](./hierarchy.md)
54
+
55
+ ## Base Classes
56
+
57
+ | Class | Purpose | Documentation |
58
+ |-------|---------|---------------|
59
+ | [Euclidian](./base/euclidian.md) | Position (x, y) and size (width, height) | [Link](./base/euclidian.md) |
60
+ | [Geometry2d](./base/geometry2d.md) | Bounding boxes and constraints | [Link](./base/geometry2d.md) |
61
+ | [Renderable](./base/renderable.md) | Visibility, opacity, shadows | [Link](./base/renderable.md) |
62
+ | [Transformable](./base/transformable.md) | Rotation and scaling | [Link](./base/transformable.md) |
63
+ | [Shape](./base/shape.md) | Fill, stroke, line styling | [Link](./base/shape.md) |
64
+
65
+ ## Available Shapes
66
+
67
+ ### 2D Primitives
68
+
69
+ | Shape | Description |
70
+ |-------|-------------|
71
+ | Circle | Basic circle with radius |
72
+ | Rectangle | Centered rectangle |
73
+ | RoundedRectangle | Rectangle with rounded corners |
74
+ | Square | Square (convenience) |
75
+ | Triangle | Three-sided polygon |
76
+ | Line | Line segment |
77
+ | Arc | Curved arc segment |
78
+ | Polygon | N-sided polygon |
79
+ | Hexagon | Six-sided shape |
80
+
81
+ ### Complex Shapes
82
+
83
+ | Shape | Description |
84
+ |-------|-------------|
85
+ | Star | Star with configurable points |
86
+ | Heart | Heart shape |
87
+ | Diamond | Diamond/rhombus |
88
+ | Cross | Plus/cross shape |
89
+ | Arrow | Arrow shape |
90
+ | Pin | Map pin/marker |
91
+ | Ring | Hollow ring/donut |
92
+ | Cloud | Cloud-like shape |
93
+ | PieSlice | Pie chart slice |
94
+
95
+ ### 3D-Looking Shapes
96
+
97
+ | Shape | Description |
98
+ |-------|-------------|
99
+ | Cube | Isometric cube with face colors |
100
+ | Sphere | Sphere with shading |
101
+ | Cylinder | Cylindrical shape |
102
+ | Cone | Cone/pyramid |
103
+ | Prism | Triangular prism |
104
+
105
+ ### Special Shapes
106
+
107
+ | Shape | Description |
108
+ |-------|-------------|
109
+ | TextShape | Rotatable, scalable text |
110
+ | Image | Image rendering |
111
+ | SVGShape | SVG path-based shapes |
112
+ | BezierShape | Bezier curve shapes |
113
+ | PatternRectangle | Pattern-filled rectangle |
114
+ | StickFigure | Simple stick figure |
115
+
116
+ ### Containers
117
+
118
+ | Class | Description |
119
+ |-------|-------------|
120
+ | Group | Container for composing multiple shapes |
121
+
122
+ ## Common Properties
123
+
124
+ All shapes inherit these properties:
125
+
126
+ ```js
127
+ // From Euclidian
128
+ shape.x // Center X position
129
+ shape.y // Center Y position
130
+ shape.width // Width
131
+ shape.height // Height
132
+
133
+ // From Geometry2d
134
+ shape.minX // Minimum X constraint
135
+ shape.maxX // Maximum X constraint
136
+ shape.minY // Minimum Y constraint
137
+ shape.maxY // Maximum Y constraint
138
+ shape.crisp // Pixel-perfect alignment
139
+
140
+ // From Renderable
141
+ shape.visible // Show/hide
142
+ shape.opacity // Transparency (0-1)
143
+ shape.active // Receive updates
144
+ shape.zIndex // Stacking order
145
+ shape.shadowColor
146
+ shape.shadowBlur
147
+ shape.shadowOffsetX
148
+ shape.shadowOffsetY
149
+
150
+ // From Transformable
151
+ shape.rotation // Rotation in degrees
152
+ shape.scaleX // Horizontal scale
153
+ shape.scaleY // Vertical scale
154
+
155
+ // From Shape
156
+ shape.color // Fill color
157
+ shape.stroke // Stroke color
158
+ shape.lineWidth // Stroke width
159
+ shape.lineJoin // "miter", "round", "bevel"
160
+ shape.lineCap // "butt", "round", "square"
161
+ ```
162
+
163
+ ## Usage Patterns
164
+
165
+ ### Basic Drawing
166
+
167
+ ```js
168
+ const circle = new Circle(50, { x: 100, y: 100, color: 'red' });
169
+ circle.draw();
170
+ ```
171
+
172
+ ### With Transforms
173
+
174
+ ```js
175
+ const rect = new Rectangle({
176
+ width: 100,
177
+ height: 50,
178
+ color: '#4ecdc4',
179
+ rotation: 45, // 45 degrees
180
+ scaleX: 1.5,
181
+ opacity: 0.8
182
+ });
183
+ rect.draw();
184
+ ```
185
+
186
+ ### Grouping Shapes
187
+
188
+ ```js
189
+ const group = new Group({ x: 400, y: 300 });
190
+ group.add(new Circle(30, { color: 'red' }));
191
+ group.add(new Rectangle({ y: 50, width: 60, height: 30, color: 'blue' }));
192
+
193
+ // Transform entire group
194
+ group.rotation = 15;
195
+ group.draw();
196
+ ```
197
+
198
+ ### Animation
199
+
200
+ ```js
201
+ function animate() {
202
+ Painter.clear();
203
+
204
+ shape.rotation += 1;
205
+ shape.x = 400 + Math.sin(Date.now() * 0.001) * 100;
206
+
207
+ shape.draw();
208
+ requestAnimationFrame(animate);
209
+ }
210
+ ```
211
+
212
+ ## Related
213
+
214
+ - [Rendering Pipeline](../../concepts/rendering-pipeline.md) - How shapes render
215
+ - [Two-Layer Architecture](../../concepts/two-layer-architecture.md) - Shape vs Game layer
216
+ - [Painter Module](../painter/README.md) - Low-level drawing API
217
+
218
+ ## See Also
219
+
220
+ - [Hello World](../../getting-started/hello-world.md)
221
+ - [Shape Hierarchy](./hierarchy.md)
@@ -0,0 +1,123 @@
1
+ # Euclidian
2
+
3
+ > The root class defining spatial properties for all visual objects.
4
+
5
+ **Module:** [shapes](../README.md) | **Extends:** `Loggable` | **Source:** `src/shapes/euclidian.js`
6
+
7
+ ## Overview
8
+
9
+ Euclidian is the foundation of all drawable objects in GCanvas. It defines the fundamental spatial contract: a 2D position and size. Before something becomes a shape, a renderable, or a transformable object, it first **exists in space**.
10
+
11
+ This class is abstract and intended to be subclassed.
12
+
13
+ ## Constructor
14
+
15
+ ```js
16
+ new Euclidian(options)
17
+ ```
18
+
19
+ ### Parameters
20
+
21
+ | Parameter | Type | Default | Description |
22
+ |-----------|------|---------|-------------|
23
+ | `options` | `Object` | `{}` | Configuration options |
24
+
25
+ ### Options
26
+
27
+ | Option | Type | Default | Description |
28
+ |--------|------|---------|-------------|
29
+ | `x` | `number` | `0` | X position (center-based) |
30
+ | `y` | `number` | `0` | Y position (center-based) |
31
+ | `width` | `number` | `0` | Width in pixels |
32
+ | `height` | `number` | `0` | Height in pixels |
33
+ | `debug` | `boolean` | `false` | Enable debug visualization |
34
+ | `debugColor` | `string` | `"#0f0"` | Debug outline color |
35
+
36
+ ## Properties
37
+
38
+ | Property | Type | Description |
39
+ |----------|------|-------------|
40
+ | `x` | `number` | X center position in canvas space |
41
+ | `y` | `number` | Y center position in canvas space |
42
+ | `width` | `number` | Width of the object (always ≥ 0) |
43
+ | `height` | `number` | Height of the object (always ≥ 0) |
44
+ | `debug` | `boolean` | Whether debug overlay is enabled |
45
+ | `debugColor` | `string` | Color of the debug box outline |
46
+
47
+ ## Coordinate System
48
+
49
+ GCanvas uses a **center-based** coordinate system:
50
+
51
+ ```
52
+ ┌────────────────────────────────┐
53
+ │ │
54
+ │ (x, y) │
55
+ │ ●───────────────┐ │
56
+ │ │ │ │
57
+ │ │ width │ │
58
+ │ │ │ │
59
+ │ └───────────────┘ │
60
+ │ height │
61
+ │ │
62
+ └────────────────────────────────┘
63
+ ```
64
+
65
+ The `(x, y)` point is the **center** of the object, not the top-left corner.
66
+
67
+ ## Example
68
+
69
+ ```js
70
+ import { Euclidian } from 'gcanvas';
71
+
72
+ // Euclidian is abstract, but shows the basic spatial contract
73
+ const spatial = {
74
+ x: 100, // Center at x=100
75
+ y: 100, // Center at y=100
76
+ width: 50, // 50 pixels wide
77
+ height: 30 // 30 pixels tall
78
+ };
79
+
80
+ // Top-left corner would be at (75, 85)
81
+ // x - width/2 = 100 - 25 = 75
82
+ // y - height/2 = 100 - 15 = 85
83
+ ```
84
+
85
+ ## Property Validation
86
+
87
+ All properties are validated on set:
88
+
89
+ ```js
90
+ shape.x = 100; // Valid
91
+ shape.x = null; // Throws Error: "Invalid property value: x null"
92
+ shape.x = undefined; // Throws Error: "Invalid property value: x undefined"
93
+ ```
94
+
95
+ Width and height are clamped to be non-negative:
96
+
97
+ ```js
98
+ shape.width = -10; // Sets width to 0
99
+ shape.height = -5; // Sets height to 0
100
+ ```
101
+
102
+ ## Inheritance
103
+
104
+ ```
105
+ Loggable
106
+ └── Euclidian <── You are here
107
+ └── Geometry2d
108
+ └── Traceable
109
+ └── Renderable
110
+ └── Transformable
111
+ └── Shape
112
+ ```
113
+
114
+ ## Related
115
+
116
+ - [Geometry2d](./geometry2d.md) - Adds bounding boxes and constraints
117
+ - [Shape Hierarchy](../hierarchy.md) - Full inheritance diagram
118
+ - [Rendering Pipeline](../../../concepts/rendering-pipeline.md) - How shapes render
119
+
120
+ ## See Also
121
+
122
+ - [Shapes Module](../README.md)
123
+ - [Renderable](./renderable.md)
@@ -0,0 +1,204 @@
1
+ # Geometry2d
2
+
3
+ > Bounding box calculations and positional constraints.
4
+
5
+ **Module:** [shapes](../README.md) | **Extends:** [Euclidian](./euclidian.md) | **Source:** `src/shapes/geometry.js`
6
+
7
+ ## Overview
8
+
9
+ Geometry2d builds upon Euclidian by adding:
10
+
11
+ - **Bounding logic** with memoization
12
+ - **Constraint enforcement** (minX, maxX, minY, maxY)
13
+ - **Property change tracking** for efficient recalculations
14
+
15
+ This class is not concerned with transforms, rendering, or visibility. It's the core layer where **position + size = spatial identity**.
16
+
17
+ ## Constructor
18
+
19
+ ```js
20
+ new Geometry2d(options)
21
+ ```
22
+
23
+ ### Options
24
+
25
+ | Option | Type | Default | Description |
26
+ |--------|------|---------|-------------|
27
+ | `minX` | `number` | `undefined` | Minimum X constraint |
28
+ | `maxX` | `number` | `undefined` | Maximum X constraint |
29
+ | `minY` | `number` | `undefined` | Minimum Y constraint |
30
+ | `maxY` | `number` | `undefined` | Maximum Y constraint |
31
+ | `crisp` | `boolean` | `true` | Round to whole pixels |
32
+
33
+ Plus all options from [Euclidian](./euclidian.md).
34
+
35
+ ## Properties
36
+
37
+ ### Inherited from Euclidian
38
+
39
+ `x`, `y`, `width`, `height`, `debug`, `debugColor`
40
+
41
+ ### Own Properties
42
+
43
+ | Property | Type | Description |
44
+ |----------|------|-------------|
45
+ | `minX` | `number \| undefined` | Minimum allowed X value |
46
+ | `maxX` | `number \| undefined` | Maximum allowed X value |
47
+ | `minY` | `number \| undefined` | Minimum allowed Y value |
48
+ | `maxY` | `number \| undefined` | Maximum allowed Y value |
49
+ | `crisp` | `boolean` | Whether to round to whole pixels |
50
+ | `boundsDirty` | `boolean` | Whether bounds need recalculation (readonly) |
51
+
52
+ ## Methods
53
+
54
+ ### getBounds()
55
+
56
+ Returns the object's bounding box. Uses memoization to avoid unnecessary recomputation.
57
+
58
+ ```js
59
+ const bounds = shape.getBounds();
60
+ // { x: 100, y: 100, width: 50, height: 30 }
61
+ ```
62
+
63
+ **Returns:** `{ x: number, y: number, width: number, height: number }`
64
+
65
+ ### calculateBounds()
66
+
67
+ Called by `getBounds()` when bounds are dirty. Override in subclasses for custom bounds (e.g., rotated shapes).
68
+
69
+ ```js
70
+ // Default implementation
71
+ calculateBounds() {
72
+ return {
73
+ x: this.x,
74
+ y: this.y,
75
+ width: this.width,
76
+ height: this.height
77
+ };
78
+ }
79
+ ```
80
+
81
+ **Returns:** `{ x: number, y: number, width: number, height: number }`
82
+
83
+ ### getLocalPosition()
84
+
85
+ Returns the object's top-left corner position. Useful for layout systems.
86
+
87
+ ```js
88
+ const local = shape.getLocalPosition();
89
+ // { x: 75, y: 85 } for a shape at (100,100) with width 50, height 30
90
+ ```
91
+
92
+ **Returns:** `{ x: number, y: number }`
93
+
94
+ ### applyConstraints()
95
+
96
+ Applies positional constraints and optionally rounds to whole pixels.
97
+
98
+ ```js
99
+ shape.minX = 0;
100
+ shape.maxX = 800;
101
+ shape.x = -50; // Out of bounds
102
+ shape.applyConstraints();
103
+ console.log(shape.x); // 0 (constrained to minX)
104
+ ```
105
+
106
+ ### markBoundsDirty()
107
+
108
+ Marks bounds for recalculation. Called automatically when spatial properties change.
109
+
110
+ ```js
111
+ shape.markBoundsDirty();
112
+ // Next getBounds() call will recalculate
113
+ ```
114
+
115
+ ### setTopLeft(x, y)
116
+
117
+ Sets position using top-left coordinates instead of center.
118
+
119
+ ```js
120
+ shape.setTopLeft(0, 0); // Top-left at (0,0)
121
+ // Center is now at (width/2, height/2)
122
+ ```
123
+
124
+ **Returns:** `this` (for chaining)
125
+
126
+ ### setCenter(x, y)
127
+
128
+ Sets the center position (same as setting x and y directly).
129
+
130
+ ```js
131
+ shape.setCenter(400, 300);
132
+ ```
133
+
134
+ **Returns:** `this` (for chaining)
135
+
136
+ ## Constraints Example
137
+
138
+ ```js
139
+ const shape = new Circle(30, {
140
+ x: 400,
141
+ y: 300,
142
+ minX: 50,
143
+ maxX: 750,
144
+ minY: 50,
145
+ maxY: 550
146
+ });
147
+
148
+ // Shape can't go outside the constrained area
149
+ shape.x = 900;
150
+ shape.applyConstraints();
151
+ console.log(shape.x); // 750 (clamped to maxX)
152
+ ```
153
+
154
+ ## Crisp Rendering
155
+
156
+ When `crisp` is true, positions and dimensions are rounded to whole pixels:
157
+
158
+ ```js
159
+ const shape = new Rectangle({
160
+ x: 100.7,
161
+ y: 50.3,
162
+ width: 80.5,
163
+ height: 40.2,
164
+ crisp: true
165
+ });
166
+
167
+ shape.applyConstraints();
168
+ // x: 101, y: 50, width: 81, height: 40
169
+ ```
170
+
171
+ This prevents blurry rendering from sub-pixel positioning.
172
+
173
+ ## Dirty Tracking
174
+
175
+ Bounds are automatically marked dirty when spatial properties change:
176
+
177
+ ```js
178
+ shape.x = 200; // Marks bounds dirty
179
+ shape.getBounds(); // Recalculates and caches
180
+ shape.getBounds(); // Returns cached value (fast)
181
+ shape.width = 100; // Marks bounds dirty again
182
+ ```
183
+
184
+ ## Inheritance
185
+
186
+ ```
187
+ Euclidian
188
+ └── Geometry2d <── You are here
189
+ └── Traceable
190
+ └── Renderable
191
+ └── Transformable
192
+ └── Shape
193
+ ```
194
+
195
+ ## Related
196
+
197
+ - [Euclidian](./euclidian.md) - Parent class
198
+ - [Renderable](./renderable.md) - Next in hierarchy
199
+ - [Shape Hierarchy](../hierarchy.md) - Full inheritance diagram
200
+
201
+ ## See Also
202
+
203
+ - [Shapes Module](../README.md)
204
+ - [Transformable](./transformable.md) - Adds rotation/scale-aware bounds