@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,70 @@
1
+ name: Release on Master Merge
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ permissions:
7
+ contents: write
8
+ jobs:
9
+ release:
10
+ name: Build and Release GCanvas
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v3
15
+ with:
16
+ fetch-depth: 0
17
+ - name: Setup Node.js
18
+ uses: actions/setup-node@v3
19
+ with:
20
+ node-version: "20"
21
+ - name: Install dependencies
22
+ run: npm ci
23
+ - name: Build library
24
+ run: npm run build
25
+ - name: Read version from package.json
26
+ id: pkg
27
+ run: |
28
+ VERSION=$(node -p "require('./package.json').version")
29
+ echo "VERSION=v$VERSION" >> $GITHUB_OUTPUT
30
+ - name: Show version used
31
+ run: |
32
+ echo "Publishing version: ${{ steps.pkg.outputs.VERSION }}"
33
+ - name: Generate Changelog
34
+ id: changelog
35
+ run: |
36
+ LAST_TAG=$(git describe --tags --abbrev=0)
37
+ echo "Last tag was: $LAST_TAG"
38
+ LOG=$(git log $LAST_TAG..HEAD --pretty=format:"- %s")
39
+ echo "LOG<<EOF" >> $GITHUB_OUTPUT
40
+ echo "$LOG" >> $GITHUB_OUTPUT
41
+ echo "EOF" >> $GITHUB_OUTPUT
42
+ - name: Create GitHub Release
43
+ id: create_release
44
+ uses: actions/create-release@v1
45
+ env:
46
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47
+ with:
48
+ tag_name: ${{ steps.pkg.outputs.VERSION }}
49
+ body: ${{ steps.changelog.outputs.LOG }}
50
+ release_name: GCanvas ${{ steps.pkg.outputs.VERSION }}
51
+ draft: false
52
+ prerelease: false
53
+ - name: Upload UMD build
54
+ uses: actions/upload-release-asset@v1
55
+ env:
56
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
+ with:
58
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
59
+ asset_path: dist/gcanvas.umd.min.js
60
+ asset_name: gcanvas.umd.min.js
61
+ asset_content_type: application/javascript
62
+ - name: Upload ESM build
63
+ uses: actions/upload-release-asset@v1
64
+ env:
65
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66
+ with:
67
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
68
+ asset_path: dist/gcanvas.es.min.js
69
+ asset_name: gcanvas.es.min.js
70
+ asset_content_type: application/javascript
package/.jshintrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "esversion": 11,
3
+ "node": false
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "workbench.colorCustomizations": {
3
+ "activityBar.activeBackground": "#2f7c47",
4
+ "activityBar.background": "#2f7c47",
5
+ "activityBar.foreground": "#e7e7e7",
6
+ "activityBar.inactiveForeground": "#e7e7e799",
7
+ "activityBarBadge.background": "#422c74",
8
+ "activityBarBadge.foreground": "#e7e7e7",
9
+ "commandCenter.border": "#e7e7e799",
10
+ "sash.hoverBorder": "#2f7c47",
11
+ "statusBar.background": "#215732",
12
+ "statusBar.foreground": "#e7e7e7",
13
+ "statusBarItem.hoverBackground": "#2f7c47",
14
+ "statusBarItem.remoteBackground": "#215732",
15
+ "statusBarItem.remoteForeground": "#e7e7e7",
16
+ "titleBar.activeBackground": "#215732",
17
+ "titleBar.activeForeground": "#e7e7e7",
18
+ "titleBar.inactiveBackground": "#21573299",
19
+ "titleBar.inactiveForeground": "#e7e7e799"
20
+ },
21
+ "peacock.color": "#215732"
22
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,310 @@
1
+ # AGENTS.md - GCanvas Development Guidelines
2
+
3
+ ## Project Overview
4
+
5
+ GCanvas is a zero-dependency HTML5 Canvas library for 2D graphics, games, and generative art. It provides a declarative API built on shapes, game objects, and a rendering pipeline.
6
+
7
+ **Repository:** https://github.com/guinetik/gcanvas
8
+
9
+ ## Project Structure
10
+
11
+ ```
12
+ gcanvas/
13
+ ├── src/ # Library source code
14
+ │ ├── index.js # Main exports
15
+ │ ├── shapes/ # Shape primitives (Circle, Rect, Text, etc.)
16
+ │ ├── game/ # Game loop, pipeline, GameObjects
17
+ │ │ ├── objects/ # GameObject wrappers (Text, Scene, ImageGo)
18
+ │ │ ├── ui/ # UI components (Button, FPS counter)
19
+ │ │ └── pipeline.js # Rendering pipeline
20
+ │ ├── painter/ # Low-level canvas drawing utilities
21
+ │ ├── motion/ # Animation & tweening (Tween, easing functions)
22
+ │ ├── math/ # Math utilities (Complex, noise, fractals)
23
+ │ ├── mixins/ # Composable behaviors (anchor, draggable)
24
+ │ ├── util/ # Utilities (layout, position, Camera3D)
25
+ │ ├── io/ # Input handling (keyboard, mouse, touch)
26
+ │ ├── collision/ # Collision detection
27
+ │ ├── state/ # State management
28
+ │ └── sound/ # Audio utilities
29
+ ├── demos/ # Demo applications
30
+ │ ├── js/ # Demo JavaScript files
31
+ │ ├── *.html # Demo HTML entry points
32
+ │ └── demos.css # Shared demo styles
33
+ ├── tests/ # Vitest test files
34
+ └── dist/ # Built library (UMD & ES modules)
35
+ ```
36
+
37
+ ## Coding Guidelines
38
+
39
+ ### 1. No Magic Numbers
40
+
41
+ **Always use a CONFIG object** at the top of files for configurable values.
42
+
43
+ ```javascript
44
+ // BAD - magic numbers scattered in code
45
+ this.camera = new Camera3D({ perspective: 800 });
46
+ for (let i = 0; i < 300; i++) { ... }
47
+ const radius = 80;
48
+
49
+ // GOOD - centralized configuration
50
+ const CONFIG = {
51
+ perspective: 800,
52
+ numPoints: 300,
53
+ helixRadius: 80,
54
+
55
+ // Group related values
56
+ physics: {
57
+ gravity: 0.0001,
58
+ damping: 0.99,
59
+ },
60
+
61
+ // Document units where helpful
62
+ timeScale: 1.0, // seconds
63
+ gridSpacing: 30, // pixels
64
+ };
65
+ ```
66
+
67
+ ### 2. Prefer Shapes and GameObjects Over Direct Canvas
68
+
69
+ The library provides abstractions - use them instead of raw canvas operations.
70
+
71
+ ```javascript
72
+ // BAD - direct canvas drawing
73
+ ctx.beginPath();
74
+ ctx.arc(x, y, 50, 0, Math.PI * 2);
75
+ ctx.fillStyle = "red";
76
+ ctx.fill();
77
+
78
+ // GOOD - use Shape classes
79
+ import { Circle } from "../../src/index.js";
80
+ const circle = new Circle(x, y, 50, { fill: "red" });
81
+ circle.render(ctx);
82
+
83
+ // GOOD - use GameObjects for managed entities
84
+ import { Game, Scene, Text } from "../../src/index.js";
85
+ const label = new Text(this, "Hello", { color: "#fff", font: "16px monospace" });
86
+ this.pipeline.add(label);
87
+ ```
88
+
89
+ ### 3. Use Painter.useCtx for Low-Level Operations
90
+
91
+ When you must access the canvas context directly, wrap it with `Painter.useCtx`:
92
+
93
+ ```javascript
94
+ import { Painter } from "../../src/index.js";
95
+
96
+ // BAD - direct ctx manipulation
97
+ ctx.save();
98
+ ctx.strokeStyle = "rgba(255,255,255,0.5)";
99
+ ctx.lineWidth = 2;
100
+ ctx.moveTo(x1, y1);
101
+ ctx.lineTo(x2, y2);
102
+ ctx.stroke();
103
+ ctx.restore();
104
+
105
+ // GOOD - Painter.useCtx handles save/restore automatically
106
+ Painter.useCtx((ctx) => {
107
+ ctx.strokeStyle = "rgba(255,255,255,0.5)";
108
+ ctx.lineWidth = 2;
109
+ ctx.moveTo(x1, y1);
110
+ ctx.lineTo(x2, y2);
111
+ ctx.stroke();
112
+ });
113
+ ```
114
+
115
+ ### 4. Use Layout Utilities for Positioning
116
+
117
+ Don't manually calculate positions for multiple items:
118
+
119
+ ```javascript
120
+ import { verticalLayout, applyLayout, applyAnchor, Position, Scene, Text } from "../../src/index.js";
121
+
122
+ // BAD - manual offset calculations
123
+ this.title = new Text(this, "Title", { y: 20 });
124
+ this.subtitle = new Text(this, "Subtitle", { y: 45 });
125
+ this.info = new Text(this, "Info", { y: 70 });
126
+
127
+ // GOOD - use layout utilities
128
+ const panel = new Scene(this, { x: 0, y: 0 });
129
+ applyAnchor(panel, { anchor: Position.TOP_CENTER, anchorOffsetY: 100 });
130
+
131
+ const items = [
132
+ new Text(this, "Title", { font: "bold 16px monospace" }),
133
+ new Text(this, "Subtitle", { font: "14px monospace" }),
134
+ new Text(this, "Info", { font: "12px monospace" }),
135
+ ];
136
+
137
+ const layout = verticalLayout(items, { spacing: 20, align: "center" });
138
+ applyLayout(items, layout.positions);
139
+ items.forEach(item => panel.add(item));
140
+ ```
141
+
142
+ ### 5. Extend Game Class for Demos
143
+
144
+ All demos should extend the `Game` class:
145
+
146
+ ```javascript
147
+ import { Game, Painter } from "../../src/index.js";
148
+
149
+ const CONFIG = {
150
+ // Configuration values
151
+ };
152
+
153
+ class MyDemo extends Game {
154
+ constructor(canvas) {
155
+ super(canvas);
156
+ this.backgroundColor = "#000";
157
+ this.enableFluidSize(); // Responsive canvas
158
+ }
159
+
160
+ init() {
161
+ super.init();
162
+ // Initialize shapes, game objects, state
163
+ this.pipeline.add(myGameObject);
164
+ }
165
+
166
+ update(dt) {
167
+ super.update(dt);
168
+ // Update logic (dt is delta time in seconds)
169
+ }
170
+
171
+ render() {
172
+ super.render(); // Clears canvas, renders pipeline
173
+ // Additional rendering if needed
174
+ }
175
+ }
176
+
177
+ window.addEventListener("load", () => {
178
+ const canvas = document.getElementById("game");
179
+ const demo = new MyDemo(canvas);
180
+ demo.start();
181
+ });
182
+ ```
183
+
184
+ ## Key APIs Reference
185
+
186
+ ### Shapes
187
+ - `Circle`, `Rect`, `Square`, `Triangle`, `Hexagon`, `Star`
188
+ - `Line`, `Arc`, `BezierShape`, `SVGShape`
189
+ - `Text` (shape), `ImageShape`, `Pattern`
190
+ - 3D shapes: `Cube`, `Sphere`, `Cylinder`, `Cone`, `Prism`
191
+
192
+ ### GameObjects (in `src/game/objects/`)
193
+ - `Text` - Managed text with automatic updates
194
+ - `Scene` - Container for grouping objects
195
+ - `ImageGo` - Managed image display
196
+ - `LayoutScene` - Scene with layout helpers
197
+
198
+ ### Motion & Animation
199
+ - `Tween` - Animate properties over time
200
+ - `TweenEnetik` - Advanced tweening
201
+ - Motion behaviors: `Orbit`, `Oscillate`, `Bounce`, `Spring`, etc.
202
+
203
+ ### Utilities
204
+ - `Camera3D` - Pseudo-3D projection with mouse controls
205
+ - `verticalLayout`, `horizontalLayout`, `gridLayout` - Layout helpers
206
+ - `applyAnchor` - Position anchoring mixin
207
+ - `Position` - Position constants (TOP_CENTER, BOTTOM_LEFT, etc.)
208
+
209
+ ### Math
210
+ - `Complex` - Complex number operations
211
+ - `Noise` - Perlin/simplex noise
212
+ - `Random` - Seeded random utilities
213
+ - Fractal generators
214
+
215
+ ### Input
216
+ - `Keys` - Keyboard input
217
+ - `Input` - Mouse/pointer input
218
+ - `Touch` - Touch input handling
219
+
220
+ ## Demo File Structure
221
+
222
+ ```
223
+ demos/
224
+ ├── mydemo.html # HTML entry point
225
+ └── js/
226
+ └── mydemo.js # Demo implementation
227
+ ```
228
+
229
+ ### HTML Template
230
+
231
+ ```html
232
+ <!DOCTYPE html>
233
+ <html lang="en">
234
+ <head>
235
+ <meta charset="UTF-8" />
236
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
237
+ <title>Demo Name</title>
238
+ <link rel="stylesheet" href="demos.css" />
239
+ <script src="./js/info-toggle.js"></script>
240
+ </head>
241
+ <body>
242
+ <div id="info">
243
+ <strong>Demo Title</strong> — Brief description.<br/>
244
+ <span style="color:#CCC">
245
+ <li>Feature 1</li>
246
+ <li>Feature 2</li>
247
+ <li>Controls info</li>
248
+ </span>
249
+ </div>
250
+ <canvas id="game"></canvas>
251
+ <script type="module" src="./js/mydemo.js"></script>
252
+ </body>
253
+ </html>
254
+ ```
255
+
256
+ ### Adding to Navigation
257
+
258
+ Update `demos/index.html` to add your demo to the appropriate section:
259
+
260
+ ```html
261
+ <h2>Section Name</h2>
262
+ <a href="mydemo.html" target="demo-frame">My Demo</a>
263
+ ```
264
+
265
+ ## Development Commands
266
+
267
+ ```bash
268
+ npm run dev # Start Vite dev server
269
+ npm run build # Build library to dist/
270
+ npm run test # Run tests
271
+ npm run test:watch # Run tests in watch mode
272
+ npm run docs # Generate JSDoc documentation
273
+ ```
274
+
275
+ ## Testing
276
+
277
+ Tests use Vitest and are located in `tests/`. Run with:
278
+
279
+ ```bash
280
+ npm test
281
+ ```
282
+
283
+ ## Common Patterns
284
+
285
+ ### Responsive Canvas
286
+ ```javascript
287
+ this.enableFluidSize(); // Auto-resize to window
288
+ ```
289
+
290
+ ### Mouse/Touch Interaction
291
+ ```javascript
292
+ this.canvas.addEventListener("click", () => this.handleClick());
293
+ this.canvas.addEventListener("touchstart", (e) => this.handleTouch(e));
294
+ ```
295
+
296
+ ### Color Utilities
297
+ ```javascript
298
+ import { Painter } from "../../src/index.js";
299
+ const rgb = Painter.colors.hslToRgb(hue, saturation, lightness);
300
+ const hex = Painter.colors.rgbToHex(r, g, b);
301
+ ```
302
+
303
+ ### Animation Loop Access
304
+ ```javascript
305
+ update(dt) {
306
+ super.update(dt);
307
+ this.time += dt; // dt is in seconds
308
+ // Animation logic
309
+ }
310
+ ```
package/blackhole.jpg ADDED
Binary file
package/demo.png ADDED
Binary file
package/demos/CNAME ADDED
@@ -0,0 +1 @@
1
+ gcanvas.guinetik.com
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Tween</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Motion Demo</strong> - Showcases reusable animations. Each animation is implemented through a tween system that handles interpolation between values over time. The demo uses a tile-based layout to organize the animations in a grid, with each animation contained in its own box. Under the hood, the system manages animation timing through a central update loop, applying mathematical transformations to the shapes' positions based on normalized time values (0-1) that loop continuously.
15
+ </div>
16
+ <canvas id="game"></canvas>
17
+ <script type="module">
18
+ import { MyGame } from './js/animations.js';
19
+
20
+ window.addEventListener("load", () => {
21
+ const canvas = document.getElementById("game");
22
+ const game = new MyGame(canvas);
23
+ // game.setFPS(1);
24
+ // game.enableLogging(true);
25
+ game.start();
26
+ // setTimeout(game.stop.bind(game), 2000);
27
+ });
28
+ </script>
29
+ </body>
30
+
31
+ </html>
@@ -0,0 +1,38 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Basic Game Template</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Basic Template</strong> — A minimal demo to kickstart new games. <br>
15
+ A <strong>Game</strong> manages the canvas, lifecycle, input, and rendering loop. <br>
16
+ A <strong>GameObject</strong> is any interactive or drawable entity (e.g. shape, text, button, particle). <br>
17
+ A <strong>Scene</strong> is a container that groups GameObjects and controls update & render order. <br>
18
+ The <strong>Pipeline</strong> is the main ordered list of GameObjects (or Scenes) that the game runs every frame.
19
+ <br>
20
+ This template sets up one game scene and one UI scene, with a "Hello World" box in the center and an FPS counter in
21
+ the corner.
22
+ </div>
23
+ <canvas id="game"></canvas>
24
+
25
+ <script type="module">
26
+ import { DemoGame } from "./js/basic.js";
27
+ window.addEventListener("load", () => {
28
+ const canvas = document.getElementById("game");
29
+ const game = new DemoGame(canvas);
30
+ //game.enableLogging();
31
+ game.enablePauseOnBlur(true);
32
+ game.setFPS(60);
33
+ game.start();
34
+ });
35
+ </script>
36
+ </body>
37
+
38
+ </html>
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Root Dance - Bhaskara Formula</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Bhaskara Dance</strong> - Visualizing the quadratic formula (Bhaskara).
15
+ Particles represent the roots of ax² + bx + c = 0. Watch them dance
16
+ as coefficients animate, merge when the discriminant hits zero, and spiral
17
+ into the complex plane when roots become imaginary.
18
+ </div>
19
+ <canvas id="game"></canvas>
20
+ <script type="module">
21
+ import { MyGame } from './js/baskara.js';
22
+
23
+ window.addEventListener("load", () => {
24
+ const canvas = document.getElementById("game");
25
+ const game = MyGame(canvas);
26
+ game.start();
27
+ });
28
+ </script>
29
+ </body>
30
+
31
+ </html>
@@ -0,0 +1,35 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Basic Game Template</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Bezier Curve Editor</strong> — Create and modify Bezier curves with interactive control points. <br>
15
+ The demo shows the separation between <strong>Shapes</strong> (visual definitions) and
16
+ <strong>GameObjects</strong> (interactive entities). <br>
17
+ <strong>BezierShape</strong> defines curve paths using commands like "M" (move), "L" (line), "Q" (quadratic),
18
+ and "C" (cubic). <br>
19
+ <strong>Control Points</strong> are wrapped with ShapeGOFactory to make them interactive, while guide lines show
20
+ relationships between points. <br>
21
+ Switch between <strong>Add Points</strong> mode to place new control points and <strong>Edit Points</strong>
22
+ mode to drag and adjust the curve shape.
23
+ </div>
24
+ <canvas id="game"></canvas>
25
+ <script type="module" src="./js/bezier.js"></script>
26
+ <script type="module">
27
+ window.addEventListener("load", () => {
28
+ const canvas = document.getElementById("game");
29
+ const game = new BezierDemoGame(canvas);
30
+ game.start();
31
+ });
32
+ </script>
33
+ </body>
34
+
35
+ </html>
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Bezier Signature</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Bezier Signature</strong> — A <code>BezierShape</code> receives an array of path commands and draws them as a
15
+ bezier curve. This can be done all frames at once or they can be iterated over time, like a signature animation.
16
+ </div>
17
+ <canvas id="game"></canvas>
18
+ <script type="module">
19
+ import { MyGame } from './js/beziersignature.js';
20
+
21
+ window.addEventListener("load", () => {
22
+ const canvas = document.getElementById("game");
23
+ const game = new MyGame(canvas);
24
+ game.start();
25
+ });
26
+ </script>
27
+ </body>
28
+
29
+ </html>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Black Hole - Cinematic Visualization</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Black Hole</strong> — Cinematic accretion disk visualization.<br/>
15
+ <span style="color:#CCC">
16
+ <li><code>Gravitational Lensing</code> — Light bends around the hole.</li>
17
+ <li><code>Accretion Disk</code> — 2500 particles with heat gradient.</li>
18
+ <li><code>Doppler Beaming</code> — Approaching side brighter.</li>
19
+ <li><code>Hawking Radiation</code> — Rare cyan quantum escapes.</li>
20
+ <li><code>Drag</code> — Orbit the camera around.</li>
21
+ <li><code>Auto-rotate</code> — Slow orbit when idle.</li>
22
+ </span>
23
+ </div>
24
+ <canvas id="game"></canvas>
25
+ <script type="module" src="./js/blackhole/index.js"></script>
26
+ </body>
27
+
28
+ </html>
@@ -0,0 +1,35 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Blob Feeder</title>
8
+ <link rel="stylesheet" href="demos.css" />
9
+ <script src="./js/info-toggle.js"></script>
10
+ </head>
11
+
12
+ <body>
13
+ <div id="info">
14
+ <strong>Blob Feeder</strong> — A Tamagotchi-style micro-game where you keep your blob alive by collecting food!<br>
15
+ <span style="color:#CCC">
16
+ <li>Guide the blob with your mouse/touch to collect shapes</li>
17
+ <li>Each level = one musical scale (do-re-mi), longer scales as you progress</li>
18
+ <li>Pick up items quickly for speed bonuses (up to 2x points)</li>
19
+ <li>Don't let your blob go hungry - it will shrink and lose points!</li>
20
+ <li>Watch the blob's face - it shows mood based on hunger and energy</li>
21
+ </span>
22
+ </div>
23
+ <canvas id="game"></canvas>
24
+ <script type="module">
25
+ import { BezierBlobGame } from './js/blob.js';
26
+
27
+ window.addEventListener("load", () => {
28
+ const canvas = document.getElementById("game");
29
+ const game = new BezierBlobGame(canvas);
30
+ game.start();
31
+ });
32
+ </script>
33
+ </body>
34
+
35
+ </html>