phoria2 1.1.0 → 1.3.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 +70 -13
- package/dist/bloom.js +4 -4
- package/dist/bloom.js.map +1 -1
- package/dist/charts.js +538 -508
- package/dist/charts.js.map +1 -1
- package/dist/core.js +4270 -3652
- package/dist/core.js.map +1 -1
- package/dist/edit.js +65 -65
- package/dist/edit.js.map +1 -1
- package/dist/explain.js +6 -2
- package/dist/explain.js.map +1 -1
- package/dist/gltf.js +116 -116
- package/dist/gltf.js.map +1 -1
- package/dist/keyboard.js +188 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/motion.js +35 -35
- package/dist/motion.js.map +1 -1
- package/dist/particles.js +188 -115
- package/dist/particles.js.map +1 -1
- package/dist/passes.js +29 -29
- package/dist/passes.js.map +1 -1
- package/dist/phoria2.js +1 -1
- package/dist/picking.js +32 -16
- package/dist/picking.js.map +1 -1
- package/dist/snapshot.js +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/types/OrbitControl.d.ts +6 -2
- package/dist/types/Raycaster.d.ts +10 -0
- package/dist/types/View.d.ts +70 -1
- package/dist/types/area.d.ts +18 -0
- package/dist/types/charts/Chart.d.ts +7 -0
- package/dist/types/explain.d.ts +3 -0
- package/dist/types/frame.d.ts +7 -0
- package/dist/types/geometry/Geometry.d.ts +24 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/keyboard.d.ts +48 -0
- package/dist/types/labels.d.ts +4 -0
- package/dist/types/material/Material.d.ts +15 -0
- package/dist/types/material/Texture.d.ts +18 -2
- package/dist/types/particles/Emitter.d.ts +39 -2
- package/dist/types/scene/Node.d.ts +19 -14
- package/dist/types/scene/drawables.d.ts +54 -15
- package/dist/types/scene/lights.d.ts +16 -2
- package/dist/types/shadow.d.ts +2 -1
- package/dist/types/types.d.ts +14 -0
- package/dist/types/value/Color.d.ts +0 -4
- package/dist/types/value/Quat.d.ts +4 -2
- package/dist/types/webgl/resources.d.ts +12 -2
- package/dist/types/webgl/shaders.d.ts +7 -2
- package/llms-full.txt +106 -10
- package/package.json +4 -1
- package/schema/scene.schema.json +67 -1
- package/src/OrbitControl.js +7 -3
- package/src/Raycaster.js +58 -0
- package/src/View.js +220 -41
- package/src/area.js +131 -0
- package/src/charts/Chart.js +20 -2
- package/src/charts/marks.js +29 -2
- package/src/explain.js +6 -2
- package/src/frame.js +29 -9
- package/src/geometry/Geometry.js +32 -4
- package/src/index.js +1 -0
- package/src/keyboard.js +298 -0
- package/src/labels.js +4 -1
- package/src/material/Material.js +9 -2
- package/src/material/Texture.js +55 -2
- package/src/particles/Emitter.js +121 -10
- package/src/scene/Node.js +20 -9
- package/src/scene/Scene.js +2 -0
- package/src/scene/cameras.js +4 -1
- package/src/scene/drawables.js +115 -15
- package/src/scene/lights.js +40 -6
- package/src/shadow.js +27 -4
- package/src/types.js +6 -0
- package/src/value/Color.js +21 -0
- package/src/value/Quat.js +15 -6
- package/src/watch.js +14 -2
- package/src/webgl/WebGLRenderer.js +36 -5
- package/src/webgl/picking.js +22 -1
- package/src/webgl/resources.js +168 -14
- package/src/webgl/shaders.js +110 -11
package/dist/types/View.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type { ToneMapping, BloomOptions } from './webgl/WebGLRenderer.js';
|
|
|
16
16
|
import type { CameraOptions } from './scene/cameras.js';
|
|
17
17
|
import type { ColorInput, Vec3Input } from './types.js';
|
|
18
18
|
import type { Node } from './scene/Node.js';
|
|
19
|
+
import type { KeyboardOptions } from './keyboard.js';
|
|
19
20
|
export type RenderMode = 'auto' | 'always' | 'manual';
|
|
20
21
|
export type ViewOptions = {
|
|
21
22
|
/**
|
|
@@ -106,6 +107,24 @@ export type ViewOptions = {
|
|
|
106
107
|
* longest frame step in seconds, so a background tab doesn't jump (default 0.1)
|
|
107
108
|
*/
|
|
108
109
|
maxDelta?: number;
|
|
110
|
+
/**
|
|
111
|
+
* cut motion short, for people it makes unwell: frame() jumps rather
|
|
112
|
+
* than glides, auto-rotation holds, and charts change at once with their flows still. Default 'auto': as the
|
|
113
|
+
* system's setting (prefers-reduced-motion), followed as it changes
|
|
114
|
+
*/
|
|
115
|
+
reducedMotion?: 'auto' | boolean;
|
|
116
|
+
/**
|
|
117
|
+
* use without a pointer: the canvas joins the page's tab order, and
|
|
118
|
+
* the arrow keys step through what can be hovered or clicked - each with the hover tint, the tooltip and hover
|
|
119
|
+
* handlers - with Enter or Space to click and Escape to leave. A screen reader hears each one. { label: (hit) =>
|
|
120
|
+
* text } says what it hears (default: the tooltip's text, the data, or the name). Default false
|
|
121
|
+
*/
|
|
122
|
+
keyboard?: boolean | KeyboardOptions;
|
|
123
|
+
/**
|
|
124
|
+
* what the view shows, for screen readers: the canvas's label. With keyboard
|
|
125
|
+
* on and no description, one is made from the scene (charts describe themselves)
|
|
126
|
+
*/
|
|
127
|
+
description?: string | null;
|
|
109
128
|
};
|
|
110
129
|
export type ViewEvent = 'click' | 'hover';
|
|
111
130
|
export type ViewHandler = (hit: Hit | null, event: PointerEvent | MouseEvent | null) => void;
|
|
@@ -168,6 +187,22 @@ export declare class View {
|
|
|
168
187
|
get highlight(): Color | null;
|
|
169
188
|
/** @param {ColorInput | null} v */
|
|
170
189
|
set highlight(v: ColorInput | null);
|
|
190
|
+
/**
|
|
191
|
+
* Is motion cut short - glides, auto-rotation, chart transitions? Set true or false, or 'auto' (the
|
|
192
|
+
* default) to follow the system's setting. Read it for motion of your own, such as a timeline.
|
|
193
|
+
* @returns {boolean}
|
|
194
|
+
*/
|
|
195
|
+
get reducedMotion(): boolean;
|
|
196
|
+
/** @param {'auto' | boolean} v */
|
|
197
|
+
set reducedMotion(v: 'auto' | boolean);
|
|
198
|
+
/**
|
|
199
|
+
* What the view shows, for screen readers - the canvas's label - or null. With keyboard on and no
|
|
200
|
+
* description, one is made from the scene.
|
|
201
|
+
* @returns {string | null}
|
|
202
|
+
*/
|
|
203
|
+
get description(): string | null;
|
|
204
|
+
/** @param {string | null} v */
|
|
205
|
+
set description(v: string | null);
|
|
171
206
|
/** Canvas width in CSS pixels. */
|
|
172
207
|
get width(): number;
|
|
173
208
|
/** Canvas height in CSS pixels. */
|
|
@@ -220,7 +255,8 @@ export declare class View {
|
|
|
220
255
|
* @param {Node | Box3} [target] (default the scene)
|
|
221
256
|
* @param {{ padding?: number, direction?: CameraPreset | Vec3Input, duration?: number }} [options] padding is
|
|
222
257
|
* the margin around it, as a fraction of its size: 0 is a tight fit, 0.2 (the default) leaves a fifth.
|
|
223
|
-
* duration is in seconds (default 0: straight there); a press or the wheel stops the glide
|
|
258
|
+
* duration is in seconds (default 0: straight there); a press or the wheel stops the glide, and with
|
|
259
|
+
* reducedMotion it goes straight there
|
|
224
260
|
* @returns {this}
|
|
225
261
|
*/
|
|
226
262
|
frame(target?: Node | Box3, { padding, direction: towards, duration }?: {
|
|
@@ -228,6 +264,28 @@ export declare class View {
|
|
|
228
264
|
direction?: CameraPreset | Vec3Input;
|
|
229
265
|
duration?: number;
|
|
230
266
|
}): this;
|
|
267
|
+
/**
|
|
268
|
+
* Where frame() would put the camera, without moving it: its position, target and - for an
|
|
269
|
+
* orthographic camera - height, or null when there is nothing to frame. For a camera of your own
|
|
270
|
+
* that eases after something moving rather than jumping each frame:
|
|
271
|
+
*
|
|
272
|
+
* const aim = view.framing(debris)
|
|
273
|
+
* if (aim) {
|
|
274
|
+
* view.camera.position.lerp(aim.position, 0.1)
|
|
275
|
+
* view.camera.target.lerp(aim.target, 0.1)
|
|
276
|
+
* }
|
|
277
|
+
* @param {Node | Box3} [target] (default the scene)
|
|
278
|
+
* @param {{ padding?: number, direction?: CameraPreset | Vec3Input }} [options] as frame()
|
|
279
|
+
* @returns {{ position: Vec3, target: Vec3, height?: number } | null}
|
|
280
|
+
*/
|
|
281
|
+
framing(target?: Node | Box3, { padding, direction }?: {
|
|
282
|
+
padding?: number;
|
|
283
|
+
direction?: CameraPreset | Vec3Input;
|
|
284
|
+
}): {
|
|
285
|
+
position: Vec3;
|
|
286
|
+
target: Vec3;
|
|
287
|
+
height?: number;
|
|
288
|
+
} | null;
|
|
231
289
|
/**
|
|
232
290
|
* The nearest hit under a canvas position - CSS pixels from the canvas's top left, or a pointer
|
|
233
291
|
* event. Found on the GPU from the last frame drawn (one pass, however many instances), then made
|
|
@@ -281,6 +339,17 @@ export declare class View {
|
|
|
281
339
|
width: number;
|
|
282
340
|
height: number;
|
|
283
341
|
} | null;
|
|
342
|
+
/**
|
|
343
|
+
* Everything inside an area of the canvas, nearest first: a box `{ x, y, width, height }` or a
|
|
344
|
+
* lasso of `[x, y]` points, CSS pixels from the canvas's top left. Each point, instance and line
|
|
345
|
+
* segment is its own hit, found by where it is (a mesh by its middle) - hidden behind others or
|
|
346
|
+
* not - so a box dragged over a scatter selects that region of it.
|
|
347
|
+
*
|
|
348
|
+
* const picked = view.pickArea({ x: 40, y: 30, width: 200, height: 120 }).map((h) => h.datum)
|
|
349
|
+
* @param {import('./area.js').PickArea} area
|
|
350
|
+
* @returns {Hit[]}
|
|
351
|
+
*/
|
|
352
|
+
pickArea(area: import('./area.js').PickArea): Hit[];
|
|
284
353
|
/** Every hit under a canvas position, nearest first. @param {number | MouseEvent} x @param {number} [y] @returns {Hit[]} */
|
|
285
354
|
pickAll(x: number | MouseEvent, y?: number): Hit[];
|
|
286
355
|
/**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Hit } from './Raycaster.js';
|
|
2
|
+
import type { Node } from './scene/Node.js';
|
|
3
|
+
import type { Camera } from './scene/cameras.js';
|
|
4
|
+
export type PickArea = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
} | [number, number][];
|
|
10
|
+
/**
|
|
11
|
+
* Everything in the scene the camera shows, pickable, whose place falls inside the area - nearest
|
|
12
|
+
* the camera first.
|
|
13
|
+
* @param {Node} scene @param {Camera} camera @param {Float32Array} viewProjection
|
|
14
|
+
* @param {number} width @param {number} height the canvas, CSS pixels
|
|
15
|
+
* @param {PickArea} area
|
|
16
|
+
* @returns {Hit[]}
|
|
17
|
+
*/
|
|
18
|
+
export declare function pickArea(scene: Node, camera: Camera, viewProjection: Float32Array, width: number, height: number, area: PickArea): Hit[];
|
|
@@ -45,6 +45,13 @@ export declare class Chart extends Group {
|
|
|
45
45
|
filter(fn: ((row: any) => boolean) | null): this;
|
|
46
46
|
/** One line about this chart, for view.explain(). */
|
|
47
47
|
explain(): string;
|
|
48
|
+
/**
|
|
49
|
+
* One sentence about this chart for screen readers - the spec's description, or its title and what
|
|
50
|
+
* it shows: "Sales by month: bar chart of 12 rows by Month, Sales". A View with keyboard: true labels
|
|
51
|
+
* its canvas with this.
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
54
|
+
summary(): string;
|
|
48
55
|
toJSON(): Record<string, unknown>;
|
|
49
56
|
/** A new chart from the same spec and transform. @returns {any} */
|
|
50
57
|
clone(): any;
|
package/dist/types/explain.d.ts
CHANGED
package/dist/types/frame.d.ts
CHANGED
|
@@ -146,6 +146,11 @@ export type FrameLabel = {
|
|
|
146
146
|
* in front of the camera and inside the view
|
|
147
147
|
*/
|
|
148
148
|
visible: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* how far zoomed in at the point: half the view's height, in world units, is 1 / scale -
|
|
151
|
+
* the layer turns it into pixels to one world unit, for minScale
|
|
152
|
+
*/
|
|
153
|
+
scale: number;
|
|
149
154
|
};
|
|
150
155
|
export type ShadowFrame = {
|
|
151
156
|
light: FrameLight;
|
|
@@ -353,6 +358,8 @@ export type FrameDescription = {
|
|
|
353
358
|
* @property {[number, number]} ndc [x, y] in -1..1
|
|
354
359
|
* @property {number} depth
|
|
355
360
|
* @property {boolean} visible in front of the camera and inside the view
|
|
361
|
+
* @property {number} scale how far zoomed in at the point: half the view's height, in world units, is 1 / scale -
|
|
362
|
+
* the layer turns it into pixels to one world unit, for minScale
|
|
356
363
|
*/
|
|
357
364
|
/**
|
|
358
365
|
* The shadow-casting directional light's view of the scene: what to draw into its depth map.
|
|
@@ -21,6 +21,19 @@ export type GeometryOptions = {
|
|
|
21
21
|
* rgb per vertex, sRGB 0-1 like every colour input
|
|
22
22
|
*/
|
|
23
23
|
colors?: ArrayLike<number>;
|
|
24
|
+
/**
|
|
25
|
+
* points: one per vertex, a multiple of the material's size
|
|
26
|
+
*/
|
|
27
|
+
sizes?: ArrayLike<number>;
|
|
28
|
+
/**
|
|
29
|
+
* points: one per vertex, 0-1, multiplying the material's opacity
|
|
30
|
+
*/
|
|
31
|
+
opacities?: ArrayLike<number>;
|
|
32
|
+
/**
|
|
33
|
+
* points: one per vertex, radians anticlockwise on screen - turns
|
|
34
|
+
* each point's texture
|
|
35
|
+
*/
|
|
36
|
+
angles?: ArrayLike<number>;
|
|
24
37
|
/**
|
|
25
38
|
* vertex indices; triangles for meshes, pairs for lines
|
|
26
39
|
*/
|
|
@@ -38,6 +51,9 @@ export declare class Geometry {
|
|
|
38
51
|
/** @type {Float32Array | null} */ uvs: Float32Array | null;
|
|
39
52
|
/** A second UV set, for baked occlusion and light maps. @type {Float32Array | null} */ uvs2: Float32Array | null;
|
|
40
53
|
/** @type {Float32Array | null} */ colors: Float32Array | null;
|
|
54
|
+
/** Points: each one's size, as a multiple of the material's. @type {Float32Array | null} */ sizes: Float32Array | null;
|
|
55
|
+
/** Points: each one's opacity, 0-1, times the material's. @type {Float32Array | null} */ opacities: Float32Array | null;
|
|
56
|
+
/** Points: each one's turn on screen, in radians anticlockwise. @type {Float32Array | null} */ angles: Float32Array | null;
|
|
41
57
|
/** @type {Uint16Array | Uint32Array | null} */ indices: Uint16Array | Uint32Array | null;
|
|
42
58
|
/**
|
|
43
59
|
* Draw only the first `drawCount` vertices (indices, when indexed), or all of them when null -
|
|
@@ -56,7 +72,9 @@ export declare class Geometry {
|
|
|
56
72
|
constructor(options: GeometryOptions);
|
|
57
73
|
/**
|
|
58
74
|
* xyz per vertex. Computed (smooth) from the triangles on first read when not supplied, so
|
|
59
|
-
* points and lines - whose geometry has no triangles - never pay for them
|
|
75
|
+
* points and lines - whose geometry has no triangles - never pay for them - and computed again after
|
|
76
|
+
* needsUpdate(), so they follow positions edited in place. Normals that were supplied, assigned or
|
|
77
|
+
* made by calling computeNormals() are kept as they are.
|
|
60
78
|
* @type {Float32Array}
|
|
61
79
|
*/
|
|
62
80
|
get normals(): Float32Array;
|
|
@@ -77,7 +95,11 @@ export declare class Geometry {
|
|
|
77
95
|
get drawnVertices(): number;
|
|
78
96
|
/** Local space bounds, cached until needsUpdate(). @returns {Box3} */
|
|
79
97
|
get bounds(): Box3;
|
|
80
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* Call after editing the arrays in place. It is no longer what its generator made, so toJSON() saves
|
|
100
|
+
* the arrays; normals that were worked out on first read are worked out again on the next.
|
|
101
|
+
* @returns {this}
|
|
102
|
+
*/
|
|
81
103
|
needsUpdate(): this;
|
|
82
104
|
/**
|
|
83
105
|
* Compute vertex normals from the triangles. Smooth normals average the faces sharing each vertex;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export type RenderMode = import('./View.js').RenderMode;
|
|
|
37
37
|
export type CameraPreset = import('./presets.js').CameraPreset;
|
|
38
38
|
export type TooltipContent = import('./tooltip.js').TooltipContent;
|
|
39
39
|
export type Hit = import('./Raycaster.js').Hit;
|
|
40
|
+
export type PickArea = import('./area.js').PickArea;
|
|
40
41
|
export type LabelPlacement = import('./scene/drawables.js').LabelPlacement;
|
|
41
42
|
export type LabelPlace = import('./scene/drawables.js').LabelPlace;
|
|
42
43
|
export type InstanceLabels = import('./scene/drawables.js').InstanceLabels;
|
|
@@ -49,6 +50,7 @@ export type ImageOptions = import('./snapshot.js').ImageOptions;
|
|
|
49
50
|
/** @typedef {import('./presets.js').CameraPreset} CameraPreset */
|
|
50
51
|
/** @typedef {import('./tooltip.js').TooltipContent} TooltipContent */
|
|
51
52
|
/** @typedef {import('./Raycaster.js').Hit} Hit */
|
|
53
|
+
/** @typedef {import('./area.js').PickArea} PickArea */
|
|
52
54
|
/** @typedef {import('./scene/drawables.js').LabelPlacement} LabelPlacement */
|
|
53
55
|
/** @typedef {import('./scene/drawables.js').LabelPlace} LabelPlace */
|
|
54
56
|
/** @typedef {import('./scene/drawables.js').InstanceLabels} InstanceLabels */
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Hit } from './Raycaster.js';
|
|
2
|
+
import type { TooltipContent } from './tooltip.js';
|
|
3
|
+
import type { Node } from './scene/Node.js';
|
|
4
|
+
import type { View } from './View.js';
|
|
5
|
+
export type KeyboardOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* what a screen reader says for each thing stepped to (default: the
|
|
8
|
+
* tooltip's text, then its data, then the node's name)
|
|
9
|
+
*/
|
|
10
|
+
label?: (hit: Hit) => string;
|
|
11
|
+
};
|
|
12
|
+
export type KeyboardHooks = {
|
|
13
|
+
/**
|
|
14
|
+
* show this as hovered, or nothing
|
|
15
|
+
*/
|
|
16
|
+
focus: (hit: Hit | null) => void;
|
|
17
|
+
/**
|
|
18
|
+
* click it
|
|
19
|
+
*/
|
|
20
|
+
press: (hit: Hit) => void;
|
|
21
|
+
/**
|
|
22
|
+
* the tooltip's content for it, if there is a tooltip
|
|
23
|
+
*/
|
|
24
|
+
tooltip: (hit: Hit) => TooltipContent;
|
|
25
|
+
/**
|
|
26
|
+
* does the View itself answer hovers or clicks (a tooltip, handlers)?
|
|
27
|
+
*/
|
|
28
|
+
viewWide: () => boolean;
|
|
29
|
+
};
|
|
30
|
+
export type Item = {
|
|
31
|
+
node: Node;
|
|
32
|
+
index: number | null;
|
|
33
|
+
whole: Node | null;
|
|
34
|
+
};
|
|
35
|
+
export declare class Keyboard {
|
|
36
|
+
#private;
|
|
37
|
+
/** @param {View} view @param {KeyboardHooks} hooks @param {KeyboardOptions} options */
|
|
38
|
+
constructor(view: View, hooks: KeyboardHooks, options: KeyboardOptions);
|
|
39
|
+
/**
|
|
40
|
+
* The canvas's label for screen readers: the View's description, or - when it has none - one made
|
|
41
|
+
* from the scene: what its charts show, and how many things there are to step through.
|
|
42
|
+
* @param {string | null} text
|
|
43
|
+
*/
|
|
44
|
+
setDescription(text: string | null): void;
|
|
45
|
+
/** Step off whatever was stepped to: the pointer has taken over, or focus has gone. */
|
|
46
|
+
clear(): void;
|
|
47
|
+
dispose(): void;
|
|
48
|
+
}
|
package/dist/types/labels.d.ts
CHANGED
|
@@ -211,6 +211,18 @@ export type MaterialOptions = {
|
|
|
211
211
|
* Lines: width in pixels (default 1)
|
|
212
212
|
*/
|
|
213
213
|
width?: number;
|
|
214
|
+
/**
|
|
215
|
+
* Lines: dashed, with dashes this long in the model's units; 0 is solid (default 0)
|
|
216
|
+
*/
|
|
217
|
+
dash?: number;
|
|
218
|
+
/**
|
|
219
|
+
* Lines: the gaps between dashes; 0 is as long as the dashes (default 0)
|
|
220
|
+
*/
|
|
221
|
+
gap?: number;
|
|
222
|
+
/**
|
|
223
|
+
* Lines: moves the dashes along the lines - animate it for flow (default 0)
|
|
224
|
+
*/
|
|
225
|
+
dashOffset?: number;
|
|
214
226
|
};
|
|
215
227
|
/**
|
|
216
228
|
* The one material: what a surface looks like. Plain objects passed as a `material` become
|
|
@@ -275,6 +287,9 @@ export declare class Material {
|
|
|
275
287
|
/** @type {number} */ size: number;
|
|
276
288
|
/** @type {boolean} */ sizeAttenuation: boolean;
|
|
277
289
|
/** @type {number} */ width: number;
|
|
290
|
+
/** Lines: dash length in the model's units; 0 is solid. @type {number} */ dash: number;
|
|
291
|
+
/** Lines: gap length; 0 is the dash's. @type {number} */ gap: number;
|
|
292
|
+
/** Lines: how far the dashes have moved along. @type {number} */ dashOffset: number;
|
|
278
293
|
/** @param {MaterialOptions} [options] */
|
|
279
294
|
constructor(options?: MaterialOptions);
|
|
280
295
|
/** Base colour; assign any colour input. @returns {Color} */
|
|
@@ -64,9 +64,15 @@ export type TextureOptions = {
|
|
|
64
64
|
*/
|
|
65
65
|
flipY?: boolean;
|
|
66
66
|
};
|
|
67
|
+
export type TextureRegion = {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
width: number;
|
|
71
|
+
height: number;
|
|
72
|
+
};
|
|
67
73
|
/**
|
|
68
74
|
* An image for a material map. A video's frames upload by themselves as it plays; after drawing on
|
|
69
|
-
* a canvas, call `needsUpdate()
|
|
75
|
+
* a canvas, call `needsUpdate()` - with the rectangle drawn in, to send only that.
|
|
70
76
|
*/
|
|
71
77
|
export declare class Texture {
|
|
72
78
|
#private;
|
|
@@ -114,7 +120,17 @@ export declare class Texture {
|
|
|
114
120
|
/** 'srgb' for colour (decoded to linear by the GPU), 'linear' for data such as normals and roughness. Call needsUpdate() after changing it. @returns {'srgb' | 'linear'} */
|
|
115
121
|
get colorSpace(): 'srgb' | 'linear';
|
|
116
122
|
set colorSpace(v: 'srgb' | 'linear');
|
|
117
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Upload the image again, after drawing on it (a canvas) or changing its pixels. Give the
|
|
125
|
+
* rectangle that changed - in the image's pixels, from its top left - and only that is sent: for a
|
|
126
|
+
* big canvas drawn on a little at a time, far less to send each frame.
|
|
127
|
+
*
|
|
128
|
+
* ctx.fillRect(x, y, 20, 20)
|
|
129
|
+
* texture.needsUpdate({ x, y, width: 20, height: 20 })
|
|
130
|
+
* @param {TextureRegion} [region]
|
|
131
|
+
* @returns {this}
|
|
132
|
+
*/
|
|
133
|
+
needsUpdate(region?: TextureRegion): this;
|
|
118
134
|
/** Release the GPU copy. @returns {void} */
|
|
119
135
|
dispose(): void;
|
|
120
136
|
/** A description (url plus options that differ from the defaults), or null for an in-memory image. */
|
|
@@ -61,6 +61,28 @@ export type EmitterOptions = NodeOptions & SpawnOptions & {
|
|
|
61
61
|
frustumCulled?: boolean;
|
|
62
62
|
renderOrder?: number;
|
|
63
63
|
onParticle?: ((p: Particle) => boolean | void) | null;
|
|
64
|
+
sort?: boolean;
|
|
65
|
+
} & LookOptions;
|
|
66
|
+
export type LookOptions = {
|
|
67
|
+
/**
|
|
68
|
+
* a multiple of the material's size, or several each particle goes
|
|
69
|
+
* through over its life - [0.5, 3] for smoke that billows out (default 1)
|
|
70
|
+
*/
|
|
71
|
+
size?: number | number[];
|
|
72
|
+
/**
|
|
73
|
+
* each particle's size varies by up to this share either way, 0-1 (default 0)
|
|
74
|
+
*/
|
|
75
|
+
sizeSpread?: number;
|
|
76
|
+
/**
|
|
77
|
+
* 0-1, or several each particle goes through - [0, 1, 0] fades in
|
|
78
|
+
* and out (default 1)
|
|
79
|
+
*/
|
|
80
|
+
opacity?: number | number[];
|
|
81
|
+
/**
|
|
82
|
+
* radians per second: a number turns each particle up to that
|
|
83
|
+
* fast either way, [min, max] a range. Spinning particles start at a random angle (default 0)
|
|
84
|
+
*/
|
|
85
|
+
spin?: number | [number, number];
|
|
64
86
|
};
|
|
65
87
|
/**
|
|
66
88
|
* Particles drawn as points. Add it to a scene and it runs itself.
|
|
@@ -102,11 +124,11 @@ export declare class Emitter extends Points {
|
|
|
102
124
|
/**
|
|
103
125
|
* Change several settings at once - a preset, say. Vectors are copied into the emitter's own,
|
|
104
126
|
* so anything bound to `emitter.gravity` and friends stays bound. Live particles carry on.
|
|
105
|
-
* @param {SpawnOptions & { rate?: number, gravity?: Vec3Input, drag?: number, follow?: Node | null,
|
|
127
|
+
* @param {SpawnOptions & LookOptions & { rate?: number, gravity?: Vec3Input, drag?: number, follow?: Node | null,
|
|
106
128
|
* onParticle?: ((p: Particle) => boolean | void) | null }} options
|
|
107
129
|
* @returns {this}
|
|
108
130
|
*/
|
|
109
|
-
set(options: SpawnOptions & {
|
|
131
|
+
set(options: SpawnOptions & LookOptions & {
|
|
110
132
|
rate?: number;
|
|
111
133
|
gravity?: Vec3Input;
|
|
112
134
|
drag?: number;
|
|
@@ -121,6 +143,21 @@ export declare class Emitter extends Points {
|
|
|
121
143
|
set color(v: ColorInput | ColorInput[]);
|
|
122
144
|
/** @returns {[number, number, number][]} */
|
|
123
145
|
get color(): [number, number, number][];
|
|
146
|
+
/** Each particle's size over its life, as multiples of the material's. @param {number | number[]} v */
|
|
147
|
+
set size(v: number | number[]);
|
|
148
|
+
/** @returns {number[]} */
|
|
149
|
+
get size(): number[];
|
|
150
|
+
/** How much each particle's size varies, 0-1 either way. @param {number} v */
|
|
151
|
+
set sizeSpread(v: number);
|
|
152
|
+
get sizeSpread(): number;
|
|
153
|
+
/** Each particle's opacity over its life. @param {number | number[]} v */
|
|
154
|
+
set opacity(v: number | number[]);
|
|
155
|
+
/** @returns {number[]} */
|
|
156
|
+
get opacity(): number[];
|
|
157
|
+
/** How fast particles turn, radians per second, as a [min, max] range. @param {number | [number, number]} v */
|
|
158
|
+
set spin(v: number | [number, number]);
|
|
159
|
+
/** @returns {[number, number]} */
|
|
160
|
+
get spin(): [number, number];
|
|
124
161
|
/**
|
|
125
162
|
* Birth `count` particles at once - explosions, splashes. Options override the emitter's own
|
|
126
163
|
* spawn settings for this burst only.
|
|
@@ -5,7 +5,7 @@ import { Mat4 } from '../value/Mat4.js';
|
|
|
5
5
|
import { Quat } from '../value/Quat.js';
|
|
6
6
|
import { Vec3 } from '../value/Vec3.js';
|
|
7
7
|
import { Clip } from '../clip.js';
|
|
8
|
-
import type { ColorInput, Vec3Input } from '../types.js';
|
|
8
|
+
import type { ColorInput, QuatInput, Vec3Input } from '../types.js';
|
|
9
9
|
import type { Hit } from '../Raycaster.js';
|
|
10
10
|
import type { Camera } from './cameras.js';
|
|
11
11
|
import type { ClipOptions } from '../clip.js';
|
|
@@ -59,9 +59,9 @@ export type NodeOptions = {
|
|
|
59
59
|
*/
|
|
60
60
|
rotation?: Vec3Input | Euler;
|
|
61
61
|
/**
|
|
62
|
-
* [x, y, z, w] - instead of rotation
|
|
62
|
+
* [x, y, z, w] or { x, y, z, w } - instead of rotation
|
|
63
63
|
*/
|
|
64
|
-
quaternion?:
|
|
64
|
+
quaternion?: QuatInput;
|
|
65
65
|
/**
|
|
66
66
|
* a number scales uniformly
|
|
67
67
|
*/
|
|
@@ -87,9 +87,10 @@ export type NodeOptions = {
|
|
|
87
87
|
*/
|
|
88
88
|
tooltip?: ((hit: Hit) => any) | null;
|
|
89
89
|
/**
|
|
90
|
-
* hover tint for this subtree, over the View's
|
|
90
|
+
* hover tint for this subtree, over the View's; false for none - a
|
|
91
|
+
* floor or wall left plain under a View that tints everything else (null: the View's)
|
|
91
92
|
*/
|
|
92
|
-
highlight?: ColorInput | null;
|
|
93
|
+
highlight?: ColorInput | null | false;
|
|
93
94
|
/**
|
|
94
95
|
* hovering any part of this subtree tints all of it, as one thing - a
|
|
95
96
|
* piece of furniture, a machine - rather than just the part under the pointer (default false)
|
|
@@ -127,7 +128,7 @@ export type NodeOptions = {
|
|
|
127
128
|
*/
|
|
128
129
|
clip?: ClipOptions | Clip | null;
|
|
129
130
|
};
|
|
130
|
-
/** @import { ColorInput, Vec3Input } from '../types.js' */
|
|
131
|
+
/** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */
|
|
131
132
|
/** @import { Hit } from '../Raycaster.js' */
|
|
132
133
|
/** @import { Camera } from './cameras.js' */
|
|
133
134
|
/** @import { ClipOptions } from '../clip.js' */
|
|
@@ -157,7 +158,7 @@ export type NodeOptions = {
|
|
|
157
158
|
* @property {string} [name]
|
|
158
159
|
* @property {Vec3Input} [position]
|
|
159
160
|
* @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order
|
|
160
|
-
* @property {
|
|
161
|
+
* @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - instead of rotation
|
|
161
162
|
* @property {Vec3Input | number} [scale] a number scales uniformly
|
|
162
163
|
* @property {boolean} [visible]
|
|
163
164
|
* @property {boolean} [pickable] include in view.pick() (default true)
|
|
@@ -167,7 +168,8 @@ export type NodeOptions = {
|
|
|
167
168
|
* @property {UpdateHandler | UpdateHandler[]} [onUpdate]
|
|
168
169
|
* @property {((hit: Hit) => any) | null} [tooltip] tooltip for anything picked in this subtree; nearer nodes win, and
|
|
169
170
|
* all win over the View's
|
|
170
|
-
* @property {ColorInput | null} [highlight] hover tint for this subtree, over the View's
|
|
171
|
+
* @property {ColorInput | null | false} [highlight] hover tint for this subtree, over the View's; false for none - a
|
|
172
|
+
* floor or wall left plain under a View that tints everything else (null: the View's)
|
|
171
173
|
* @property {boolean} [highlightWhole] hovering any part of this subtree tints all of it, as one thing - a
|
|
172
174
|
* piece of furniture, a machine - rather than just the part under the pointer (default false)
|
|
173
175
|
* @property {((hit: Hit | null) => void) | null} [onHover] called as the thing under the pointer in this subtree changes
|
|
@@ -244,14 +246,17 @@ export declare class Node {
|
|
|
244
246
|
set rotation(v: Vec3Input);
|
|
245
247
|
/** Kept in sync with rotation. Assigning copies, normalised. @returns {Quat} */
|
|
246
248
|
get quaternion(): Quat;
|
|
247
|
-
/** @param {
|
|
248
|
-
set quaternion(v:
|
|
249
|
+
/** @param {QuatInput} v */
|
|
250
|
+
set quaternion(v: QuatInput);
|
|
249
251
|
/** @param {NodeOptions} [options] */
|
|
250
252
|
constructor(options?: NodeOptions);
|
|
251
|
-
/**
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Hover tint for this subtree, over the View's: a colour, false for none, or null to use the View's.
|
|
255
|
+
* @returns {Color | null | false}
|
|
256
|
+
*/
|
|
257
|
+
get highlight(): Color | null | false;
|
|
258
|
+
/** @param {ColorInput | null | false} value */
|
|
259
|
+
set highlight(value: ColorInput | null | false);
|
|
255
260
|
/**
|
|
256
261
|
* The section plane cutting this subtree, or null. Set { normal, offset, cap }, a Clip or null;
|
|
257
262
|
* move the cut by changing its offset or normal in place.
|