@weasel-js/core 1.4.4 → 1.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/CHANGELOG.md +937 -2202
- package/README.md +118 -75
- package/dist/{autoPoseDescriptor-DF1SnnSx.d.ts → autoPoseDescriptor-CvjflWJK.d.ts} +29 -26
- package/dist/{chunk-2VXGHUVL.js → chunk-BDWAA634.js} +4 -22
- package/dist/chunk-BDWAA634.js.map +1 -0
- package/dist/{chunk-R3AWPTLZ.js → chunk-MG7OXCAI.js} +2760 -4491
- package/dist/chunk-MG7OXCAI.js.map +1 -0
- package/dist/{chunk-PRGBGMH3.js → chunk-MQI4PIX3.js} +3 -3
- package/dist/chunk-MQI4PIX3.js.map +1 -0
- package/dist/{chunk-WPM42WJP.js → chunk-UCPV7JXC.js} +201 -256
- package/dist/chunk-UCPV7JXC.js.map +1 -0
- package/dist/clipboard.d.ts +2 -3
- package/dist/clone.d.ts +3 -2
- package/dist/depSchema-nMqj_qTM.d.ts +3490 -0
- package/dist/{grid-0Pbn5B2C.d.ts → grid-BrIa38gG.d.ts} +7 -10
- package/dist/index.d.ts +1996 -1229
- package/dist/index.js +4 -5
- package/dist/insert.d.ts +4 -4
- package/dist/insert.js +1 -1
- package/dist/move.d.ts +5 -6
- package/dist/move.js +3 -6
- package/dist/move.js.map +1 -1
- package/dist/{options-DbYLImvq.d.ts → options-BDyCnrp8.d.ts} +3 -2
- package/dist/poseDescriptor-CGOgIgf8.d.ts +134 -0
- package/dist/renderer.d.ts +10 -4
- package/dist/renderer.js +4 -5
- package/dist/resize.d.ts +10 -12
- package/dist/resize.js +2 -2
- package/dist/routing.d.ts +1 -142
- package/dist/routing.js +1 -1
- package/dist/routing.js.map +1 -1
- package/dist/{types-ei3UMl9R.d.ts → types-DMyo7dnM.d.ts} +12 -41
- package/dist/{types-DEALFt5F.d.ts → types-DtjCJA5r.d.ts} +9 -3
- package/package.json +13 -10
- package/dist/DrawCommand-CD-ug3d9.d.ts +0 -332
- package/dist/builtins-BXFBXegF.d.ts +0 -840
- package/dist/chunk-2VXGHUVL.js.map +0 -1
- package/dist/chunk-BL65SHCX.js +0 -573
- package/dist/chunk-BL65SHCX.js.map +0 -1
- package/dist/chunk-PRGBGMH3.js.map +0 -1
- package/dist/chunk-R3AWPTLZ.js.map +0 -1
- package/dist/chunk-WPM42WJP.js.map +0 -1
- package/dist/geometry-6fCNhAux.d.ts +0 -114
- package/dist/path-JEV2c5If.d.ts +0 -48
- package/dist/registry-BY-wI9gm.d.ts +0 -4003
- package/dist/types-BHK2dkMu.d.ts +0 -172
- package/dist/types-bcc7jcUy.d.ts +0 -594
- package/dist/view-DSQgxBJB.d.ts +0 -63
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
import { Op } from '@weasel-js/history';
|
|
2
|
-
import { S as SnapTarget, M as MoveAdapter, I as InsertAdapter } from './types-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Snapshot of modifier-key state at gesture dispatch.
|
|
6
|
-
*
|
|
7
|
-
* Lives in core rather than beside the gesture types that produce it because
|
|
8
|
-
* `core/selection/chromeState.ts` reads it, and core may not import from
|
|
9
|
-
* `interactions/`. Re-exported from `interactions/gestures/types.ts`, which
|
|
10
|
-
* is still where gesture code names it.
|
|
11
|
-
*/
|
|
12
|
-
interface ModifierState {
|
|
13
|
-
alt: boolean;
|
|
14
|
-
shift: boolean;
|
|
15
|
-
meta: boolean;
|
|
16
|
-
ctrl: boolean;
|
|
17
|
-
}
|
|
2
|
+
import { S as SnapTarget, M as MoveAdapter, I as InsertAdapter } from './types-DtjCJA5r.js';
|
|
3
|
+
import { Bounds, ModifierState, ResizeAnchor } from '@weasel-js/routing';
|
|
18
4
|
|
|
19
5
|
/** Pointer position in both world and client coords. */
|
|
20
6
|
interface PointerState {
|
|
@@ -130,31 +116,20 @@ type BehaviorMoveResult<TPose> = BehaviorResult<TPose>;
|
|
|
130
116
|
* `useMove`) and return a `BehaviorResult` shaping it (or, legacy, an
|
|
131
117
|
* override pose run through the back-compat shim). */
|
|
132
118
|
type MoveBehavior<TPose> = ActionBehavior<TPose, GroupTransform, BehaviorResult<TPose>>;
|
|
133
|
-
|
|
134
|
-
type ResizeAnchor = {
|
|
135
|
-
x: 'min' | 'max' | 'free';
|
|
136
|
-
y: 'min' | 'max' | 'free';
|
|
137
|
-
};
|
|
138
|
-
/** Minimum rect-shaped pose required by the resize machinery. */
|
|
139
|
-
interface ResizePose {
|
|
140
|
-
x: number;
|
|
141
|
-
y: number;
|
|
142
|
-
width: number;
|
|
143
|
-
height: number;
|
|
144
|
-
}
|
|
119
|
+
|
|
145
120
|
/** Per-frame proposed resize: pose plus the anchor pinning the opposite corner. */
|
|
146
|
-
interface ResizeProposed<TPose extends
|
|
121
|
+
interface ResizeProposed<TPose extends Bounds> {
|
|
147
122
|
pose: TPose;
|
|
148
123
|
anchor: ResizeAnchor;
|
|
149
124
|
}
|
|
150
125
|
/** Per-frame result a `BoundsConstraint.onMove` can return to override the proposed pose. */
|
|
151
|
-
interface ResizeMoveResult<TPose extends
|
|
126
|
+
interface ResizeMoveResult<TPose extends Bounds> {
|
|
152
127
|
pose?: TPose;
|
|
153
128
|
}
|
|
154
129
|
/** A bounds-frame constraint plugged into `useResize` / `resizeAction`.
|
|
155
130
|
* Reads/writes `{x,y,width,height}` and can override the proposed pose
|
|
156
131
|
* on each frame (e.g. lock-aspect, clamp-min-size, snap-to-grid). */
|
|
157
|
-
type BoundsConstraint<TPose extends
|
|
132
|
+
type BoundsConstraint<TPose extends Bounds> = ActionBehavior<TPose, ResizeProposed<TPose>, ResizeMoveResult<TPose>>;
|
|
158
133
|
/** Live overlay state exposed by `useResize` for rendering the in-flight resize ghost. */
|
|
159
134
|
interface ResizeOverlay<TPose> {
|
|
160
135
|
id: string;
|
|
@@ -168,11 +143,7 @@ interface ResizeOverlay<TPose> {
|
|
|
168
143
|
* resizes. */
|
|
169
144
|
leafPoses?: Map<string, TPose>;
|
|
170
145
|
}
|
|
171
|
-
|
|
172
|
-
* center of the unrotated `{x, y, width, height}`. */
|
|
173
|
-
interface RotatedPose extends ResizePose {
|
|
174
|
-
rotation: number;
|
|
175
|
-
}
|
|
146
|
+
|
|
176
147
|
/** Per-frame proposed rotation: pose plus the candidate angle in radians. */
|
|
177
148
|
interface RotateProposed<TPose> {
|
|
178
149
|
pose: TPose;
|
|
@@ -203,7 +174,7 @@ interface InsertPoint {
|
|
|
203
174
|
interface InsertProposed<TPose> {
|
|
204
175
|
start: InsertPoint;
|
|
205
176
|
current: InsertPoint;
|
|
206
|
-
bounds:
|
|
177
|
+
bounds: Bounds;
|
|
207
178
|
pose: TPose;
|
|
208
179
|
}
|
|
209
180
|
/** Per-frame result an `InsertBehavior.onMove` can return to override the start/current points. */
|
|
@@ -221,7 +192,7 @@ interface InsertOverlay<TPose> {
|
|
|
221
192
|
start: InsertPoint;
|
|
222
193
|
current: InsertPoint;
|
|
223
194
|
/** Axis-aligned bounding rect derived from `start`/`current`. */
|
|
224
|
-
bounds:
|
|
195
|
+
bounds: Bounds;
|
|
225
196
|
/** TPose constructed from `bounds` via the hook's `posefromBounds`. */
|
|
226
197
|
pose: TPose;
|
|
227
198
|
}
|
|
@@ -276,7 +247,7 @@ type PointSnapFrame = 'dragged-corner' | 'fixed-corner' | 'center' | 'origin';
|
|
|
276
247
|
* `draggedCorner` and `fixedCorner` are `null` for edge drags
|
|
277
248
|
* (`anchor.x === 'free'` or `anchor.y === 'free'`). `center` and
|
|
278
249
|
* `origin` are always present. */
|
|
279
|
-
interface PointSnapContext<TPose extends
|
|
250
|
+
interface PointSnapContext<TPose extends Bounds> {
|
|
280
251
|
draggedCorner: {
|
|
281
252
|
worldX: number;
|
|
282
253
|
worldY: number;
|
|
@@ -305,7 +276,7 @@ interface PointSnapResult {
|
|
|
305
276
|
worldY: number;
|
|
306
277
|
}
|
|
307
278
|
/** A point-snap behavior plugged into `useResize`'s `pointSnapBehaviors`. */
|
|
308
|
-
interface PointSnapBehavior<TPose extends
|
|
279
|
+
interface PointSnapBehavior<TPose extends Bounds> {
|
|
309
280
|
id?: string;
|
|
310
281
|
onMove(ctx: PointSnapContext<TPose>): PointSnapResult | null | undefined;
|
|
311
282
|
}
|
|
@@ -336,4 +307,4 @@ interface CloneBehavior {
|
|
|
336
307
|
}) => Op[];
|
|
337
308
|
}
|
|
338
309
|
|
|
339
|
-
export type { ActionBehavior as A, BoundsConstraint as B, CloneBehavior as C,
|
|
310
|
+
export type { ActionBehavior as A, BoundsConstraint as B, CloneBehavior as C, GestureContext as G, InsertBehavior as I, LassoSelectBehavior as L, MoveBehavior as M, PointSnapBehavior as P, RotateBehavior as R, SnapStrategy as S, PointSnapFrame as a, AreaSelectOverlay as b, BehaviorMoveResult as c, BehaviorResult as d, CloneLayer as e, ClonePose as f, GroupTransform as g, InsertMoveResult as h, InsertOverlay as i, InsertPoint as j, InsertProposed as k, LassoSelectMoveResult as l, LassoSelectOverlay as m, LassoSelectPose as n, LassoSelectProposed as o, PointSnapContext as p, PointSnapResult as q, PointerState as r, ResizeMoveResult as s, ResizeOverlay as t, ResizeProposed as u, RotateMoveResult as v, RotateOverlay as w, RotateProposed as x };
|
|
@@ -133,9 +133,10 @@ interface SnapTarget<TPose = unknown> {
|
|
|
133
133
|
*
|
|
134
134
|
* **Pose semantics:** `getPose` / `setPose` work in **local** coordinates —
|
|
135
135
|
* relative to the node's direct parent (or world, for root-parented nodes).
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
136
|
+
* `getWorldPose` is the composed reading, and is what the render walk, picking
|
|
137
|
+
* and chrome consume. For the common axis-aligned rect pose, `composeRectPose`
|
|
138
|
+
* (translation only) and `composeRigidPose` (a container's pose is a frame, so
|
|
139
|
+
* its rotation reaches its children) ship as the two canonical strategies.
|
|
139
140
|
*/
|
|
140
141
|
interface SceneAdapter<TNode extends {
|
|
141
142
|
id: string;
|
|
@@ -145,6 +146,11 @@ interface SceneAdapter<TNode extends {
|
|
|
145
146
|
getSelection(): string[];
|
|
146
147
|
hitTest(worldX: number, worldY: number): string | null;
|
|
147
148
|
getPose(id: string): TPose;
|
|
149
|
+
/** The node's pose in world coordinates, with every ancestor's frame folded
|
|
150
|
+
* in. Equal to `getPose` under the absolute-pose model; anything reasoning
|
|
151
|
+
* about where a node actually is — picking, chrome, snapping, export —
|
|
152
|
+
* wants this rather than `getPose`. */
|
|
153
|
+
getWorldPose?(id: string): TPose;
|
|
148
154
|
getParent(id: string): string | null;
|
|
149
155
|
setPose(id: string, pose: TPose): void;
|
|
150
156
|
setParent(id: string, parentId: string | null): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Domain-agnostic 2D scene graph primitives for React: viewport math, drag/resize/insert/clone interactions, layered canvas rendering.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "orochi235",
|
|
@@ -72,16 +72,16 @@
|
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"react": ">=18",
|
|
75
|
-
"@weasel-js/font": "1.
|
|
75
|
+
"@weasel-js/font": "1.5.0"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@weasel-js/cursor": "1.
|
|
79
|
-
"@weasel-js/geom": "1.
|
|
80
|
-
"@weasel-js/gestures": "1.
|
|
81
|
-
"@weasel-js/history": "1.
|
|
82
|
-
"@weasel-js/
|
|
83
|
-
"@weasel-js/
|
|
84
|
-
"@weasel-js/text": "1.
|
|
78
|
+
"@weasel-js/cursor": "1.5.0",
|
|
79
|
+
"@weasel-js/geom": "1.5.0",
|
|
80
|
+
"@weasel-js/gestures": "1.5.0",
|
|
81
|
+
"@weasel-js/history": "1.5.0",
|
|
82
|
+
"@weasel-js/paint": "1.5.0",
|
|
83
|
+
"@weasel-js/routing": "1.5.0",
|
|
84
|
+
"@weasel-js/text": "1.5.0",
|
|
85
85
|
"earcut": "2.2.4",
|
|
86
86
|
"polygon-clipping": "^0.15.7"
|
|
87
87
|
},
|
|
@@ -97,5 +97,8 @@
|
|
|
97
97
|
"resize",
|
|
98
98
|
"viewport",
|
|
99
99
|
"2d"
|
|
100
|
-
]
|
|
100
|
+
],
|
|
101
|
+
"devDependencies": {
|
|
102
|
+
"@weasel-js/modes": "1.5.0"
|
|
103
|
+
}
|
|
101
104
|
}
|
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
import { P as Path } from './path-JEV2c5If.js';
|
|
2
|
-
import { TextureHandle, FillStyle, Stroke } from '@weasel-js/paint';
|
|
3
|
-
import { ResolvedRun, TextStyle, TextVerticalAlign } from '@weasel-js/text';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 2D affine matrix utilities. Column-major 9-element Float32Array, matching
|
|
7
|
-
* `WebGL2RenderingContext.uniformMatrix3fv` byte order so we can pass the
|
|
8
|
-
* array directly without a transpose flag.
|
|
9
|
-
*
|
|
10
|
-
* Layout (column-major):
|
|
11
|
-
* [m00, m10, 0,
|
|
12
|
-
* m01, m11, 0,
|
|
13
|
-
* tx, ty, 1]
|
|
14
|
-
*
|
|
15
|
-
* `apply(m, x, y)` returns `[m * (x, y, 1)] = [m00*x + m01*y + tx,
|
|
16
|
-
* m10*x + m11*y + ty]`.
|
|
17
|
-
*/
|
|
18
|
-
type Mat3 = Float32Array;
|
|
19
|
-
declare function identity(): Mat3;
|
|
20
|
-
declare function multiply(out: Mat3, m: Mat3): Mat3;
|
|
21
|
-
declare function translate(m: Mat3, tx: number, ty: number): Mat3;
|
|
22
|
-
declare function scale(m: Mat3, sx: number, sy: number): Mat3;
|
|
23
|
-
/**
|
|
24
|
-
* Inverse of an affine matrix. Returns identity for a singular matrix
|
|
25
|
-
* (determinant 0) — a degenerate transform collapses every point onto a
|
|
26
|
-
* line, so there is no meaningful inverse and callers get an unmapped
|
|
27
|
-
* space rather than NaNs propagating into a shader uniform.
|
|
28
|
-
*/
|
|
29
|
-
declare function invert(m: Mat3): Mat3;
|
|
30
|
-
declare function apply(m: Mat3, x: number, y: number): [number, number];
|
|
31
|
-
/**
|
|
32
|
-
* Map screen pixel coords (0..width on X, 0..height on Y, top-left origin)
|
|
33
|
-
* into clip space (-1..1 on X, 1..-1 on Y — note Y flip so screen-down
|
|
34
|
-
* matches clip-down).
|
|
35
|
-
*/
|
|
36
|
-
declare function screenToClip(width: number, height: number): Mat3;
|
|
37
|
-
/**
|
|
38
|
-
* Uniform-equivalent scale factor: the square root of the absolute
|
|
39
|
-
* determinant of the linear part, i.e. the geometric mean of the two axis
|
|
40
|
-
* scales. Rotation-invariant. Under non-uniform scale it is between the two
|
|
41
|
-
* axes and exact on neither — the same compromise `meanScale` documents.
|
|
42
|
-
*/
|
|
43
|
-
declare function meanScaleOf(m: Mat3): number;
|
|
44
|
-
/** The renderer's 3x3 matrix operations, as one namespace. These work on the
|
|
45
|
-
* 9-element `Float32Array` form the GL uniform upload wants — distinct from
|
|
46
|
-
* `@weasel-js/geom`'s 6-element affine `Mat3`, though the logical element
|
|
47
|
-
* order is the same. */
|
|
48
|
-
declare const mat3: {
|
|
49
|
-
identity: typeof identity;
|
|
50
|
-
multiply: typeof multiply;
|
|
51
|
-
translate: typeof translate;
|
|
52
|
-
scale: typeof scale;
|
|
53
|
-
invert: typeof invert;
|
|
54
|
-
apply: typeof apply;
|
|
55
|
-
screenToClip: typeof screenToClip;
|
|
56
|
-
meanScaleOf: typeof meanScaleOf;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* registerProgram — public API for registering custom shader programs.
|
|
61
|
-
*
|
|
62
|
-
* Stores raw GLSL source strings in a module-level registry. GL compilation
|
|
63
|
-
* happens on each WeaselRenderer via WeaselRenderer.registerProgram(), which
|
|
64
|
-
* calls getProgramSource() and compiles the result. This keeps registerProgram
|
|
65
|
-
* GL-context-agnostic — identical pattern to registerFont storing ImageBitmap.
|
|
66
|
-
*
|
|
67
|
-
* Module-level state = source strings only; compiled GL
|
|
68
|
-
* programs live on each renderer's programRegistry (Map<id, ShaderProgram>).
|
|
69
|
-
*
|
|
70
|
-
* Lifecycle: program sources live for the module lifetime. No unregister in v1.
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
/** Opaque handle to a compiled custom shader program. */
|
|
74
|
-
interface ShaderProgramHandle {
|
|
75
|
-
readonly id: string;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Scalar and vector uniform types accepted by the custom shader uniform binder.
|
|
79
|
-
*
|
|
80
|
-
* | TS type | GL call |
|
|
81
|
-
* |-------------------------|--------------------------------------|
|
|
82
|
-
* | number | uniform1f |
|
|
83
|
-
* | [n, n] | uniform2fv |
|
|
84
|
-
* | [n, n, n] | uniform3fv |
|
|
85
|
-
* | [n, n, n, n] | uniform4fv |
|
|
86
|
-
* | Float32Array length 9 | uniformMatrix3fv (column-major) |
|
|
87
|
-
* | Float32Array length 16 | uniformMatrix4fv (column-major) |
|
|
88
|
-
* | TextureHandle | bind to next tex unit + uniform1i |
|
|
89
|
-
*/
|
|
90
|
-
type ShaderUniform = number | [number, number] | [number, number, number] | [number, number, number, number] | Float32Array | TextureHandle;
|
|
91
|
-
/**
|
|
92
|
-
* Register a custom shader program by id.
|
|
93
|
-
*
|
|
94
|
-
* Pass an empty string for `vert` to use the kit's default vertex shader
|
|
95
|
-
* (recommended). The kit's vertex shader exposes `v_uv`, `v_screen`, and
|
|
96
|
-
* `v_world` varyings plus `u_bounds` and `u_view` uniforms.
|
|
97
|
-
*
|
|
98
|
-
* **IMPORTANT — Premultiplied alpha:**
|
|
99
|
-
* Your fragment shader MUST output premultiplied alpha:
|
|
100
|
-
* `outColor = vec4(rgb * a, a);` ← correct
|
|
101
|
-
* `outColor = vec4(rgb, a);` ← WRONG — over-brightens translucent regions
|
|
102
|
-
*
|
|
103
|
-
* The renderer uses `gl.blendFunc(ONE, ONE_MINUS_SRC_ALPHA)` to match.
|
|
104
|
-
* Opaque fragments (a=1) are unaffected; only fragments with a < 1 differ.
|
|
105
|
-
*
|
|
106
|
-
* **Re-registration behavior:**
|
|
107
|
-
* - Dev mode (`NODE_ENV !== 'production'`): calling with an existing id replaces
|
|
108
|
-
* the source (hot-reload). Each renderer must call `WeaselRenderer.registerProgram(handle)`
|
|
109
|
-
* again to pick up the new source.
|
|
110
|
-
* - Prod mode: calling with an existing id throws.
|
|
111
|
-
*
|
|
112
|
-
* Actual GL compilation and `ShaderCompileError` throwing happen in
|
|
113
|
-
* `WeaselRenderer.registerProgram()`, not here.
|
|
114
|
-
*
|
|
115
|
-
* @experimental API may break before v2.
|
|
116
|
-
*/
|
|
117
|
-
declare function registerProgram(id: string, vert: string, frag: string): ShaderProgramHandle;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* One full-screen pass over what a group has already drawn.
|
|
121
|
-
*
|
|
122
|
-
* The renderer runs a group's effects in order, each reading the previous
|
|
123
|
-
* one's output through `u_source` and writing a whole new buffer — so an
|
|
124
|
-
* effect is free to read neighbouring pixels, which is the entire point and
|
|
125
|
-
* the one thing `colorMatrix` can never do.
|
|
126
|
-
*
|
|
127
|
-
* `uniforms` are the effect's own; `u_source`, `u_resolution` and `u_texel`
|
|
128
|
-
* come from the renderer and must not be passed here.
|
|
129
|
-
*/
|
|
130
|
-
interface Effect {
|
|
131
|
-
program: ShaderProgramHandle;
|
|
132
|
-
uniforms?: Record<string, ShaderUniform>;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Register a fragment shader as an effect. Sugar over `registerProgram` with
|
|
136
|
-
* the effect vertex shader, and the reason a consumer never imports the
|
|
137
|
-
* prelude: an effect that registers with the *custom-shader* vertex shader
|
|
138
|
-
* compiles, runs, and samples its source upside down.
|
|
139
|
-
*
|
|
140
|
-
* The fragment shader reads `v_uv` and `u_source`, and may declare
|
|
141
|
-
* `u_resolution` / `u_texel`. See `effectPrelude.ts` for the full contract,
|
|
142
|
-
* including the premultiplied-alpha requirement.
|
|
143
|
-
*
|
|
144
|
-
* @experimental
|
|
145
|
-
*/
|
|
146
|
-
declare function registerEffect(id: string, frag: string): ShaderProgramHandle;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Solid-fill paint variant (subset of the full `FillStyle` union from
|
|
150
|
-
* `@weasel-js/core`). Kept for back-compat with step-1/2 consumers and
|
|
151
|
-
* because some code reads `fill.color` directly. Through step 4, fills can
|
|
152
|
-
* be any `FillStyle` variant — solid, pattern, or gradient.
|
|
153
|
-
*/
|
|
154
|
-
interface SolidPaint {
|
|
155
|
-
fill?: 'solid';
|
|
156
|
-
/** Any CSS color string accepted by `parseColor`: hex, `rgb()`/`rgba()`, `hsl()`/`hsla()`, named, or `transparent`. */
|
|
157
|
-
color: string;
|
|
158
|
-
opacity?: number;
|
|
159
|
-
}
|
|
160
|
-
/** DrawCommand variants implemented through step 6. */
|
|
161
|
-
type DrawCommand = PathDrawCommand | GroupDrawCommand | TextDrawCommand | ImageDrawCommand | SpritesDrawCommand | ShaderDrawCommand;
|
|
162
|
-
/** Draw a path, filled and/or stroked. The workhorse command: every shape the
|
|
163
|
-
* kit draws that is not text, an image, or a custom shader is one of these. */
|
|
164
|
-
interface PathDrawCommand {
|
|
165
|
-
kind: 'path';
|
|
166
|
-
path: Path;
|
|
167
|
-
/** Any `FillStyle` variant: solid, pattern, or gradient (linear/radial/conic). */
|
|
168
|
-
fill?: FillStyle;
|
|
169
|
-
/** Stroke spec. Only solid `paint` supported through step 4. */
|
|
170
|
-
stroke?: Stroke;
|
|
171
|
-
/**
|
|
172
|
-
* Optional flat RGBA-per-path-anchor color array (length =
|
|
173
|
-
* `4 × countPathAnchors(path)`, floats in 0..1). The renderer
|
|
174
|
-
* arc-length-interpolates these per-anchor colors across the
|
|
175
|
-
* flattened/triangulated mesh between consecutive anchors using the
|
|
176
|
-
* mesh's `anchorA` / `anchorB` / `anchorT` parameterization.
|
|
177
|
-
*
|
|
178
|
-
* **`fill` must also be set when using `vertexColors`.** The renderer
|
|
179
|
-
* only enters the per-vertex shader path when the command has a fill
|
|
180
|
-
* (the fill provides the opacity uniform; the vertex colors override
|
|
181
|
-
* the fill's color). Pass any solid `fill` (e.g. `{ color: '#fff' }`)
|
|
182
|
-
* as the placeholder; the per-vertex colors win in the shader.
|
|
183
|
-
*/
|
|
184
|
-
vertexColors?: number[];
|
|
185
|
-
}
|
|
186
|
-
/** Draw a list of commands under a shared transform, opacity, color matrix
|
|
187
|
-
* and clip. Groups nest, and their effects accumulate down the stack — this
|
|
188
|
-
* is how a container node's transform reaches its descendants. */
|
|
189
|
-
interface GroupDrawCommand {
|
|
190
|
-
kind: 'group';
|
|
191
|
-
transform?: Mat3;
|
|
192
|
-
alpha?: number;
|
|
193
|
-
/**
|
|
194
|
-
* Optional 4×5 color matrix (row-major, 20 numbers) — `out = M₄ₓ₄ * in + bias`.
|
|
195
|
-
* Accumulated multiplicatively down the group stack. Defaults to identity.
|
|
196
|
-
*/
|
|
197
|
-
colorMatrix?: number[];
|
|
198
|
-
/** Optional clip path. When set, the renderer rasterizes this path into
|
|
199
|
-
* the stencil buffer before drawing `children`; the children paint only
|
|
200
|
-
* where the clip covers. Nested groups with clips intersect — a child
|
|
201
|
-
* cannot escape an ancestor's clip. Max 7 nesting levels; the renderer
|
|
202
|
-
* throws if exceeded. */
|
|
203
|
-
clip?: Path;
|
|
204
|
-
/**
|
|
205
|
-
* Full-screen passes run over this group's own pixels, in order, before it
|
|
206
|
-
* is composited into its parent.
|
|
207
|
-
*
|
|
208
|
-
* Unlike every other field here, this does not accumulate down the group
|
|
209
|
-
* stack — it is a render-target boundary. The children draw into a buffer of
|
|
210
|
-
* their own, each effect reads the previous one's output, and the result is
|
|
211
|
-
* composited back under this group's `transform`, `alpha`, `colorMatrix` and
|
|
212
|
-
* whatever clip encloses it. So a blur here blurs this group and nothing
|
|
213
|
-
* around it, which is what a CSS `filter` on the canvas cannot do.
|
|
214
|
-
*
|
|
215
|
-
* An empty or absent list costs nothing: no buffer is allocated until a
|
|
216
|
-
* group asks for one.
|
|
217
|
-
*/
|
|
218
|
-
effects?: readonly Effect[];
|
|
219
|
-
children: DrawCommand[];
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Text draw command. Renders one or more runs at (`x`, `y`) in screen
|
|
223
|
-
* space, optionally word-wrapping at `maxWidth`. The renderer resolves
|
|
224
|
-
* each run's `(fontFamily, fontWeight, fontStyle)` to an MSDF atlas via
|
|
225
|
-
* `resolveFontVariant` and bucket-draws by atlas + color group.
|
|
226
|
-
*
|
|
227
|
-
* `style` carries node-level defaults (`lineHeight`, anti-alias width)
|
|
228
|
-
* that don't belong on individual runs.
|
|
229
|
-
*/
|
|
230
|
-
interface TextDrawCommand {
|
|
231
|
-
kind: 'text';
|
|
232
|
-
x: number;
|
|
233
|
-
y: number;
|
|
234
|
-
runs: ResolvedRun[];
|
|
235
|
-
maxWidth?: number;
|
|
236
|
-
align?: 'left' | 'center' | 'right';
|
|
237
|
-
style: TextStyle;
|
|
238
|
-
/** Box height for vertical alignment. When set with `verticalAlign`,
|
|
239
|
-
* the laid-out block shifts within `[y, y+height]`. */
|
|
240
|
-
height?: number;
|
|
241
|
-
/** Default 'top' — the legacy top-anchored behavior. */
|
|
242
|
-
verticalAlign?: TextVerticalAlign;
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Image draw command — renders `image` at screen-space rect (x, y, w, h).
|
|
246
|
-
* The image is stretched to fit; no tiling. Use a pattern FillStyle on a path
|
|
247
|
-
* for tiling.
|
|
248
|
-
*/
|
|
249
|
-
interface ImageDrawCommand {
|
|
250
|
-
kind: 'image';
|
|
251
|
-
image: ImageBitmap;
|
|
252
|
-
x: number;
|
|
253
|
-
y: number;
|
|
254
|
-
w: number;
|
|
255
|
-
h: number;
|
|
256
|
-
opacity?: number;
|
|
257
|
-
/** Magnification filter. `'linear'` (default) smooths; `'nearest'` shows
|
|
258
|
-
* device pixels as hard squares — required by anything magnifying a
|
|
259
|
-
* framebuffer readback, where blur destroys the point of the readback. */
|
|
260
|
-
sampling?: 'linear' | 'nearest';
|
|
261
|
-
/** Sub-rectangle of `image` to draw, in bitmap pixels from the top-left.
|
|
262
|
-
* Omitted draws the whole bitmap. Not range-checked: a rect past the edge
|
|
263
|
-
* samples outside [0..1], which CLAMP_TO_EDGE smears. With
|
|
264
|
-
* `sampling: 'linear'` the filter reaches half a texel beyond `source`, so
|
|
265
|
-
* atlas frames need a gutter (see `SpriteSheet.spacing`) or `'nearest'`. */
|
|
266
|
-
source?: {
|
|
267
|
-
x: number;
|
|
268
|
-
y: number;
|
|
269
|
-
w: number;
|
|
270
|
-
h: number;
|
|
271
|
-
};
|
|
272
|
-
/** Mirror the sampled region within the destination rect. The quad does not
|
|
273
|
-
* move — a flipped draw covers exactly the pixels an unflipped one does. */
|
|
274
|
-
flipX?: boolean;
|
|
275
|
-
flipY?: boolean;
|
|
276
|
-
}
|
|
277
|
-
/** Floats per sprite in `SpritesDrawCommand.sprites`. */
|
|
278
|
-
declare const SPRITE_STRIDE = 9;
|
|
279
|
-
/**
|
|
280
|
-
* Draw many quads sampling one bitmap — an atlas, a sprite sheet, a wall of
|
|
281
|
-
* thumbnails. The same picture as a run of `ImageDrawCommand`s the renderer
|
|
282
|
-
* would coalesce anyway, handed over already packed so it never walks a
|
|
283
|
-
* command object per quad.
|
|
284
|
-
*
|
|
285
|
-
* Reach for it past a few thousand sprites. Below that a plain run of image
|
|
286
|
-
* commands merges into the same single draw and reads better; the packed form
|
|
287
|
-
* exists because at 20,000 the object walk is about half the frame.
|
|
288
|
-
*
|
|
289
|
-
* The sprites are one run: they share a texture, a filter, and whatever group
|
|
290
|
-
* transform, alpha, color matrix and clip are live, exactly as a merged run of
|
|
291
|
-
* image commands would. Anything varying per sprite is in the array.
|
|
292
|
-
*/
|
|
293
|
-
interface SpritesDrawCommand {
|
|
294
|
-
kind: 'sprites';
|
|
295
|
-
image: ImageBitmap;
|
|
296
|
-
/** Magnification filter for the whole run, as `ImageDrawCommand.sampling`. */
|
|
297
|
-
sampling?: 'linear' | 'nearest';
|
|
298
|
-
/**
|
|
299
|
-
* `SPRITE_STRIDE` floats per sprite:
|
|
300
|
-
* `dx, dy, dw, dh, sx, sy, sw, sh, opacity`.
|
|
301
|
-
*
|
|
302
|
-
* Destination is in the group's coordinates; source is in bitmap pixels,
|
|
303
|
-
* like `ImageDrawCommand.source`. A negative `sw` or `sh` mirrors that axis
|
|
304
|
-
* within the source rect, which is what `flipX` / `flipY` do. A trailing
|
|
305
|
-
* partial sprite is ignored.
|
|
306
|
-
*/
|
|
307
|
-
sprites: Float32Array;
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Custom shader draw command. The renderer generates a quad over `bounds`
|
|
311
|
-
* and dispatches the consumer's fragment shader with the kit's vertex prelude.
|
|
312
|
-
*
|
|
313
|
-
* `uniforms` keys must match names declared in the consumer's fragment shader.
|
|
314
|
-
* The kit automatically sets `u_bounds`, `u_view`, and `u_proj` — do not
|
|
315
|
-
* declare those in `uniforms`.
|
|
316
|
-
*
|
|
317
|
-
* @experimental API may change before v2.
|
|
318
|
-
*/
|
|
319
|
-
interface ShaderDrawCommand {
|
|
320
|
-
kind: 'shader';
|
|
321
|
-
program: ShaderProgramHandle;
|
|
322
|
-
uniforms: Record<string, ShaderUniform>;
|
|
323
|
-
/** Screen-space bounding rect in CSS pixels. */
|
|
324
|
-
bounds: {
|
|
325
|
-
x: number;
|
|
326
|
-
y: number;
|
|
327
|
-
w: number;
|
|
328
|
-
h: number;
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
export { type DrawCommand as D, type Effect as E, type GroupDrawCommand as G, type ImageDrawCommand as I, type Mat3 as M, type PathDrawCommand as P, SPRITE_STRIDE as S, type TextDrawCommand as T, type ShaderDrawCommand as a, type ShaderProgramHandle as b, type ShaderUniform as c, type SolidPaint as d, type SpritesDrawCommand as e, registerProgram as f, mat3 as m, registerEffect as r };
|