effect-motion 0.4.0 → 0.5.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 +2 -2
  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 +682 -38
  9. package/dist/Entity.js +271 -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 +37 -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 +639 -350
  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 +8 -6
  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 +2 -4
  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
package/dist/Color.js CHANGED
@@ -1,8 +1,44 @@
1
+ /**
2
+ * Colors: construction, adjustment, and conversion.
3
+ *
4
+ * @remarks
5
+ * Reach for {@link hex} for CSS strings, {@link rgba} for byte components,
6
+ * or {@link tw} for the built-in Tailwind palette. Perceptual spaces
7
+ * ({@link oklch}, {@link lab}) are available when you want even lightness
8
+ * across hues.
9
+ *
10
+ * Values are immutable and every adjustment is a dual, so operations
11
+ * compose in either call style. Colors interpolate, so any fill or stroke
12
+ * animates with the ordinary tween animators.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import * as Color from "effect-motion/Color";
17
+ *
18
+ * const brand = Color.hex("#7f5af0");
19
+ * const dim = brand.pipe(Color.darken(0.6), Color.alpha(0.75));
20
+ * ```
21
+ */
1
22
  import chroma from "chroma-js";
2
23
  import { Schema } from "effect";
3
24
  import * as Function from "effect/Function";
4
25
  import * as Pipeable from "effect/Pipeable";
5
26
  const clamp = (value, minimum, maximum) => Math.min(Math.max(value, minimum), maximum);
27
+ /**
28
+ * A color with an alpha channel.
29
+ *
30
+ * @remarks
31
+ * Build one with a constructor below — {@link hex} for CSS strings,
32
+ * {@link rgba} for byte components, {@link tw} for the Tailwind palette —
33
+ * rather than the class directly.
34
+ *
35
+ * RGB channels are 0–255 while alpha is 0–1, matching CSS. Colors are
36
+ * immutable and pipeable, so adjustments compose:
37
+ * `Color.hex("#7f5af0").pipe(Color.darken(0.5), Color.alpha(0.8))`.
38
+ *
39
+ * Colors are interpolable, so any fill or stroke can be animated with the
40
+ * ordinary tween animators.
41
+ */
6
42
  export class Color extends Schema.TaggedClass()("Color", {
7
43
  "~r": Schema.Number,
8
44
  "~g": Schema.Number,
@@ -44,11 +80,35 @@ const fromChroma = (color) => {
44
80
  "~a": color._rgb._unclipped[3],
45
81
  });
46
82
  };
83
+ /** Whether `value` is a {@link Color}. */
47
84
  export const is = (value) => {
48
85
  return value instanceof Color;
49
86
  };
87
+ /**
88
+ * A color from red, green, blue (each 0–255) and optional alpha (0–1).
89
+ *
90
+ * @defaultValue `alpha` — `1`
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * Color.rgba(22, 22, 29)
95
+ * ```
96
+ */
50
97
  export const rgba = (r, g, b, alpha) => Color.of(r, g, b, alpha);
51
- /** Parse a CSS color string (`#rgb`, `#rrggbb`, `#rrggbbaa`, named, `rgb()`, …). */
98
+ /**
99
+ * Parse a CSS color string — the most convenient constructor.
100
+ *
101
+ * @remarks
102
+ * Accepts everything CSS does: `#rgb`, `#rrggbb`, `#rrggbbaa`, named colors
103
+ * like `"rebeccapurple"`, and functional forms like `rgb()` / `hsl()`.
104
+ *
105
+ * @param value - A CSS color string.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * Color.hex("#7f5af0")
110
+ * ```
111
+ */
52
112
  export const hex = (value) => {
53
113
  const c = chroma(value);
54
114
  const [r, g, b] = c.rgb();
@@ -92,6 +152,7 @@ export const gl = (g, l, r, alpha) => {
92
152
  };
93
153
  const secondIsColor = (args) => is(args[1]);
94
154
  const firstIsColor = (args) => is(args[0]);
155
+ /** Set a color's opacity (0–1), leaving its channels untouched. */
95
156
  export const alpha = Function.dual(firstIsColor, (self, amount) => {
96
157
  return new Color({
97
158
  "~r": self["~r"],
@@ -100,18 +161,34 @@ export const alpha = Function.dual(firstIsColor, (self, amount) => {
100
161
  "~a": amount,
101
162
  });
102
163
  });
164
+ /** Darken by `amount` steps in Lab space. @defaultValue `amount` — `1` */
103
165
  export const darken = Function.dual(firstIsColor, (self, amount) => {
104
166
  return fromChroma(toChroma(self).darken(amount));
105
167
  });
168
+ /** Brighten by `amount` steps in Lab space. @defaultValue `amount` — `1` */
106
169
  export const brighten = Function.dual(firstIsColor, (self, amount) => {
107
170
  return fromChroma(toChroma(self).brighten(amount));
108
171
  });
172
+ /** Increase saturation by `amount` steps. @defaultValue `amount` — `1` */
109
173
  export const saturate = Function.dual(firstIsColor, (self, amount) => {
110
174
  return fromChroma(toChroma(self).saturate(amount));
111
175
  });
176
+ /** Reduce saturation by `amount` steps. @defaultValue `amount` — `1` */
112
177
  export const desaturate = Function.dual(firstIsColor, (self, amount) => {
113
178
  return fromChroma(toChroma(self).desaturate(amount));
114
179
  });
180
+ /**
181
+ * Blend two colors, `amount` of the way from `self` to `color`.
182
+ *
183
+ * @remarks
184
+ * `mode` picks the color space the blend travels through, which changes the
185
+ * intermediate hues considerably: `"lab"` (the animators' default) keeps
186
+ * perceptual evenness, while `"rgb"` can pass through muddy midpoints.
187
+ *
188
+ * @param color - The color to blend toward.
189
+ * @param amount - 0 keeps `self`, 1 gives `color`.
190
+ * @param mode - Interpolation space.
191
+ */
115
192
  export const mix = Function.dual(secondIsColor, (self, color, amount, mode) => {
116
193
  const colorMix = chroma.mix(toChroma(self), toChroma(color), amount, mode);
117
194
  return fromChroma(colorMix);
@@ -181,8 +258,14 @@ export const bytes = (self) => ({
181
258
  b: Math.round(self.b),
182
259
  a: Math.round(self.a * 255),
183
260
  });
261
+ /** Opaque black. */
184
262
  export const black = rgba(0, 0, 0, 1);
263
+ /** Opaque white. */
185
264
  export const white = rgba(255, 255, 255, 1);
265
+ /**
266
+ * Fully transparent — the default scene background, which leaves whatever
267
+ * is behind the composition showing through.
268
+ */
186
269
  export const transparent = rgba(0, 0, 0, 0);
187
270
  export const twMap = {
188
271
  slate: {
@@ -524,6 +607,23 @@ export const twMap = {
524
607
  "950": oklch(0.271, 0.105, 12.094),
525
608
  },
526
609
  };
610
+ /**
611
+ * A color from the Tailwind palette.
612
+ *
613
+ * @remarks
614
+ * A ready-made, perceptually even set of hues — handy for getting a scene
615
+ * looking coherent without hand-picking values.
616
+ *
617
+ * @param color - Palette name, e.g. `"violet"`.
618
+ * @param shade - Lightness step, `"50"` (lightest) to `"950"` (darkest).
619
+ * @param alpha - Opacity, 0–1.
620
+ * @defaultValue `shade` — `"400"`; `alpha` — `1`
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * Color.tw("violet", "500")
625
+ * ```
626
+ */
527
627
  export const tw = (color, shade = "400", alpha = 1) => {
528
628
  const value = twMap[color][shade];
529
629
  return new Color({
@@ -1,10 +1,27 @@
1
1
  declare const EffectMotionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
2
2
  readonly _tag: "EffectMotionError";
3
3
  } & Readonly<A>;
4
+ /**
5
+ * The library's error type, raised when something outside the engine fails.
6
+ *
7
+ * @remarks
8
+ * Used at the boundaries where the outside world can go wrong — fetching a
9
+ * font, decoding an image, talking to the GPU. Because it is a tagged error,
10
+ * it appears in an Effect's error channel and can be caught by tag, rather
11
+ * than thrown.
12
+ *
13
+ * Author mistakes inside a scene are deliberately NOT this: animating a
14
+ * field that has no value, or orbiting without a point of interest, fail
15
+ * loudly as defects, because they are bugs to fix rather than conditions to
16
+ * handle.
17
+ *
18
+ * `cause` carries the underlying failure when there is one.
19
+ */
4
20
  export declare class EffectMotionError extends EffectMotionError_base<{
5
21
  readonly message: string;
6
22
  readonly cause: unknown;
7
23
  }> {
24
+ /** Build an error with a message and an optional underlying cause. */
8
25
  static of(message: string, cause?: unknown): EffectMotionError;
9
26
  }
10
27
  export {};
@@ -1,5 +1,22 @@
1
1
  import { Data } from "effect";
2
+ /**
3
+ * The library's error type, raised when something outside the engine fails.
4
+ *
5
+ * @remarks
6
+ * Used at the boundaries where the outside world can go wrong — fetching a
7
+ * font, decoding an image, talking to the GPU. Because it is a tagged error,
8
+ * it appears in an Effect's error channel and can be caught by tag, rather
9
+ * than thrown.
10
+ *
11
+ * Author mistakes inside a scene are deliberately NOT this: animating a
12
+ * field that has no value, or orbiting without a point of interest, fail
13
+ * loudly as defects, because they are bugs to fix rather than conditions to
14
+ * handle.
15
+ *
16
+ * `cause` carries the underlying failure when there is one.
17
+ */
2
18
  export class EffectMotionError extends Data.TaggedError("EffectMotionError") {
19
+ /** Build an error with a message and an optional underlying cause. */
3
20
  static of(message, cause) {
4
21
  return new EffectMotionError({ message, cause });
5
22
  }