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.
- package/README.md +2 -2
- package/dist/Camera.d.ts +186 -49
- package/dist/Camera.js +343 -76
- package/dist/Color.d.ts +101 -1
- package/dist/Color.js +101 -1
- package/dist/EffectMotionError.d.ts +17 -0
- package/dist/EffectMotionError.js +17 -0
- package/dist/Entity.d.ts +682 -38
- package/dist/Entity.js +271 -27
- package/dist/Font.d.ts +108 -0
- package/dist/Font.js +95 -0
- package/dist/Image.d.ts +71 -0
- package/dist/Image.js +50 -0
- package/dist/Instance.d.ts +73 -11
- package/dist/Instance.js +44 -11
- package/dist/Motion.d.ts +328 -53
- package/dist/Motion.js +278 -46
- package/dist/Physics.d.ts +154 -20
- package/dist/Physics.js +92 -11
- package/dist/Projection.d.ts +37 -132
- package/dist/Projection.js +33 -292
- package/dist/Resource.d.ts +26 -0
- package/dist/Resource.js +41 -0
- package/dist/Runner.d.ts +639 -350
- package/dist/Runner.js +197 -150
- package/dist/Scene.d.ts +603 -175
- package/dist/Scene.js +596 -112
- package/dist/Timing.d.ts +170 -13
- package/dist/Timing.js +124 -6
- package/dist/Tree.d.ts +39 -0
- package/dist/Tree.js +127 -0
- package/dist/index.d.ts +54 -5
- package/dist/index.js +56 -5
- package/dist/particles/Particle.d.ts +2 -2
- package/dist/particles/ParticleField.d.ts +8 -6
- package/dist/particles/ParticleField.js +8 -9
- package/dist/particles/constructors.d.ts +5 -6
- package/dist/particles/constructors.js +8 -3
- package/dist/particles/legacy.d.ts +58 -0
- package/dist/particles/legacy.js +46 -0
- package/dist/particles/simulate.js +11 -3
- package/dist/particles/step.js +14 -10
- package/dist/types.d.ts +5 -0
- package/dist/types.js +1 -0
- package/package.json +2 -4
- package/dist/CameraHelpers.d.ts +0 -70
- package/dist/CameraHelpers.js +0 -239
- package/dist/CanvasExporter.d.ts +0 -12
- package/dist/CanvasExporter.js +0 -40
- package/dist/Fonts.d.ts +0 -41
- package/dist/Fonts.js +0 -27
- package/dist/Images.d.ts +0 -33
- package/dist/Images.js +0 -24
- package/dist/PngExporter.d.ts +0 -6
- package/dist/PngExporter.js +0 -85
- package/dist/Renderer.d.ts +0 -118
- package/dist/Renderer.js +0 -508
- package/dist/Shapes.d.ts +0 -11
- package/dist/Shapes.js +0 -11
- package/dist/demo.d.ts +0 -3
- package/dist/demo.js +0 -71
- package/dist/render/dof.d.ts +0 -27
- package/dist/render/dof.js +0 -37
- package/dist/render/paint.d.ts +0 -30
- package/dist/render/paint.js +0 -36
- package/dist/render/shapes.d.ts +0 -42
- package/dist/render/shapes.js +0 -310
- package/dist/shapes/Circle.d.ts +0 -32
- package/dist/shapes/Circle.js +0 -9
- package/dist/shapes/Ellipse.d.ts +0 -35
- package/dist/shapes/Ellipse.js +0 -10
- package/dist/shapes/Group.d.ts +0 -126
- package/dist/shapes/Group.js +0 -89
- package/dist/shapes/Hud.d.ts +0 -38
- package/dist/shapes/Hud.js +0 -35
- package/dist/shapes/Image.d.ts +0 -45
- package/dist/shapes/Image.js +0 -28
- package/dist/shapes/Line.d.ts +0 -47
- package/dist/shapes/Line.js +0 -35
- package/dist/shapes/Path.d.ts +0 -107
- package/dist/shapes/Path.js +0 -32
- package/dist/shapes/Rect.d.ts +0 -51
- package/dist/shapes/Rect.js +0 -22
- package/dist/shapes/Shape2D.d.ts +0 -49
- package/dist/shapes/Shape2D.js +0 -52
- package/dist/shapes/Shapes.d.ts +0 -11
- package/dist/shapes/Shapes.js +0 -11
- package/dist/shapes/Square.d.ts +0 -32
- package/dist/shapes/Square.js +0 -11
- package/dist/shapes/Text.d.ts +0 -51
- package/dist/shapes/Text.js +0 -24
package/dist/Physics.js
CHANGED
|
@@ -4,12 +4,36 @@ import * as Entity from "./Entity.js";
|
|
|
4
4
|
import * as Instance from "./Instance.js";
|
|
5
5
|
import * as Runner from "./Runner.js";
|
|
6
6
|
import * as Scene from "./Scene.js";
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* The spring used when a call names none: quick and only lightly damped, so
|
|
9
|
+
* it overshoots a little before settling.
|
|
10
|
+
*/
|
|
8
11
|
export const defaultSpring = {
|
|
9
12
|
mass: 0.05,
|
|
10
13
|
stiffness: 10,
|
|
11
14
|
damping: 0.5,
|
|
12
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* The named spring presets, each a calibrated point in `{ mass, stiffness,
|
|
18
|
+
* damping }` space. Pass the NAME to any spring animator — it autocompletes.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* Durations below are measured for a 100px move at 60fps and scale with
|
|
22
|
+
* distance; a spring's length is emergent, so treat them as character, not
|
|
23
|
+
* contract:
|
|
24
|
+
*
|
|
25
|
+
* - `strike` — hardest and fastest, launched with initial velocity (~0.7s).
|
|
26
|
+
* - `jump` — a quick launched hop (~1.4s).
|
|
27
|
+
* - `smooth` — mild overshoot, unobtrusive (~2s).
|
|
28
|
+
* - `beat` — a small, tight pulse; the least overshoot of the set (~2.6s).
|
|
29
|
+
* - `swing` — a relaxed, pendulum-like arc (~3.5s).
|
|
30
|
+
* - `plop` — lands heavy and wobbles noticeably (~7s).
|
|
31
|
+
* - `bounce` — barely damped, so it rings for a LONG time: about 37 seconds
|
|
32
|
+
* and 90 direction changes for a 100px move. Striking as a one-off accent,
|
|
33
|
+
* but check the frame count before putting it in a timed sequence.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link Spring} to define your own.
|
|
36
|
+
*/
|
|
13
37
|
export const springs = {
|
|
14
38
|
beat: { mass: 0.13, stiffness: 5.7, damping: 1.2, initialVelocity: 10 },
|
|
15
39
|
plop: { mass: 0.2, stiffness: 20, damping: 0.68 },
|
|
@@ -95,23 +119,80 @@ const simulate = Effect.fnUntraced(function* (from, to, springInput, fn, settleT
|
|
|
95
119
|
yield* Scene.tick;
|
|
96
120
|
});
|
|
97
121
|
const springPosition = Effect.fnUntraced(function* (instanceOrEffect, from, to, springInput, settleTolerance) {
|
|
98
|
-
const instance = yield* Instance.
|
|
99
|
-
|
|
100
|
-
|
|
122
|
+
const instance = yield* Instance.flattenInstance(instanceOrEffect);
|
|
123
|
+
// flatten the Vec3 for the simulator: it works on flat numeric records
|
|
124
|
+
// (design D2), so the tagged struct is unwrapped here and rebuilt below
|
|
125
|
+
const position = (yield* Scene.data(instance)).position;
|
|
126
|
+
const current = { x: position.x, y: position.y, z: position.z };
|
|
101
127
|
// partial targets/origins hold the missing axis at its current value
|
|
102
128
|
const target = { ...current, ...to };
|
|
103
129
|
const start = { ...current, ...(from ?? {}) };
|
|
104
|
-
yield* simulate(start, target, springInput ?? defaultSpring, (value) => Scene.update(instance, (data) =>
|
|
130
|
+
yield* simulate(start, target, springInput ?? defaultSpring, (value) => Scene.update(instance, (data) => ({
|
|
131
|
+
...data,
|
|
132
|
+
position: Entity.vec3(value),
|
|
133
|
+
})), settleTolerance);
|
|
105
134
|
return instance;
|
|
106
135
|
});
|
|
107
136
|
const firstArgIsInstance = (args) => Instance.isInstance(args[0]);
|
|
108
137
|
/**
|
|
109
|
-
* Spring an instance to a position
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
138
|
+
* Spring an instance to a position — `Motion.moveTo` with momentum instead
|
|
139
|
+
* of a duration.
|
|
140
|
+
*
|
|
141
|
+
* @remarks
|
|
142
|
+
* The animation runs until the simulation settles, then lands exactly on
|
|
143
|
+
* `to`, so chaining springs is safe: each starts precisely where the last
|
|
144
|
+
* finished, with no accumulated drift. How long that takes depends on the
|
|
145
|
+
* spring AND the distance — a longer move rings longer.
|
|
146
|
+
*
|
|
147
|
+
* Because the length is emergent, a spring is awkward to synchronize
|
|
148
|
+
* against a fixed beat. When several things must finish together, either
|
|
149
|
+
* spring them inside a `Scene.all` and let the slowest govern, or use a
|
|
150
|
+
* duration-based tween with an elastic easing.
|
|
151
|
+
*
|
|
152
|
+
* Targets are partial, like `moveTo` — naming only `x` holds the other axes.
|
|
153
|
+
* Every axis is simulated by the same spring, so a diagonal move settles as
|
|
154
|
+
* one motion.
|
|
155
|
+
*
|
|
156
|
+
* @param to - Target position; omitted axes hold their current value.
|
|
157
|
+
* @param springInput - A preset name from {@link springs}, or a custom
|
|
158
|
+
* {@link Spring}.
|
|
159
|
+
* @param settleTolerance - How close to the target (in both displacement
|
|
160
|
+
* and velocity) counts as settled. Larger ends sooner and cuts the tail.
|
|
161
|
+
* @defaultValue `springInput` — {@link defaultSpring}; `settleTolerance` — `0.001`
|
|
162
|
+
* @returns The instance, so animators chain.
|
|
163
|
+
* @see {@link spring} to start from an explicit position.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* A struck-then-settling entrance, using two different presets.
|
|
167
|
+
* ```typescript
|
|
168
|
+
* yield* badge.pipe(
|
|
169
|
+
* Physics.springTo({ y: 120 }, "strike"),
|
|
170
|
+
* Physics.springTo({ x: 300 }, "smooth"),
|
|
171
|
+
* );
|
|
172
|
+
* ```
|
|
114
173
|
*/
|
|
115
174
|
export const springTo = dual(firstArgIsInstance, (instance, to, springInput, settleTolerance) => springPosition(instance, undefined, to, springInput, settleTolerance));
|
|
116
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Like {@link springTo}, but starting from an explicit position.
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* The springy entrance: an instance declared at its resting place can still
|
|
180
|
+
* fly in from off-screen and settle, because the origin is stated rather
|
|
181
|
+
* than read from the entity. Both `from` and `to` are partial and fill
|
|
182
|
+
* missing axes from the current position.
|
|
183
|
+
*
|
|
184
|
+
* @param from - Starting position; omitted axes start at the current value.
|
|
185
|
+
* @param to - Target position; omitted axes hold their current value.
|
|
186
|
+
* @param springInput - A preset name from {@link springs}, or a custom
|
|
187
|
+
* {@link Spring}.
|
|
188
|
+
* @param settleTolerance - How close counts as settled.
|
|
189
|
+
* @defaultValue `springInput` — {@link defaultSpring}; `settleTolerance` — `0.001`
|
|
190
|
+
* @returns The instance, so animators chain.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* Drop a card in from above and let it settle where it was declared.
|
|
194
|
+
* ```typescript
|
|
195
|
+
* yield* card.pipe(Physics.spring({ y: -200 }, { y: 150 }, "plop"));
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
117
198
|
export const spring = dual(firstArgIsInstance, (instance, from, to, springInput, settleTolerance) => springPosition(instance, from, to, springInput, settleTolerance));
|
package/dist/Projection.d.ts
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
* point twice is bit-for-bit identical, which is what keeps 2.5D scenes
|
|
5
5
|
* deterministic.
|
|
6
6
|
*
|
|
7
|
-
* The model
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* The model: a camera with a world position, Euler orientation, and a focal
|
|
8
|
+
* length, looking down world -z at rest. World points are transformed into
|
|
9
|
+
* the camera's frame (the view transform, which is the inverse of the
|
|
10
|
+
* camera's own world transform), then divided by their depth in front of the
|
|
11
|
+
* camera to land on screen. Scene space is right-handed — x right, y up,
|
|
12
|
+
* origin at the viewport center, +z toward the viewer — so the camera's
|
|
13
|
+
* optical axis passes through world (0, 0) at rest.
|
|
12
14
|
*
|
|
13
15
|
* Identity invariant: the default camera (see `defaultFocalLength` and
|
|
14
16
|
* `defaultCameraZ`) projects a world point at `z = 0` to screen `(x, y)` at
|
|
@@ -23,10 +25,6 @@ export interface Vec3 {
|
|
|
23
25
|
readonly y: number;
|
|
24
26
|
readonly z: number;
|
|
25
27
|
}
|
|
26
|
-
export interface Vec2 {
|
|
27
|
-
readonly x: number;
|
|
28
|
-
readonly y: number;
|
|
29
|
-
}
|
|
30
28
|
/** The camera view, as it arrives on the frame from the runner. */
|
|
31
29
|
export interface CameraView {
|
|
32
30
|
readonly x: number;
|
|
@@ -37,11 +35,20 @@ export interface CameraView {
|
|
|
37
35
|
readonly rotZ: number;
|
|
38
36
|
readonly focalLength: number;
|
|
39
37
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* View-space distance to the intended sharp plane. Runner-filled to the
|
|
39
|
+
* resting camera distance.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Currently inert: depth-of-field rendering is not implemented, so every
|
|
43
|
+
* frame renders sharp regardless of this value.
|
|
42
44
|
*/
|
|
43
45
|
readonly focusDistance: number;
|
|
44
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Intended depth-of-field blur strength; 0 is a pinhole.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* Currently inert — see {@link CameraView.focusDistance}.
|
|
51
|
+
*/
|
|
45
52
|
readonly aperture: number;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
@@ -76,8 +83,7 @@ export interface PointOfInterest {
|
|
|
76
83
|
}
|
|
77
84
|
/**
|
|
78
85
|
* The auto-orient Euler angles (yaw + pitch, no roll) aiming a camera at
|
|
79
|
-
* `poi` from its WORLD position
|
|
80
|
-
* see `resolveCamera`). The view transform flips z before rotating
|
|
86
|
+
* `poi` from its WORLD position. The view transform flips z before rotating
|
|
81
87
|
* (in-front is +z), which inverts rotation handedness vs. world space;
|
|
82
88
|
* that subtlety is handled here, exactly once, pinned by tests that
|
|
83
89
|
* project the POI and assert it lands on the viewport center.
|
|
@@ -93,133 +99,32 @@ export declare const lookAtOrientation: (position: Vec3, poi: Vec3) => {
|
|
|
93
99
|
* camera's own frame (so a lone `rotZ` rolls about the view axis and the
|
|
94
100
|
* POI stays centered); the exact composed rotation is extracted back to
|
|
95
101
|
* the fixed Rz·Ry·Rx Euler convention the view transform consumes.
|
|
96
|
-
* Camera `x`/`y` are
|
|
97
|
-
*
|
|
98
|
-
* (one-node camera, unchanged); a partial POI is a loud
|
|
99
|
-
* user's rotation fields are never written back — derivation
|
|
100
|
-
* here, at view-assembly time.
|
|
101
|
-
*/
|
|
102
|
-
export declare const resolveCamera: (camera: CameraView & PointOfInterest, origin: Vec2) => CameraView;
|
|
103
|
-
/**
|
|
104
|
-
* The four world-space corners of a flat rectangular plane. The rect spans
|
|
105
|
-
* local `[x, x+width] × [y, y+height]` on the z=0 plane; each corner is
|
|
106
|
-
* rotated about the rect's local origin `(x, y)` by the Euler orientation,
|
|
107
|
-
* then translated to `world` (the plane's composed world anchor minus its own
|
|
108
|
-
* local x/y, so rotation pivots on the anchor). Winding: TL, TR, BR, BL.
|
|
102
|
+
* Camera `x`/`y` are world coordinates (the center-origin frame makes a
|
|
103
|
+
* resting camera sit on the optical axis through world (0, 0)). Absent POI
|
|
104
|
+
* is a pass-through (one-node camera, unchanged); a partial POI is a loud
|
|
105
|
+
* defect. The user's rotation fields are never written back — derivation
|
|
106
|
+
* happens here, at view-assembly time.
|
|
109
107
|
*/
|
|
110
|
-
export declare const
|
|
111
|
-
x: number;
|
|
112
|
-
y: number;
|
|
113
|
-
width: number;
|
|
114
|
-
height: number;
|
|
115
|
-
}, orientation: {
|
|
116
|
-
rotX: number;
|
|
117
|
-
rotY: number;
|
|
118
|
-
rotZ: number;
|
|
119
|
-
}, world: Vec3) => [Vec3, Vec3, Vec3, Vec3];
|
|
108
|
+
export declare const resolveCamera: (camera: CameraView & PointOfInterest) => CameraView;
|
|
120
109
|
/**
|
|
121
|
-
* A world point in the camera's frame
|
|
122
|
-
* viewport center)
|
|
123
|
-
*
|
|
124
|
-
* the
|
|
125
|
-
*
|
|
110
|
+
* A world point in the camera's frame. The camera's `x`/`y` are its world
|
|
111
|
+
* position (origin at the viewport center), so a resting camera keeps
|
|
112
|
+
* world-x/y = screen-x/y at unit scale. `+z` in the result is in front of
|
|
113
|
+
* the camera: the camera looks down world -z, so a resting camera at
|
|
114
|
+
* z=focalLength sees the z=0 plane at view-z = focalLength.
|
|
126
115
|
*/
|
|
127
|
-
export declare const toView: (camera: CameraView, p: Vec3
|
|
116
|
+
export declare const toView: (camera: CameraView, p: Vec3) => Vec3;
|
|
128
117
|
/**
|
|
129
|
-
* Project a world point to screen.
|
|
130
|
-
*
|
|
131
|
-
*
|
|
118
|
+
* Project a world point to screen. The camera's optical axis passes through
|
|
119
|
+
* screen (0, 0) — the viewport center — so pan/zoom read as "into the
|
|
120
|
+
* middle of the shot", while a resting camera reproduces plain-2D
|
|
132
121
|
* placement. A point at or behind the camera (view-z <= 0) has no valid
|
|
133
122
|
* projection; `depth` is still returned for sorting, `scale` clamps to 0.
|
|
134
123
|
*/
|
|
135
|
-
export declare const project: (camera: CameraView, p: Vec3
|
|
136
|
-
/**
|
|
137
|
-
* The affine placement for a camera-facing billboard whose local origin is
|
|
138
|
-
* `anchor`: translate the anchor's projected screen point and uniformly
|
|
139
|
-
* scale by its perspective scale. Returned as SVG matrix components
|
|
140
|
-
* `(a b c d e f)` — a and d carry the scale, e/f the translation — so a shape
|
|
141
|
-
* authored in local space lands correctly without knowing about the camera.
|
|
142
|
-
*/
|
|
143
|
-
export interface Affine {
|
|
144
|
-
readonly a: number;
|
|
145
|
-
readonly b: number;
|
|
146
|
-
readonly c: number;
|
|
147
|
-
readonly d: number;
|
|
148
|
-
readonly e: number;
|
|
149
|
-
readonly f: number;
|
|
150
|
-
}
|
|
151
|
-
export declare const billboardAffine: (proj: Projected, anchor: Vec2) => Affine;
|
|
152
|
-
/**
|
|
153
|
-
* Project the world-space corners of a tilted plane to a screen polygon.
|
|
154
|
-
* The polygon is clipped against the near plane in view space
|
|
155
|
-
* (Sutherland–Hodgman, winding preserved) before the per-vertex perspective
|
|
156
|
-
* divide, so a plane crossing the camera renders its visible part instead
|
|
157
|
-
* of folding — a quad straddling the plane yields up to 5 vertices; a plane
|
|
158
|
-
* fully behind yields none (cull). Fully in front, this is plain per-corner
|
|
159
|
-
* projection: a receding plane is a true perspective trapezoid.
|
|
160
|
-
*/
|
|
161
|
-
export declare const projectPlane: (camera: CameraView, corners: ReadonlyArray<Vec3>, origin: Vec2) => Array<Vec2>;
|
|
162
|
-
/** A projected segment: exact screen endpoints plus its single sort key. */
|
|
163
|
-
export interface ProjectedSegment {
|
|
164
|
-
readonly a: Vec2;
|
|
165
|
-
readonly b: Vec2;
|
|
166
|
-
/** midpoint view-space depth of the visible (clipped) segment */
|
|
167
|
-
readonly depth: number;
|
|
168
|
-
/** perspective scale at that midpoint (focalLength / depth) */
|
|
169
|
-
readonly scale: number;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Project a world-space segment (a skeletal shape's two endpoints) to
|
|
173
|
-
* screen. Both endpoints go to view space, are clipped against the near
|
|
174
|
-
* plane (lerp to z = NEAR — the 1D case of projectPlane's polygon clip),
|
|
175
|
-
* and are projected individually, so a line spanning depth foreshortens
|
|
176
|
-
* per endpoint. Returns `undefined` when the segment lies entirely behind
|
|
177
|
-
* the near plane (cull). `depth`/`scale` come from the visible midpoint.
|
|
178
|
-
*/
|
|
179
|
-
export declare const projectSegment: (camera: CameraView, a: Vec3, b: Vec3, origin: Vec2) => ProjectedSegment | undefined;
|
|
180
|
-
/** A subpath of a skeletal path: world-space points, closed or open. */
|
|
181
|
-
export interface Subpath3 {
|
|
182
|
-
readonly points: ReadonlyArray<Vec3>;
|
|
183
|
-
readonly closed: boolean;
|
|
184
|
-
}
|
|
185
|
-
/** A projected path: screen subpaths plus the path's single sort key. */
|
|
186
|
-
export interface ProjectedPath {
|
|
187
|
-
readonly subpaths: ReadonlyArray<{
|
|
188
|
-
readonly points: ReadonlyArray<Vec2>;
|
|
189
|
-
readonly closed: boolean;
|
|
190
|
-
}>;
|
|
191
|
-
/** mean view-space depth of the near-visible points */
|
|
192
|
-
readonly depth: number;
|
|
193
|
-
/** perspective scale at that depth (focalLength / depth) */
|
|
194
|
-
readonly scale: number;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Project a skeletal path's world-space subpaths to screen — the N-point
|
|
198
|
-
* generalization of `projectSegment`. Every point goes to view space and is
|
|
199
|
-
* projected individually, so a path spanning depth foreshortens per point.
|
|
200
|
-
* Near-plane clipping is per subpath: a closed subpath clips as a polygon
|
|
201
|
-
* (Sutherland–Hodgman, winding preserved — the tilted-plane treatment); an
|
|
202
|
-
* open subpath clips per span (lerp to z = NEAR) and SPLITS into separate
|
|
203
|
-
* visible pieces when interior points fall behind the plane. Returns
|
|
204
|
-
* `undefined` when nothing survives (cull). `depth`/`scale` come from the
|
|
205
|
-
* mean view depth of all emitted points — one key per path, the same
|
|
206
|
-
* ceiling as a segment's midpoint.
|
|
207
|
-
*/
|
|
208
|
-
export declare const projectPath: (camera: CameraView, subpaths: ReadonlyArray<Subpath3>, origin: Vec2) => ProjectedPath | undefined;
|
|
209
|
-
/**
|
|
210
|
-
* Clip a screen-space segment to a rectangle (Liang–Barsky). Returns the
|
|
211
|
-
* clipped pair, or `undefined` when the segment lies entirely outside.
|
|
212
|
-
* ThorVG's software rasterizer pays stroke cost proportional to a path's
|
|
213
|
-
* full extent — offscreen included — so segments are clipped to the
|
|
214
|
-
* viewport (plus a stroke margin) before painting; a near-camera line can
|
|
215
|
-
* project tens of thousands of px wide otherwise (measured ~7× the cost
|
|
216
|
-
* of its visible part).
|
|
217
|
-
*/
|
|
218
|
-
export declare const clipSegmentToRect: (a: Vec2, b: Vec2, min: Vec2, max: Vec2) => readonly [Vec2, Vec2] | undefined;
|
|
124
|
+
export declare const project: (camera: CameraView, p: Vec3) => Projected;
|
|
219
125
|
/**
|
|
220
126
|
* The view-space depth of a world point — the painter's-sort key alone.
|
|
221
127
|
* With no camera rotation this is `camera.z - p.z`; rotation tilts the
|
|
222
|
-
* depth axis, so the full view transform is used.
|
|
223
|
-
* never depth, so a zero origin suffices.
|
|
128
|
+
* depth axis, so the full view transform is used.
|
|
224
129
|
*/
|
|
225
130
|
export declare const depthOf: (camera: CameraView, p: Vec3) => number;
|