canvasengine 2.0.1-beta.2 → 2.0.1

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 (206) hide show
  1. package/dist/DebugRenderer-DkjTAc48.js +1384 -0
  2. package/dist/DebugRenderer-DkjTAc48.js.map +1 -0
  3. package/dist/components/Button.d.ts +185 -0
  4. package/dist/components/Button.d.ts.map +1 -0
  5. package/dist/components/Canvas.d.ts +17 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/Container.d.ts +25 -0
  8. package/dist/components/Container.d.ts.map +1 -0
  9. package/dist/components/DOMContainer.d.ts +28 -0
  10. package/dist/components/DOMContainer.d.ts.map +1 -0
  11. package/dist/components/DOMElement.d.ts +54 -0
  12. package/dist/components/DOMElement.d.ts.map +1 -0
  13. package/dist/components/DOMSprite.d.ts +127 -0
  14. package/dist/components/DOMSprite.d.ts.map +1 -0
  15. package/dist/components/DisplayObject.d.ts +18 -0
  16. package/dist/components/DisplayObject.d.ts.map +1 -0
  17. package/dist/components/FocusContainer.d.ts +129 -0
  18. package/dist/components/FocusContainer.d.ts.map +1 -0
  19. package/dist/components/Graphic.d.ts +64 -0
  20. package/dist/components/Graphic.d.ts.map +1 -0
  21. package/dist/components/Joystick.d.ts +37 -0
  22. package/dist/components/Joystick.d.ts.map +1 -0
  23. package/dist/components/Mesh.d.ts +138 -0
  24. package/dist/components/Mesh.d.ts.map +1 -0
  25. package/dist/components/NineSliceSprite.d.ts +16 -0
  26. package/dist/components/NineSliceSprite.d.ts.map +1 -0
  27. package/dist/components/ParticleEmitter.d.ts +4 -0
  28. package/dist/components/ParticleEmitter.d.ts.map +1 -0
  29. package/dist/components/Scene.d.ts +2 -0
  30. package/dist/components/Scene.d.ts.map +1 -0
  31. package/dist/components/Sprite.d.ts +182 -0
  32. package/dist/components/Sprite.d.ts.map +1 -0
  33. package/dist/components/Text.d.ts +24 -0
  34. package/dist/components/Text.d.ts.map +1 -0
  35. package/dist/components/TilingSprite.d.ts +17 -0
  36. package/dist/components/TilingSprite.d.ts.map +1 -0
  37. package/dist/components/Video.d.ts +14 -0
  38. package/dist/components/Video.d.ts.map +1 -0
  39. package/dist/components/Viewport.d.ts +52 -0
  40. package/dist/components/Viewport.d.ts.map +1 -0
  41. package/dist/components/index.d.ts +20 -0
  42. package/dist/components/index.d.ts.map +1 -0
  43. package/dist/components/types/DisplayObject.d.ts +127 -0
  44. package/dist/components/types/DisplayObject.d.ts.map +1 -0
  45. package/dist/components/types/MouseEvent.d.ts +4 -0
  46. package/dist/components/types/MouseEvent.d.ts.map +1 -0
  47. package/dist/components/types/Spritesheet.d.ts +248 -0
  48. package/dist/components/types/Spritesheet.d.ts.map +1 -0
  49. package/dist/components/types/index.d.ts +4 -0
  50. package/dist/components/types/index.d.ts.map +1 -0
  51. package/dist/directives/Controls.d.ts +112 -0
  52. package/dist/directives/Controls.d.ts.map +1 -0
  53. package/dist/directives/ControlsBase.d.ts +199 -0
  54. package/dist/directives/ControlsBase.d.ts.map +1 -0
  55. package/dist/directives/Drag.d.ts +69 -0
  56. package/dist/directives/Drag.d.ts.map +1 -0
  57. package/dist/directives/Flash.d.ts +116 -0
  58. package/dist/directives/Flash.d.ts.map +1 -0
  59. package/dist/directives/FocusNavigation.d.ts +52 -0
  60. package/dist/directives/FocusNavigation.d.ts.map +1 -0
  61. package/dist/directives/FogVisibility.d.ts +47 -0
  62. package/dist/directives/FogVisibility.d.ts.map +1 -0
  63. package/dist/directives/GamepadControls.d.ts +224 -0
  64. package/dist/directives/GamepadControls.d.ts.map +1 -0
  65. package/dist/directives/JoystickControls.d.ts +171 -0
  66. package/dist/directives/JoystickControls.d.ts.map +1 -0
  67. package/dist/directives/KeyboardControls.d.ts +219 -0
  68. package/dist/directives/KeyboardControls.d.ts.map +1 -0
  69. package/dist/directives/Scheduler.d.ts +36 -0
  70. package/dist/directives/Scheduler.d.ts.map +1 -0
  71. package/dist/directives/Shake.d.ts +98 -0
  72. package/dist/directives/Shake.d.ts.map +1 -0
  73. package/dist/directives/Sound.d.ts +25 -0
  74. package/dist/directives/Sound.d.ts.map +1 -0
  75. package/dist/directives/SpriteEffects.d.ts +70 -0
  76. package/dist/directives/SpriteEffects.d.ts.map +1 -0
  77. package/dist/directives/Transition.d.ts +10 -0
  78. package/dist/directives/Transition.d.ts.map +1 -0
  79. package/dist/directives/ViewportCull.d.ts +11 -0
  80. package/dist/directives/ViewportCull.d.ts.map +1 -0
  81. package/dist/directives/ViewportFollow.d.ts +18 -0
  82. package/dist/directives/ViewportFollow.d.ts.map +1 -0
  83. package/dist/directives/index.d.ts +15 -0
  84. package/dist/directives/index.d.ts.map +1 -0
  85. package/dist/dist-BOOc43Qm.js +778 -0
  86. package/dist/dist-BOOc43Qm.js.map +1 -0
  87. package/dist/engine/FocusManager.d.ts +174 -0
  88. package/dist/engine/FocusManager.d.ts.map +1 -0
  89. package/dist/engine/animation.d.ts +72 -0
  90. package/dist/engine/animation.d.ts.map +1 -0
  91. package/dist/engine/bootstrap.d.ts +52 -0
  92. package/dist/engine/bootstrap.d.ts.map +1 -0
  93. package/dist/engine/directive.d.ts +13 -0
  94. package/dist/engine/directive.d.ts.map +1 -0
  95. package/dist/engine/reactive.d.ts +139 -0
  96. package/dist/engine/reactive.d.ts.map +1 -0
  97. package/dist/engine/signal.d.ts +74 -0
  98. package/dist/engine/signal.d.ts.map +1 -0
  99. package/dist/engine/trigger.d.ts +54 -0
  100. package/dist/engine/trigger.d.ts.map +1 -0
  101. package/dist/engine/utils.d.ts +89 -0
  102. package/dist/engine/utils.d.ts.map +1 -0
  103. package/dist/hooks/addContext.d.ts +2 -0
  104. package/dist/hooks/addContext.d.ts.map +1 -0
  105. package/dist/hooks/useFocus.d.ts +60 -0
  106. package/dist/hooks/useFocus.d.ts.map +1 -0
  107. package/dist/hooks/useProps.d.ts +53 -0
  108. package/dist/hooks/useProps.d.ts.map +1 -0
  109. package/dist/hooks/useRef.d.ts +4 -0
  110. package/dist/hooks/useRef.d.ts.map +1 -0
  111. package/dist/index.d.ts +19 -844
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.global.js +189 -0
  114. package/dist/index.global.js.map +1 -0
  115. package/dist/index.js +15156 -3279
  116. package/dist/index.js.map +1 -1
  117. package/dist/utils/Ease.d.ts +17 -0
  118. package/dist/utils/Ease.d.ts.map +1 -0
  119. package/dist/utils/GlobalAssetLoader.d.ts +141 -0
  120. package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
  121. package/dist/utils/RadialGradient.d.ts +57 -0
  122. package/dist/utils/RadialGradient.d.ts.map +1 -0
  123. package/dist/utils/functions.d.ts +2 -0
  124. package/dist/utils/functions.d.ts.map +1 -0
  125. package/dist/utils/tabindex.d.ts +16 -0
  126. package/dist/utils/tabindex.d.ts.map +1 -0
  127. package/index.d.ts +1 -3
  128. package/package.json +17 -46
  129. package/src/components/Button.ts +406 -0
  130. package/src/components/Canvas.ts +82 -51
  131. package/src/components/Container.ts +31 -4
  132. package/src/components/DOMContainer.ts +387 -0
  133. package/src/components/DOMElement.ts +556 -0
  134. package/src/components/DOMSprite.ts +1044 -0
  135. package/src/components/DisplayObject.ts +423 -202
  136. package/src/components/FocusContainer.ts +368 -0
  137. package/src/components/Graphic.ts +255 -68
  138. package/src/components/Joystick.ts +269 -0
  139. package/src/components/Mesh.ts +239 -0
  140. package/src/components/NineSliceSprite.ts +4 -1
  141. package/src/components/ParticleEmitter.ts +12 -8
  142. package/src/components/Sprite.ts +441 -54
  143. package/src/components/Text.ts +270 -26
  144. package/src/components/Video.ts +110 -0
  145. package/src/components/Viewport.ts +122 -63
  146. package/src/components/index.ts +12 -5
  147. package/src/components/types/DisplayObject.ts +64 -5
  148. package/src/components/types/Spritesheet.ts +0 -118
  149. package/src/directives/Controls.ts +254 -0
  150. package/src/directives/ControlsBase.ts +267 -0
  151. package/src/directives/Drag.ts +357 -52
  152. package/src/directives/Flash.ts +419 -0
  153. package/src/directives/FocusNavigation.ts +113 -0
  154. package/src/directives/FogVisibility.ts +273 -0
  155. package/src/directives/GamepadControls.ts +537 -0
  156. package/src/directives/JoystickControls.ts +396 -0
  157. package/src/directives/KeyboardControls.ts +86 -431
  158. package/src/directives/Scheduler.ts +21 -5
  159. package/src/directives/Shake.ts +298 -0
  160. package/src/directives/Sound.ts +94 -31
  161. package/src/directives/SpriteEffects.ts +461 -0
  162. package/src/directives/ViewportFollow.ts +40 -9
  163. package/src/directives/index.ts +14 -6
  164. package/src/engine/FocusManager.ts +510 -0
  165. package/src/engine/animation.ts +175 -21
  166. package/src/engine/bootstrap.ts +140 -6
  167. package/src/engine/directive.ts +4 -4
  168. package/src/engine/reactive.ts +1266 -167
  169. package/src/engine/signal.ts +335 -47
  170. package/src/engine/trigger.ts +95 -12
  171. package/src/engine/utils.ts +101 -9
  172. package/src/hooks/useFocus.ts +91 -0
  173. package/src/hooks/useProps.ts +92 -7
  174. package/src/index.ts +13 -6
  175. package/src/types/pixi-cull.d.ts +7 -0
  176. package/src/utils/GlobalAssetLoader.ts +257 -0
  177. package/src/utils/RadialGradient.ts +29 -0
  178. package/src/utils/functions.ts +7 -0
  179. package/src/utils/tabindex.ts +70 -0
  180. package/testing/index.ts +42 -0
  181. package/tsconfig.json +18 -23
  182. package/vite.config.ts +39 -0
  183. package/README.md +0 -79
  184. package/compiler/dist/index.d.ts +0 -9
  185. package/compiler/dist/index.js +0 -119
  186. package/compiler/dist/index.js.map +0 -1
  187. package/compiler/grammar.pegjs +0 -180
  188. package/compiler/index.ts +0 -166
  189. package/compiler/package-lock.json +0 -1850
  190. package/compiler/package.json +0 -27
  191. package/compiler/tsconfig.json +0 -29
  192. package/compiler/tsup.config.ts +0 -14
  193. package/src/components/DrawMap/index.ts +0 -65
  194. package/src/components/Tilemap/Tile.ts +0 -79
  195. package/src/components/Tilemap/TileGroup.ts +0 -207
  196. package/src/components/Tilemap/TileLayer.ts +0 -163
  197. package/src/components/Tilemap/TileSet.ts +0 -41
  198. package/src/components/Tilemap/index.ts +0 -80
  199. package/src/presets/Bar.ts +0 -89
  200. package/src/presets/Button.ts +0 -0
  201. package/src/presets/Joystick.ts +0 -286
  202. package/src/presets/NightAmbiant.ts +0 -122
  203. package/src/presets/Particle.ts +0 -53
  204. package/tsconfig.node.json +0 -10
  205. package/tsup.config.ts +0 -13
  206. package/vitest.config.ts +0 -12
@@ -1,5 +1,13 @@
1
1
  import { Texture, ImageSource, DOMAdapter, Matrix } from "pixi.js";
2
2
 
3
+ /**
4
+ * Creates a radial gradient texture that can be used in PixiJS.
5
+ * @example
6
+ * const gradient = new RadialGradient(size, size, 0, size, size, 0);
7
+ * gradient.addColorStop(0, "rgba(255, 255, 0, 1)");
8
+ * gradient.addColorStop(0.5, "rgba(255, 255, 0, 0.3)");
9
+ * gradient.addColorStop(0.8, "rgba(255, 255, 0, 0)");
10
+ */
3
11
  export class RadialGradient {
4
12
  private canvas: HTMLCanvasElement;
5
13
  private ctx: CanvasRenderingContext2D | null;
@@ -9,6 +17,16 @@ export class RadialGradient {
9
17
 
10
18
  public size = 600;
11
19
 
20
+ /**
21
+ * Creates a new RadialGradient instance
22
+ * @param x0 - The x-coordinate of the starting circle
23
+ * @param y0 - The y-coordinate of the starting circle
24
+ * @param x1 - The x-coordinate of the ending circle
25
+ * @param y1 - The y-coordinate of the ending circle
26
+ * @param x2 - The x-coordinate for gradient transformation
27
+ * @param y2 - The y-coordinate for gradient transformation
28
+ * @param focalPoint - The focal point of the gradient (0-1), defaults to 0
29
+ */
12
30
  constructor(
13
31
  private x0: number,
14
32
  private y0: number,
@@ -38,12 +56,23 @@ export class RadialGradient {
38
56
  }
39
57
  }
40
58
 
59
+ /**
60
+ * Adds a color stop to the gradient
61
+ * @param offset - The position of the color stop (0-1)
62
+ * @param color - The color value (any valid CSS color string)
63
+ */
41
64
  addColorStop(offset: number, color: string) {
42
65
  if (this.gradient) {
43
66
  this.gradient.addColorStop(offset, color);
44
67
  }
45
68
  }
46
69
 
70
+ /**
71
+ * Renders the gradient and returns the texture with its transformation matrix
72
+ * @param options - Render options
73
+ * @param options.translate - Optional translation coordinates
74
+ * @returns Object containing the texture and transformation matrix
75
+ */
47
76
  render({ translate }: { translate?: { x: number; y: number } } = {}) {
48
77
  const { x0, y0, x1, y1, x2, y2, focalPoint } = this;
49
78
  const defaultSize = this.size;
@@ -0,0 +1,7 @@
1
+ export function isPercent(value?: string | number) {
2
+ if (!value) return false
3
+ if (typeof value === "string") {
4
+ return value.endsWith("%")
5
+ }
6
+ return false
7
+ }
@@ -0,0 +1,70 @@
1
+ import { WritableSignal } from "@signe/reactive";
2
+
3
+ export type TabindexBoundaryMode = "wrap" | "clamp" | "none";
4
+
5
+ export type TabindexBounds =
6
+ | { count: () => number; min?: number }
7
+ | { min: number; max: number };
8
+
9
+ type TabindexNavigator = {
10
+ next: (delta: number) => void;
11
+ set: (value: number) => void;
12
+ };
13
+
14
+ function resolveBounds(bounds: TabindexBounds): { min: number; max: number; size: number } | null {
15
+ if ("count" in bounds) {
16
+ const count = bounds.count();
17
+ if (!Number.isFinite(count) || count <= 0) return null;
18
+ const min = bounds.min ?? 0;
19
+ const max = min + count - 1;
20
+ return { min, max, size: count };
21
+ }
22
+
23
+ const min = bounds.min;
24
+ const max = bounds.max;
25
+ if (!Number.isFinite(min) || !Number.isFinite(max) || max < min) return null;
26
+ return { min, max, size: max - min + 1 };
27
+ }
28
+
29
+ function normalizeValue(
30
+ value: number,
31
+ current: number,
32
+ bounds: { min: number; max: number; size: number },
33
+ mode: TabindexBoundaryMode
34
+ ): number {
35
+ if (mode === "clamp") {
36
+ return Math.min(bounds.max, Math.max(bounds.min, value));
37
+ }
38
+
39
+ if (mode === "none") {
40
+ return value < bounds.min || value > bounds.max ? current : value;
41
+ }
42
+
43
+ // wrap
44
+ const size = bounds.size;
45
+ if (size <= 0) return current;
46
+ const offset = value - bounds.min;
47
+ const wrapped = ((offset % size) + size) % size;
48
+ return bounds.min + wrapped;
49
+ }
50
+
51
+ export function createTabindexNavigator(
52
+ tabindex: WritableSignal<number>,
53
+ bounds: TabindexBounds,
54
+ mode: TabindexBoundaryMode = "wrap"
55
+ ): TabindexNavigator {
56
+ const applyValue = (value: number) => {
57
+ const current = tabindex();
58
+ const resolved = resolveBounds(bounds);
59
+ if (!resolved) return;
60
+ const nextValue = normalizeValue(value, current, resolved, mode);
61
+ if (nextValue !== current) {
62
+ tabindex.set(nextValue);
63
+ }
64
+ };
65
+
66
+ return {
67
+ next: (delta: number) => applyValue(tabindex() + delta),
68
+ set: (value: number) => applyValue(value),
69
+ };
70
+ }
@@ -0,0 +1,42 @@
1
+ import { bootstrapCanvas, Canvas, ComponentInstance, Element, h } from "canvasengine";
2
+ import type { Application } from "pixi.js";
3
+
4
+ export class TestBed {
5
+ private static lastApp: Application | null = null;
6
+
7
+ static async createComponent(
8
+ component: any,
9
+ props: any = {},
10
+ children: any = [],
11
+ options: { enableLayout?: boolean } = {}
12
+ ): Promise<Element<ComponentInstance>> {
13
+ if (TestBed.lastApp) {
14
+ try {
15
+ TestBed.lastApp.destroy(
16
+ { removeView: true },
17
+ { children: true, texture: true, textureSource: true, context: true }
18
+ );
19
+ } catch {
20
+ // ignore cleanup errors in test environment
21
+ }
22
+ TestBed.lastApp = null;
23
+ }
24
+
25
+ const root = document.getElementById('root');
26
+ if (root) {
27
+ root.innerHTML = '';
28
+ }
29
+
30
+ const comp = () => h(Canvas, {
31
+ tickStart: false
32
+ }, h(component, props, children))
33
+ const enableLayout = options.enableLayout ?? true;
34
+ const { canvasElement, app } = await bootstrapCanvas(root, comp, {
35
+ enableLayout,
36
+ ...(enableLayout ? { layout: { throttle: 0 } } : {})
37
+ })
38
+ app.render()
39
+ TestBed.lastApp = app as Application;
40
+ return canvasElement.props.children?.[0]
41
+ }
42
+ }
package/tsconfig.json CHANGED
@@ -1,27 +1,22 @@
1
1
  {
2
+ "extends": "../../tsconfig.json",
2
3
  "compilerOptions": {
3
- "target": "ES2020",
4
- "lib": ["dom", "esnext"],
5
- "module": "ES2020",
6
- "outDir": "./lib",
4
+ "outDir": "dist",
5
+ "declaration": true,
6
+ "emitDeclarationOnly": false,
7
+ "declarationMap": true,
7
8
  "rootDir": "src",
8
- "strict": true,
9
- "sourceMap": true,
10
- "strictNullChecks": true,
11
- "strictPropertyInitialization": false,
12
- "moduleResolution": "Bundler",
13
- "esModuleInterop": true,
14
- "removeComments": false,
15
- "noUnusedParameters": false,
16
- "noUnusedLocals": false,
17
- "noImplicitThis": false,
9
+ "module": "ESNext",
10
+ "strict": false,
18
11
  "noImplicitAny": false,
19
- "noImplicitReturns": false,
20
- "declaration": true,
21
- "experimentalDecorators": true,
22
- "emitDecoratorMetadata": true,
23
- "stripInternal": true,
24
- "skipLibCheck": true,
25
- "types": ["node"]
26
- }
27
- }
12
+ "strictNullChecks": false,
13
+ "strictPropertyInitialization": false
14
+ },
15
+ "include": [
16
+ "src/**/*"
17
+ ],
18
+ "exclude": [
19
+ "dist",
20
+ "node_modules"
21
+ ]
22
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { defineConfig } from 'vite'
2
+ import { resolve } from 'path'
3
+ import dts from 'vite-plugin-dts'
4
+
5
+ export default defineConfig({
6
+ plugins: [dts()],
7
+ build: {
8
+ lib: {
9
+ entry: resolve(__dirname, 'src/index.ts'),
10
+ name: 'CanvasEngine'
11
+ },
12
+ rollupOptions: {
13
+ external: ['pixi.js'],
14
+ output: [
15
+ // ESM build
16
+ {
17
+ format: 'es',
18
+ dir: 'dist',
19
+ entryFileNames: 'index.js'
20
+ },
21
+ // IIFE build for global usage
22
+ {
23
+ format: 'iife',
24
+ dir: 'dist',
25
+ entryFileNames: 'index.global.js',
26
+ name: 'CanvasEngine',
27
+ globals: {
28
+ 'pixi.js': 'PIXI'
29
+ },
30
+ }
31
+ ]
32
+ },
33
+ minify: true,
34
+ sourcemap: true
35
+ },
36
+ define: {
37
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
38
+ }
39
+ })
package/README.md DELETED
@@ -1,79 +0,0 @@
1
- # CanvasEngine - A reactive HTML5 Canvas management library built on top of PixiJS
2
-
3
- ![CanvasEngine](logo.png)
4
-
5
- CanvasEngine is a reactive HTML5 Canvas management library built on top of PixiJS. It provides a component-oriented approach to canvas rendering, similar to modern frontend frameworks.
6
-
7
- Features:
8
- - Reactive components
9
- - Use flex in Canvas !
10
- - Easy Animation system
11
- - Keyboard, Gamepad et Virtual Joystick
12
- - Tiled Map Editor integration
13
- - Particle Emitter
14
- - Audio System
15
-
16
- ## Note: Performance Comparison with Pixi React
17
-
18
- CanvasEngine offers significant performance advantages over Pixi React. While Pixi React relies on React's detection cycles in addition to Pixi's traversal, which can be resource-intensive, CanvasEngine takes a more granular approach. It only updates the specific elements that have changed, resulting in more efficient rendering and better overall performance.
19
-
20
- ## Installation
21
-
22
- ```bash
23
- npx degit RSamaium/CanvasEngine/starter my-project
24
- cd my-project
25
- npm install
26
- npm run dev # and go to localhost:5173
27
- ```
28
-
29
- ## Documentation
30
-
31
- https://canvasengine.net
32
-
33
- ## Example:
34
-
35
- ```html
36
- <Container flexDirection="column" width="500px">
37
- <Sprite
38
- image="/assets/logo.png"
39
- anchor="0.5"
40
- rotation
41
- scale
42
- @pointerenter={onEnter}
43
- @pointerleave={onLeave}
44
- />
45
- <Text text size="70" fontFamily="Helvetica" x="90" y="-30" />
46
- </Container>
47
-
48
- <script>
49
- import { signal, tick, animatedSignal, Easing } from "canvasengine";
50
-
51
- const { text } = defineProps();
52
- const rotation = signal(0);
53
- const scale = animatedSignal(1, {
54
- duration: 300,
55
- ease: Easing.easeInOut,
56
- });
57
-
58
- tick(() => {
59
- rotation.update(rotation => rotation + 0.01);
60
- });
61
-
62
- const onEnter = () => {
63
- scale.set(1.5);
64
- };
65
-
66
- const onLeave = () => {
67
- scale.set(1);
68
- };
69
- </script>
70
- ```
71
-
72
- ## Contributing
73
-
74
- ```bash
75
- git clone https://github.com/RSamaium/CanvasEngine.git
76
- cd CanvasEngine
77
- npm install
78
- npm run dev
79
- ```
@@ -1,9 +0,0 @@
1
- declare function canvasengine(): {
2
- name: string;
3
- transform(code: string, id: string): {
4
- code: string;
5
- map: null;
6
- } | undefined;
7
- };
8
-
9
- export { canvasengine as default };
@@ -1,119 +0,0 @@
1
- // index.ts
2
- import { createFilter } from "vite";
3
- import { parse } from "acorn";
4
- import fs from "fs";
5
- import pkg from "peggy";
6
- import path from "path";
7
- import * as ts from "typescript";
8
- import { fileURLToPath } from "url";
9
- var { generate } = pkg;
10
- var DEV_SRC = "../../src";
11
- function canvasengine() {
12
- const filter = createFilter("**/*.ce");
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = path.dirname(__filename);
15
- const grammar = fs.readFileSync(
16
- path.join(__dirname, "grammar.pegjs").replace("dist/grammar.pegjs", "grammar.pegjs"),
17
- "utf8"
18
- );
19
- const parser = generate(grammar);
20
- const isDev = process.env.NODE_ENV === "dev";
21
- const FLAG_COMMENT = "/*--[TPL]--*/";
22
- const PRIMITIVE_COMPONENTS = [
23
- "Canvas",
24
- "Sprite",
25
- "Text",
26
- "Joystick",
27
- "Viewport",
28
- "Graphics",
29
- "Container",
30
- "ImageMap",
31
- "NineSliceSprite",
32
- "Rect",
33
- "Circle",
34
- "svg"
35
- ];
36
- return {
37
- name: "vite-plugin-ce",
38
- transform(code, id) {
39
- if (!filter(id)) return;
40
- const scriptMatch = code.match(/<script>([\s\S]*?)<\/script>/);
41
- let scriptContent = scriptMatch ? scriptMatch[1].trim() : "";
42
- let template = code.replace(/<script>[\s\S]*?<\/script>/, "").replace(/^\s+|\s+$/g, "");
43
- template = template.replace(/<svg>([\s\S]*?)<\/svg>/g, (match, content) => {
44
- return `<Svg content="${content.trim()}" />`;
45
- });
46
- const parsedTemplate = parser.parse(template);
47
- scriptContent += FLAG_COMMENT + parsedTemplate;
48
- let transpiledCode = ts.transpileModule(scriptContent, {
49
- compilerOptions: {
50
- module: ts.ModuleKind.Preserve
51
- }
52
- }).outputText;
53
- transpiledCode = transpiledCode.split(FLAG_COMMENT)[0];
54
- const parsed = parse(transpiledCode, {
55
- sourceType: "module",
56
- ecmaVersion: 2020
57
- });
58
- const imports = parsed.body.filter(
59
- (node) => node.type === "ImportDeclaration"
60
- );
61
- const nonImportCode = parsed.body.filter((node) => node.type !== "ImportDeclaration").map((node) => transpiledCode.slice(node.start, node.end)).join("\n");
62
- let importsCode = imports.map((imp) => {
63
- let importCode = transpiledCode.slice(imp.start, imp.end);
64
- if (isDev && importCode.includes("from 'canvasengine'")) {
65
- importCode = importCode.replace(
66
- "from 'canvasengine'",
67
- `from '${DEV_SRC}'`
68
- );
69
- }
70
- return importCode;
71
- }).join("\n");
72
- const requiredImports = ["h", "computed", "cond", "loop"];
73
- const missingImports = requiredImports.filter(
74
- (importName) => !imports.some(
75
- (imp) => imp.specifiers && imp.specifiers.some(
76
- (spec) => spec.type === "ImportSpecifier" && spec.imported && "name" in spec.imported && spec.imported.name === importName
77
- )
78
- )
79
- );
80
- if (missingImports.length > 0) {
81
- const additionalImportCode = `import { ${missingImports.join(
82
- ", "
83
- )} } from ${isDev ? `'${DEV_SRC}'` : "'canvasengine'"};`;
84
- importsCode = `${additionalImportCode}
85
- ${importsCode}`;
86
- }
87
- const primitiveImports = PRIMITIVE_COMPONENTS.filter(
88
- (component) => parsedTemplate.includes(`h(${component}`)
89
- );
90
- primitiveImports.forEach((component) => {
91
- const importStatement = `import { ${component} } from ${isDev ? `'${DEV_SRC}'` : "'canvasengine'"};`;
92
- if (!importsCode.includes(importStatement)) {
93
- importsCode = `${importStatement}
94
- ${importsCode}`;
95
- }
96
- });
97
- const output = String.raw`
98
- ${importsCode}
99
- import { useProps, useDefineProps } from ${isDev ? `'${DEV_SRC}'` : "'canvasengine'"}
100
-
101
- export default function component($$props) {
102
- const $props = useProps($$props)
103
- const defineProps = useDefineProps($$props)
104
- ${nonImportCode}
105
- let $this = ${parsedTemplate}
106
- return $this
107
- }
108
- `;
109
- return {
110
- code: output,
111
- map: null
112
- };
113
- }
114
- };
115
- }
116
- export {
117
- canvasengine as default
118
- };
119
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { createFilter } from \"vite\";\nimport { parse } from \"acorn\";\nimport fs from \"fs\";\nimport pkg from \"peggy\";\nimport path from \"path\";\nimport * as ts from \"typescript\";\nimport { fileURLToPath } from 'url';\n\nconst { generate } = pkg;\n\nconst DEV_SRC = \"../../src\"\n\nexport default function canvasengine() {\n const filter = createFilter(\"**/*.ce\");\n\n // Convert import.meta.url to a file path\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n\n const grammar = fs.readFileSync(\n path.join(__dirname, \"grammar.pegjs\").replace(\"dist/grammar.pegjs\", \"grammar.pegjs\"), \n \"utf8\");\n const parser = generate(grammar);\n const isDev = process.env.NODE_ENV === \"dev\";\n const FLAG_COMMENT = \"/*--[TPL]--*/\";\n\n const PRIMITIVE_COMPONENTS = [\n \"Canvas\",\n \"Sprite\",\n \"Text\",\n \"Joystick\",\n \"Viewport\",\n \"Graphics\",\n \"Container\",\n \"ImageMap\",\n \"NineSliceSprite\",\n \"Rect\",\n \"Circle\",\n \"svg\"\n ];\n\n return {\n name: \"vite-plugin-ce\",\n transform(code: string, id: string) {\n if (!filter(id)) return;\n\n // Extract the script content\n const scriptMatch = code.match(/<script>([\\s\\S]*?)<\\/script>/);\n let scriptContent = scriptMatch ? scriptMatch[1].trim() : \"\";\n \n // Transform SVG tags to Svg components\n let template = code.replace(/<script>[\\s\\S]*?<\\/script>/, \"\")\n .replace(/^\\s+|\\s+$/g, '');\n \n // Add SVG transformation\n template = template.replace(/<svg>([\\s\\S]*?)<\\/svg>/g, (match, content) => {\n return `<Svg content=\"${content.trim()}\" />`;\n });\n \n const parsedTemplate = parser.parse(template);\n\n // trick to avoid typescript remove imports in scriptContent\n scriptContent += FLAG_COMMENT + parsedTemplate\n\n let transpiledCode = ts.transpileModule(scriptContent, {\n compilerOptions: {\n module: ts.ModuleKind.Preserve,\n },\n }).outputText;\n\n // remove code after /*---*/\n transpiledCode = transpiledCode.split(FLAG_COMMENT)[0]\n\n // Use Acorn to parse the script content\n const parsed = parse(transpiledCode, {\n sourceType: \"module\",\n ecmaVersion: 2020,\n });\n\n // Extract imports\n const imports = parsed.body.filter(\n (node) => node.type === \"ImportDeclaration\"\n );\n\n // Extract non-import statements from scriptContent\n const nonImportCode = parsed.body\n .filter((node) => node.type !== \"ImportDeclaration\")\n .map((node) => transpiledCode.slice(node.start, node.end))\n .join(\"\\n\");\n\n let importsCode = imports\n .map((imp) => {\n let importCode = transpiledCode.slice(imp.start, imp.end);\n if (isDev && importCode.includes(\"from 'canvasengine'\")) {\n importCode = importCode.replace(\n \"from 'canvasengine'\",\n `from '${DEV_SRC}'`\n );\n }\n return importCode;\n })\n .join(\"\\n\");\n\n // Define an array for required imports\n const requiredImports = [\"h\", \"computed\", \"cond\", \"loop\"];\n\n // Check for missing imports\n const missingImports = requiredImports.filter(\n (importName) =>\n !imports.some(\n (imp) =>\n imp.specifiers &&\n imp.specifiers.some(\n (spec) =>\n spec.type === \"ImportSpecifier\" &&\n spec.imported && \n 'name' in spec.imported &&\n spec.imported.name === importName\n )\n )\n );\n\n // Add missing imports\n if (missingImports.length > 0) {\n const additionalImportCode = `import { ${missingImports.join(\n \", \"\n )} } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"};`;\n importsCode = `${additionalImportCode}\\n${importsCode}`;\n }\n\n // Check for primitive components in parsedTemplate\n const primitiveImports = PRIMITIVE_COMPONENTS.filter((component) =>\n parsedTemplate.includes(`h(${component}`)\n );\n\n // Add missing imports for primitive components\n primitiveImports.forEach((component) => {\n const importStatement = `import { ${component} } from ${\n isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"\n };`;\n if (!importsCode.includes(importStatement)) {\n importsCode = `${importStatement}\\n${importsCode}`;\n }\n });\n\n // Generate the output\n const output = String.raw`\n ${importsCode}\n import { useProps, useDefineProps } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"}\n\n export default function component($$props) {\n const $props = useProps($$props)\n const defineProps = useDefineProps($$props)\n ${nonImportCode}\n let $this = ${parsedTemplate}\n return $this\n }\n `;\n\n return {\n code: output,\n map: null,\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,180 +0,0 @@
1
- {
2
- function generateError(message, location) {
3
- const { start, end } = location;
4
- const errorMessage = `${message}\n` +
5
- `at line ${start.line}, column ${start.column} to line ${end.line}, column ${end.column}`;
6
- throw new Error(errorMessage);
7
- }
8
- }
9
-
10
- start
11
- = _ elements:(element)* _ {
12
- if (elements.length === 1) {
13
- return elements[0];
14
- }
15
- return `[${elements.join(',')}]`;
16
- }
17
-
18
- element
19
- = forLoop
20
- / ifCondition
21
- / selfClosingElement
22
- / openCloseElement
23
- / comment
24
-
25
- selfClosingElement
26
- = _ "<" _ tagName:tagName _ attributes:attributes _ "/>" _ {
27
- const attrs = attributes.length > 0 ? `{ ${attributes.join(', ')} }` : null;
28
- return attrs ? `h(${tagName}, ${attrs})` : `h(${tagName})`;
29
- }
30
-
31
- openCloseElement
32
- = "<" _ tagName:tagName _ attributes:attributes _ ">" _ content:content _ "</" _ closingTagName:tagName _ ">" {
33
- if (tagName !== closingTagName) {
34
- error("Mismatched opening and closing tags");
35
- }
36
- const attrs = attributes.length > 0 ? `{ ${attributes.join(', ')} }` : null;
37
- const children = content ? content : null;
38
- if (attrs && children) {
39
- return `h(${tagName}, ${attrs}, ${children})`;
40
- } else if (attrs) {
41
- return `h(${tagName}, ${attrs})`;
42
- } else if (children) {
43
- return `h(${tagName}, null, ${children})`;
44
- } else {
45
- return `h(${tagName})`;
46
- }
47
- }
48
-
49
- / "<" _ tagName:tagName _ attributes:attributes _ {
50
- generateError("Syntaxe d'élément invalide", location());
51
- }
52
-
53
- attributes
54
- = attrs:(attribute (_ attribute)*)? {
55
- return attrs
56
- ? [attrs[0]].concat(attrs[1].map(a => a[1]))
57
- : [];
58
- }
59
-
60
- attribute
61
- = staticAttribute
62
- / dynamicAttribute
63
- / eventHandler
64
-
65
- eventHandler
66
- = "@" eventName:identifier _ "=" _ "{" _ handlerName:attributeValue _ "}" {
67
- return `${eventName}: ${handlerName}`;
68
- }
69
- / "@" eventName:attributeName _ {
70
- return eventName;
71
- }
72
-
73
- dynamicAttribute
74
- = attributeName:attributeName _ "=" _ "{" _ attributeValue:attributeValue _ "}" {
75
- if (attributeValue.trim().match(/^[a-zA-Z_]\w*$/)) {
76
- return `${attributeName}: ${attributeValue}`;
77
- } else {
78
- return `${attributeName}: computed(() => ${attributeValue.replace(/@?[a-zA-Z_][a-zA-Z0-9_]*(?!:)/g, (match) => {
79
- if (match.startsWith('@')) {
80
- return match.substring(1);
81
- }
82
- return `${match}()`;
83
- })})`;
84
- }
85
- }
86
- / attributeName:attributeName _ {
87
- return attributeName;
88
- }
89
-
90
- attributeValue
91
- = $([^{}]* ("{" [^{}]* "}" [^{}]*)*) {
92
- const t = text().trim()
93
- if (t.startsWith("{") && t.endsWith("}")) {
94
- return `(${t})`;
95
- }
96
- return t
97
- }
98
-
99
- staticAttribute
100
- = attributeName:attributeName _ "=" _ "\"" attributeValue:staticValue "\"" {
101
- return `${attributeName}: ${attributeValue}`;
102
- }
103
-
104
- eventAttribute
105
- = "(" _ eventName:eventName _ ")" _ "=" _ "\"" eventAction:eventAction "\"" {
106
- return `${eventName}: () => { ${eventAction} }`;
107
- }
108
-
109
- staticValue
110
- = [^"]+ {
111
- var val = text();
112
- return isNaN(val) ? `'${val}'` : val;
113
- }
114
-
115
- content
116
- = elements:(element)* {
117
- const filteredElements = elements.filter(el => el !== null);
118
- if (filteredElements.length === 0) return null;
119
- if (filteredElements.length === 1) return filteredElements[0];
120
- return `[${filteredElements.join(', ')}]`;
121
- }
122
-
123
- textNode
124
- = text:$([^<]+) {
125
- const trimmed = text.trim();
126
- return trimmed ? `'${trimmed}'` : null;
127
- }
128
-
129
- textElement
130
- = text:[^<>]+ {
131
- const trimmed = text.join('').trim();
132
- return trimmed ? JSON.stringify(trimmed) : null;
133
- }
134
-
135
- forLoop
136
- = _ "@for" _ "(" _ variableName:identifier _ "of" _ iterable:identifier _ ")" _ "{" _ content:content _ "}" _ {
137
- return `loop(${iterable}, (${variableName}) => ${content})`;
138
- }
139
-
140
- ifCondition
141
- = _ "@if" _ "(" _ condition:condition _ ")" _ "{" _ content:content _ "}" _ {
142
- return `cond(${condition}, () => ${content})`;
143
- }
144
-
145
- tagName
146
- = [a-zA-Z][a-zA-Z0-9]* { return text(); }
147
-
148
- attributeName
149
- = [a-zA-Z][a-zA-Z0-9-]* { return text(); }
150
-
151
- eventName
152
- = [a-zA-Z][a-zA-Z0-9-]* { return text(); }
153
-
154
- variableName
155
- = [a-zA-Z_][a-zA-Z0-9_]* { return text(); }
156
-
157
- iterable
158
- = [a-zA-Z_][a-zA-Z0-9_]* { return text(); }
159
-
160
- condition
161
- = $([^)]*) { return text().trim(); }
162
-
163
- eventAction
164
- = [^"]* { return text(); }
165
-
166
- _ 'whitespace'
167
- = [ \t\n\r]*
168
-
169
- identifier
170
- = [a-zA-Z_][a-zA-Z0-9_]* { return text(); }
171
-
172
- comment
173
- = singleComment+ {
174
- return null
175
- }
176
-
177
- singleComment
178
- = "<!--" _ content:((!("-->") .)* "-->") _ {
179
- return null;
180
- }