@vectojs/core 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,9 +10,10 @@ export declare class DOMPortalEntity extends Entity {
10
10
  lastHeight: string;
11
11
  lastTransform: string;
12
12
  lastZIndex: string;
13
+ lastOpacity: string;
13
14
  constructor(domElement: HTMLElement, width?: number, height?: number, id?: string);
14
15
  isPointInside(globalX: number, globalY: number): boolean;
15
- add(child: Entity): this;
16
+ add(_child: Entity): this;
16
17
  render(): void;
17
18
  destroy(): void;
18
19
  }
@@ -8,6 +8,15 @@ export interface Point {
8
8
  x: number;
9
9
  y: number;
10
10
  }
11
+ /** Six-scalar 2D affine transform matching CanvasRenderingContext2D. */
12
+ export interface AffineTransform {
13
+ a: number;
14
+ b: number;
15
+ c: number;
16
+ d: number;
17
+ e: number;
18
+ f: number;
19
+ }
11
20
  /**
12
21
  * An axis-aligned bounding box in an entity's local coordinate space.
13
22
  *
@@ -114,9 +123,10 @@ export declare class VectoJSEvent<N = unknown> {
114
123
  readonly nativeEvent: N | undefined;
115
124
  /** Whether the event bubbles past its target (capture always runs). */
116
125
  readonly bubbles: boolean;
126
+ private readonly explicitScenePoint;
117
127
  private stopped;
118
128
  private stoppedImmediate;
119
- constructor(type: VectoEvent, target: Entity, nativeEvent?: N, bubbles?: boolean);
129
+ constructor(type: VectoEvent, target: Entity, nativeEvent?: N, bubbles?: boolean, scenePoint?: Point);
120
130
  /** Stop the event from reaching the next node in the propagation path. */
121
131
  stopPropagation(): void;
122
132
  /** Stop propagation AND skip any remaining listeners on the current node. */
@@ -137,6 +147,19 @@ export declare class VectoJSEvent<N = unknown> {
137
147
  get clientX(): number | undefined;
138
148
  /** Native pointer Y, if this wraps a pointer/mouse event. */
139
149
  get clientY(): number | undefined;
150
+ private get resolvedScenePoint();
151
+ /** Pointer X in the Scene's logical coordinate space. */
152
+ get sceneX(): number | undefined;
153
+ /** Pointer Y in the Scene's logical coordinate space. */
154
+ get sceneY(): number | undefined;
155
+ /** Pointer X local to the entity whose listener is currently running. */
156
+ get localX(): number | undefined;
157
+ /** Pointer Y local to the entity whose listener is currently running. */
158
+ get localY(): number | undefined;
159
+ get shiftKey(): boolean;
160
+ get ctrlKey(): boolean;
161
+ get altKey(): boolean;
162
+ get metaKey(): boolean;
140
163
  /** Native key, if this wraps a keyboard event. */
141
164
  get key(): string | undefined;
142
165
  }
@@ -263,6 +286,7 @@ export declare abstract class Entity {
263
286
  * that need to seed a starting state (e.g. the presence helper's enter `from`).
264
287
  */
265
288
  protected setImmediate(prop: AnimatableProp, v: number): void;
289
+ private _settleDriver;
266
290
  private _spawnDriver;
267
291
  /** Assignment path when a declarative transition is configured for `prop`. */
268
292
  private _animateProp;
@@ -342,6 +366,23 @@ export declare abstract class Entity {
342
366
  * @returns World-space {@link Point} for this entity.
343
367
  */
344
368
  getGlobalPosition(): Point;
369
+ /**
370
+ * Return the exact accumulated Canvas `T * S * R` transform for this entity.
371
+ */
372
+ getWorldTransform(): AffineTransform;
373
+ /** Convert a point from this entity's local space to Scene/world space. */
374
+ localToWorld(localX: number, localY: number): Point;
375
+ /**
376
+ * Convert a Scene/world point into this entity's local space.
377
+ * Returns `null` when the accumulated transform is singular.
378
+ */
379
+ worldToLocal(worldX: number, worldY: number): Point | null;
380
+ /**
381
+ * Return the entity's local bounds transformed into a world-space AABB.
382
+ * Falls back to the entity's `[0, 0, width, height]` box when `getBounds()`
383
+ * does not provide a render-specific box.
384
+ */
385
+ getWorldBounds(): Bounds;
345
386
  /**
346
387
  * Accumulated world scale factors: this entity's own `scaleX`/`scaleY` times
347
388
  * those of every ancestor (excluding the scene root). Useful for mapping a
@@ -393,12 +434,12 @@ export declare abstract class Entity {
393
434
  * Opt into the renderer's draw-call batching fast-path for point-cloud /
394
435
  * particle entities that draw as a single filled circle at their local origin.
395
436
  *
396
- * When a leaf entity returns a {@link BatchCircle} and has uniform scale, the
397
- * {@link Scene} skips its per-entity `save`/`translate`/`scale`/`rotate`/
398
- * `restore` and {@link render}, emitting the circle through
399
- * {@link IRenderer.fillCircle} so runs of same-color siblings coalesce into a
400
- * single `fill()`. Returns `null` by default (normal render path). Read each
401
- * frame, so an animated color/radius is honored.
437
+ * When a leaf entity returns a {@link BatchCircle} and its accumulated
438
+ * transform is representable by the selected batch backend, the {@link Scene}
439
+ * skips its per-entity `save`/`translate`/`scale`/`rotate`/`restore` and
440
+ * {@link render}. Canvas mode or an unsupported affine transform uses the
441
+ * normal render path, so implementations must keep {@link render} correct.
442
+ * Returns `null` by default. Read each frame, so animated color/radius works.
402
443
  *
403
444
  * @returns The circle to batch, or `null` to use the normal {@link render} path.
404
445
  */
@@ -28,7 +28,7 @@ export interface SceneOptions {
28
28
  /**
29
29
  * Backend for particle simulation and rendering:
30
30
  * - `'auto'` (default): tries WebGPU first, falls back to CPU if WebGPU is unavailable or fails.
31
- * - `'webgpu'`: forces WebGPU.
31
+ * - `'webgpu'`: explicitly requests WebGPU; the current runtime still falls back to CPU if initialization fails.
32
32
  * - `'cpu'`: forces CPU simulation and rendering (disabling WebGPU completely).
33
33
  */
34
34
  particleBackend?: 'auto' | 'webgpu' | 'cpu';
@@ -189,6 +189,11 @@ export declare class Scene {
189
189
  * @returns The active renderer instance.
190
190
  */
191
191
  getRenderer(): IRenderer;
192
+ /** Convert browser viewport coordinates into this Scene's logical coordinates. */
193
+ clientToScene(clientX: number, clientY: number): {
194
+ x: number;
195
+ y: number;
196
+ };
192
197
  /**
193
198
  * Add a top-level entity to the scene graph.
194
199
  *
@@ -224,6 +229,7 @@ export declare class Scene {
224
229
  * Remove an overlay entity from the overlay root.
225
230
  */
226
231
  hideOverlay(overlay: Entity): void;
232
+ private destroyEntitySubtree;
227
233
  /**
228
234
  * Tear down the Scene, halt the loop, and clean up event listeners and DOM elements.
229
235
  */
@@ -262,6 +268,8 @@ export declare class Scene {
262
268
  private hasAnyInteractive;
263
269
  private syncA11y;
264
270
  private enforceA11yDomOrder;
271
+ /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
272
+ private syncOverlayGeometry;
265
273
  getA11yTree(): A11yTreeNode[];
266
274
  private renderPortalDOM;
267
275
  private reconcilePortals;
package/package.json CHANGED
@@ -1,17 +1,15 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "A zero-DOM, Canvas 2D Entity Component System (ECS) rendering framework 60 FPS with 100,000+ entities.",
7
+ "description": "A mathematical Canvas 2D scene-graph framework with layout, events, accessibility projection, and optional GPU backends.",
8
8
  "keywords": [
9
9
  "canvas",
10
- "ecs",
11
10
  "fourier",
12
11
  "spline",
13
12
  "rendering",
14
- "60fps",
15
13
  "typescript",
16
14
  "vectorization"
17
15
  ],