effect-motion 0.4.0 → 0.6.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 (91) hide show
  1. package/README.md +3 -3
  2. package/dist/Camera.d.ts +186 -49
  3. package/dist/Camera.js +343 -76
  4. package/dist/Color.d.ts +101 -1
  5. package/dist/Color.js +101 -1
  6. package/dist/EffectMotionError.d.ts +17 -0
  7. package/dist/EffectMotionError.js +17 -0
  8. package/dist/Entity.d.ts +684 -30
  9. package/dist/Entity.js +281 -27
  10. package/dist/Font.d.ts +108 -0
  11. package/dist/Font.js +95 -0
  12. package/dist/Image.d.ts +71 -0
  13. package/dist/Image.js +50 -0
  14. package/dist/Instance.d.ts +73 -11
  15. package/dist/Instance.js +44 -11
  16. package/dist/Motion.d.ts +328 -53
  17. package/dist/Motion.js +278 -46
  18. package/dist/Physics.d.ts +154 -20
  19. package/dist/Physics.js +92 -11
  20. package/dist/Projection.d.ts +36 -132
  21. package/dist/Projection.js +33 -292
  22. package/dist/Resource.d.ts +26 -0
  23. package/dist/Resource.js +41 -0
  24. package/dist/Runner.d.ts +714 -349
  25. package/dist/Runner.js +197 -150
  26. package/dist/Scene.d.ts +603 -175
  27. package/dist/Scene.js +596 -112
  28. package/dist/Timing.d.ts +170 -13
  29. package/dist/Timing.js +124 -6
  30. package/dist/Tree.d.ts +39 -0
  31. package/dist/Tree.js +127 -0
  32. package/dist/index.d.ts +54 -5
  33. package/dist/index.js +56 -5
  34. package/dist/particles/Particle.d.ts +2 -2
  35. package/dist/particles/ParticleField.d.ts +44 -42
  36. package/dist/particles/ParticleField.js +8 -9
  37. package/dist/particles/constructors.d.ts +5 -6
  38. package/dist/particles/constructors.js +8 -3
  39. package/dist/particles/legacy.d.ts +58 -0
  40. package/dist/particles/legacy.js +46 -0
  41. package/dist/particles/simulate.js +11 -3
  42. package/dist/particles/step.js +14 -10
  43. package/dist/types.d.ts +5 -0
  44. package/dist/types.js +1 -0
  45. package/package.json +58 -60
  46. package/dist/CameraHelpers.d.ts +0 -70
  47. package/dist/CameraHelpers.js +0 -239
  48. package/dist/CanvasExporter.d.ts +0 -12
  49. package/dist/CanvasExporter.js +0 -40
  50. package/dist/Fonts.d.ts +0 -41
  51. package/dist/Fonts.js +0 -27
  52. package/dist/Images.d.ts +0 -33
  53. package/dist/Images.js +0 -24
  54. package/dist/PngExporter.d.ts +0 -6
  55. package/dist/PngExporter.js +0 -85
  56. package/dist/Renderer.d.ts +0 -118
  57. package/dist/Renderer.js +0 -508
  58. package/dist/Shapes.d.ts +0 -11
  59. package/dist/Shapes.js +0 -11
  60. package/dist/demo.d.ts +0 -3
  61. package/dist/demo.js +0 -71
  62. package/dist/render/dof.d.ts +0 -27
  63. package/dist/render/dof.js +0 -37
  64. package/dist/render/paint.d.ts +0 -30
  65. package/dist/render/paint.js +0 -36
  66. package/dist/render/shapes.d.ts +0 -42
  67. package/dist/render/shapes.js +0 -310
  68. package/dist/shapes/Circle.d.ts +0 -32
  69. package/dist/shapes/Circle.js +0 -9
  70. package/dist/shapes/Ellipse.d.ts +0 -35
  71. package/dist/shapes/Ellipse.js +0 -10
  72. package/dist/shapes/Group.d.ts +0 -126
  73. package/dist/shapes/Group.js +0 -89
  74. package/dist/shapes/Hud.d.ts +0 -38
  75. package/dist/shapes/Hud.js +0 -35
  76. package/dist/shapes/Image.d.ts +0 -45
  77. package/dist/shapes/Image.js +0 -28
  78. package/dist/shapes/Line.d.ts +0 -47
  79. package/dist/shapes/Line.js +0 -35
  80. package/dist/shapes/Path.d.ts +0 -107
  81. package/dist/shapes/Path.js +0 -32
  82. package/dist/shapes/Rect.d.ts +0 -51
  83. package/dist/shapes/Rect.js +0 -22
  84. package/dist/shapes/Shape2D.d.ts +0 -49
  85. package/dist/shapes/Shape2D.js +0 -52
  86. package/dist/shapes/Shapes.d.ts +0 -11
  87. package/dist/shapes/Shapes.js +0 -11
  88. package/dist/shapes/Square.d.ts +0 -32
  89. package/dist/shapes/Square.js +0 -11
  90. package/dist/shapes/Text.d.ts +0 -51
  91. package/dist/shapes/Text.js +0 -24
@@ -1,85 +0,0 @@
1
- import { deflateSync } from "node:zlib";
2
- import * as Effect from "effect/Effect";
3
- import { FileSystem } from "effect/FileSystem";
4
- import { EffectMotionError } from "./EffectMotionError.js";
5
- const SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
6
- const crcTable = (() => {
7
- const t = new Uint32Array(256);
8
- for (let n = 0; n < 256; n++) {
9
- let c = n;
10
- for (let k = 0; k < 8; k++) {
11
- c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
12
- }
13
- t[n] = c >>> 0;
14
- }
15
- return t;
16
- })();
17
- const crc32 = (bytes) => {
18
- let c = 0xffffffff;
19
- for (let i = 0; i < bytes.length; i++) {
20
- c = crcTable[(c ^ bytes[i]) & 0xff] ^ (c >>> 8);
21
- }
22
- return (c ^ 0xffffffff) >>> 0;
23
- };
24
- const chunk = (type, data) => {
25
- const typeBytes = new Uint8Array([
26
- type.charCodeAt(0),
27
- type.charCodeAt(1),
28
- type.charCodeAt(2),
29
- type.charCodeAt(3),
30
- ]);
31
- const body = new Uint8Array(typeBytes.length + data.length);
32
- body.set(typeBytes, 0);
33
- body.set(data, typeBytes.length);
34
- const out = new Uint8Array(4 + body.length + 4);
35
- const view = new DataView(out.buffer);
36
- view.setUint32(0, data.length, false);
37
- out.set(body, 4);
38
- view.setUint32(4 + body.length, crc32(body), false);
39
- return out;
40
- };
41
- /** Encode a raw RGBA8888 buffer (`width * height * 4` bytes) as a PNG. */
42
- const encodePng = Effect.fnUntraced(function* (rgba, width, height) {
43
- if (rgba.length !== width * height * 4) {
44
- return yield* Effect.fail(EffectMotionError.of(`Could not encode PNG: buffer is ${rgba.length} bytes, expected ${width * height * 4} (${width}x${height} RGBA)`));
45
- }
46
- // prepend a filter byte (0 = none) to each scanline
47
- const stride = width * 4;
48
- const raw = new Uint8Array((stride + 1) * height);
49
- for (let y = 0; y < height; y++) {
50
- raw[y * (stride + 1)] = 0;
51
- raw.set(rgba.subarray(y * stride, y * stride + stride), y * (stride + 1) + 1);
52
- }
53
- const ihdr = new Uint8Array(13);
54
- const ihdrView = new DataView(ihdr.buffer);
55
- ihdrView.setUint32(0, width, false);
56
- ihdrView.setUint32(4, height, false);
57
- ihdr[8] = 8; // bit depth
58
- ihdr[9] = 6; // color type: RGBA
59
- // [10] compression, [11] filter, [12] interlace all 0
60
- const idat = new Uint8Array(deflateSync(raw));
61
- const chunks = [
62
- SIGNATURE,
63
- chunk("IHDR", ihdr),
64
- chunk("IDAT", idat),
65
- chunk("IEND", new Uint8Array(0)),
66
- ];
67
- const total = chunks.reduce((n, c) => n + c.length, 0);
68
- const png = new Uint8Array(total);
69
- let offset = 0;
70
- for (const c of chunks) {
71
- png.set(c, offset);
72
- offset += c.length;
73
- }
74
- return png;
75
- });
76
- export const toBuffer = (fb) => {
77
- return encodePng(fb.rgba, fb.width, fb.height);
78
- };
79
- export const toFile = (fb, outPath) => {
80
- return Effect.gen(function* () {
81
- const fs = yield* FileSystem;
82
- const png = yield* toBuffer(fb);
83
- yield* fs.writeFile(outPath, png);
84
- });
85
- };
@@ -1,118 +0,0 @@
1
- import type { OwnedPaint, RenderSession, ThorvgException, ThorvgWasm } from "@effect-motion/thorvg";
2
- import * as Tvg from "@effect-motion/thorvg";
3
- import type { Canvas } from "@effect-motion/thorvg/Canvas";
4
- import * as Effect from "effect/Effect";
5
- import type * as Scope from "effect/Scope";
6
- import * as Color from "./Color.js";
7
- import type * as Entity from "./Entity.js";
8
- import * as Projection from "./Projection.js";
9
- import type { Frame } from "./Scene.js";
10
- /**
11
- * The projection handed to each paint function — how the camera places a
12
- * paintable this frame. `screen` is the projected billboard placement (an
13
- * affine the paint fn applies via `setTransform`); `depth` is the view-space
14
- * sort key; `scale` is the perspective scale (<= 0 means the anchor is behind
15
- * the camera — cull, unless a `quad` or `segment` is present). `quad`, when
16
- * present, is the projected, near-plane-clipped screen polygon of a tilted
17
- * plane (3–5 vertices — see Projection.projectPlane); a shape that can tilt
18
- * paints an exact path from these instead of applying the billboard affine.
19
- * `segment`, when present, is the exact projected screen endpoints of a
20
- * skeletal shape (Line) — each endpoint carries its own world depth, so the
21
- * pair is projected per point (see Projection.projectSegment) and the paint
22
- * fn draws it directly, skipping the billboard affine. `subpaths`, when
23
- * present, is the projected screen geometry of a skeletal path (Path): every
24
- * command point projected individually and near-plane-clipped per subpath
25
- * (see Projection.projectPath) — the paint fn emits it directly at screen
26
- * coordinates.
27
- */
28
- export interface PaintProjection {
29
- readonly screen: Projection.Affine;
30
- readonly depth: number;
31
- readonly scale: number;
32
- readonly quad?: ReadonlyArray<Projection.Vec2>;
33
- readonly segment?: readonly [Projection.Vec2, Projection.Vec2];
34
- readonly subpaths?: Projection.ProjectedPath["subpaths"];
35
- }
36
- /** The frame's render metadata, handed to paint functions. */
37
- export interface FrameMeta {
38
- readonly frameRate: number;
39
- readonly width: number;
40
- readonly height: number;
41
- readonly backgroundColor: Color.Color;
42
- /**
43
- * the active camera's view — world position `{x, y, z}`, Euler
44
- * orientation `{rotX, rotY, rotZ}`, and `focalLength` (FOV). The renderer
45
- * projects every instance through it. The resting camera (see
46
- * Camera.identity) reproduces plain-2D placement for z=0 content.
47
- */
48
- readonly camera: {
49
- readonly x: number;
50
- readonly y: number;
51
- readonly z: number;
52
- readonly rotX: number;
53
- readonly rotY: number;
54
- readonly rotZ: number;
55
- readonly focalLength: number;
56
- };
57
- }
58
- /**
59
- * Paints one entity instance onto the shared ThorVG scene. It issues ThorVG
60
- * C-API calls (make a shape, append geometry, style it, apply the projection,
61
- * add it to `scene`) — there is no intermediate description value. A container
62
- * (Group / root) paints nothing itself; its position has already composed into
63
- * its children's world coordinates by the time this is called.
64
- */
65
- export type PaintFunction<Ent extends Entity.AnyEntity> = (payload: {
66
- readonly entity: Ent;
67
- readonly id: string;
68
- readonly data: Ent["data"]["Type"];
69
- readonly projection: PaintProjection;
70
- readonly canvas: Canvas;
71
- readonly scene: OwnedPaint;
72
- readonly meta: FrameMeta;
73
- }) => Effect.Effect<void, ThorvgException, ThorvgWasm | RenderSession | Scope.Scope>;
74
- /**
75
- * A registry of paint functions keyed by entity name. `PaintFunctions<E>` is
76
- * the exhaustive map over an entity union — a built-in with no paint function
77
- * is a type error at the render call, not a runtime surprise (the old
78
- * "coverage manifest" guarantee, kept without a Context registry).
79
- */
80
- export type PaintFunctions<Entities extends Entity.AnyEntity> = {
81
- readonly [K in Entities as K["name"]]: PaintFunction<K>;
82
- };
83
- /** RGBA8888 framebuffer plus its dimensions, straight from the SW canvas. */
84
- export interface Framebuffer {
85
- readonly rgba: Uint8Array;
86
- /** physical pixel size of the rgba buffer (logical size × dpr) */
87
- readonly width: number;
88
- readonly height: number;
89
- /**
90
- * logical scene size — the resolution the buffer should be displayed at
91
- * (CSS pixels). Equals width/height when rendered at dpr 1.
92
- */
93
- readonly logicalWidth: number;
94
- readonly logicalHeight: number;
95
- }
96
- /**
97
- * Render one frame to an RGBA framebuffer, shared by both output adapters.
98
- *
99
- * Uses the RenderSession's canvas (resized in place to the frame's physical
100
- * size, cleared of the previous frame), adds a root scene, folds the frame
101
- * onto it via `Renderer.render`, then update/draw/sync and reads the SW
102
- * framebuffer. The scene and every painted shape are scoped per frame; the
103
- * canvas belongs to the session (a player mount, an export run) and is
104
- * deleted when the session closes.
105
- *
106
- * The background is painted as a filled rect (not a canvas clear color) so it
107
- * survives into the buffer the same way the SVG sink emitted a background
108
- * rect.
109
- */
110
- export declare const render: (frame: Frame, options?: {
111
- /**
112
- * device-pixel-ratio multiplier for high-dpi displays. The buffer is
113
- * rasterized at `logical × dpr` while paint functions keep working in
114
- * logical scene coordinates (the root scene is scaled). Callers display
115
- * the buffer at the logical size. Default 1 (node/export paths).
116
- */
117
- readonly dpr?: number;
118
- }) => Effect.Effect<Framebuffer, ThorvgException, Tvg.ThorvgWasm | Tvg.RenderSession | Scope.Scope>;