@maxenve/ren-three 0.0.0-stage → 0.1.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/src/surface.js ADDED
@@ -0,0 +1,204 @@
1
+ // The portable primitives in a three.js scene: a Surface is a ren-canv
2
+ // Document (layout, portable style, text, editing, selection, the native
3
+ // text entry and the accessibility mirror) drawn with a 2D canvas into a
4
+ // three.js texture.
5
+ //
6
+ // - The overlay: primitives placed in the scene itself lie over the canvas,
7
+ // pixel for pixel, drawn after the scene (a quad in front of an
8
+ // orthographic camera). The whole canvas is its page.
9
+ // - A panel: primitives placed in a three.js object become a plane in that
10
+ // object, as large as their content (`pixel` world units per pixel),
11
+ // facing +z; the texture has `scale` pixels per pixel.
12
+ //
13
+ // Input reaches a surface in its own pixels: the overlay's are the
14
+ // canvas's; a panel's come from the raycast hit's texture coordinate.
15
+
16
+ import { Document, attach } from 'ren-canv';
17
+ import { Replay2D } from 'ren-canv/backend';
18
+
19
+ /** The kinds of ren-canv's items that take the focus: an Edit, an Action. */
20
+ const EDIT = 4;
21
+ const ACTION = 5;
22
+
23
+ /** @typedef {import('./index.js').Renderer} Renderer */
24
+
25
+ export class Surface extends Document {
26
+ /**
27
+ * @param {Renderer} owner @param {boolean} panel
28
+ */
29
+ constructor(owner, panel) {
30
+ const options = owner.options;
31
+ super(/** @type {any} */ (owner.fonts()), {
32
+ width: panel ? 1 : owner.width,
33
+ height: panel ? 1 : owner.height,
34
+ scale: owner.scale,
35
+ theme: options.theme,
36
+ background: 0,
37
+ aria: options.aria,
38
+ fit: panel,
39
+ layout: options.layout,
40
+ });
41
+ const kit = owner.kit;
42
+ this.owner = owner;
43
+ this.panel = panel;
44
+ this.replay = new Replay2D(
45
+ owner.family,
46
+ owner.picture,
47
+ () => {
48
+ this.damage = true;
49
+ this.full = true;
50
+ this.present();
51
+ },
52
+ owner.monoFamily,
53
+ // A source that fails: its Images hear `error`; one that left the cache is loaded again.
54
+ source => this.failed(source),
55
+ source => this.forgot(source),
56
+ owner.typefaces,
57
+ );
58
+ /** The 2D canvas it draws on, where there is a document. @type {any} */
59
+ this.image = null;
60
+ /** @type {any} */
61
+ this.ctx = null;
62
+ const doc = owner.canvas?.ownerDocument ?? null;
63
+ if (doc !== null) {
64
+ const image = doc.createElement('canvas');
65
+ const ctx = typeof image.getContext === 'function' ? image.getContext('2d') : null;
66
+ if (ctx != null) {
67
+ this.image = image;
68
+ this.ctx = ctx;
69
+ }
70
+ }
71
+ this.texture = new kit.CanvasTexture(this.image ?? undefined);
72
+ if (kit.SRGBColorSpace !== undefined) this.texture.colorSpace = kit.SRGBColorSpace;
73
+ const material = new kit.MeshBasicMaterial({ map: this.texture, transparent: true, toneMapped: false, depthWrite: !panel, side: panel ? kit.DoubleSide : kit.FrontSide });
74
+ // The overlay fills the orthographic view (-1..1); a panel is a unit
75
+ // plane scaled to its size.
76
+ this.mesh = new kit.Mesh(new kit.PlaneGeometry(panel ? 1 : 2, panel ? 1 : 2), material);
77
+ this.mesh.userData.surface = this;
78
+ this.mesh.visible = false;
79
+ this.grow();
80
+ /** Stops the entry and mirror beside the three.js canvas. @type {(() => void) | null} */
81
+ this.stop = null;
82
+ if (owner.canvas != null && doc !== null) this.stop = attach(this, owner.canvas, { input: false, shift: !panel });
83
+ }
84
+
85
+ get kind() {
86
+ return 'three';
87
+ }
88
+
89
+ get drawing() {
90
+ return this.ctx !== null;
91
+ }
92
+
93
+ /** Sizes the canvas and the texture to the page, and a panel's plane. */
94
+ grow() {
95
+ const image = this.image;
96
+ if (image !== null) {
97
+ const w = Math.max(1, Math.round(this.width * this.scale));
98
+ const h = Math.max(1, Math.round(this.height * this.scale));
99
+ if (image.width !== w || image.height !== h) {
100
+ image.width = w;
101
+ image.height = h;
102
+ // A texture keeps its size on the GPU: a new size needs a new upload.
103
+ this.texture.dispose();
104
+ }
105
+ }
106
+ if (this.panel) {
107
+ const pixel = this.owner.pixel;
108
+ this.mesh.scale.set(this.width * pixel, this.height * pixel, 1);
109
+ }
110
+ this.full = true;
111
+ }
112
+
113
+ sized() {
114
+ this.grow();
115
+ }
116
+
117
+ /** @param {import('ren-canv/backend').Frame} frame @param {import('ren-canv/backend').Damage | null} damage */
118
+ draw(frame, damage) {
119
+ this.replay.run(this.ctx, frame, this.scale, 0, damage, this.shiftX, this.shiftY);
120
+ this.texture.needsUpdate = true;
121
+ this.owner.dirty = true;
122
+ this.owner.request();
123
+ }
124
+
125
+ present() {
126
+ const painted = super.present();
127
+ // Shown while it holds anything.
128
+ const shown = this.root.first !== null || this.overlay.first !== null;
129
+ if (this.mesh.visible !== shown) {
130
+ this.mesh.visible = shown;
131
+ this.owner.dirty = true;
132
+ this.owner.request();
133
+ }
134
+ return painted;
135
+ }
136
+
137
+ /**
138
+ * Keyboard focus to `item` in this surface (null blurs), as ren-canv's
139
+ * Document moves it, taking the focus from every other surface of the
140
+ * renderer first: one surface has the focus and hears the keys, also when
141
+ * code focuses an item (`focus()`, `focusFirst()`, ren-core's `$focus`)
142
+ * rather than a press. An item that cannot take the focus (not an Edit
143
+ * or an Action, or disabled) takes it from no other surface. A blur
144
+ * handler there that moves the focus (in its own surface or this one)
145
+ * wins, and `item` hears nothing, as in Chrome.
146
+ * @param {import('ren-canv').Item | null} item @param {boolean} [ring]
147
+ */
148
+ focus(item, ring = false) {
149
+ if (item !== null && (item.kind === EDIT || item.kind === ACTION) && !item.disabled && !this.closed) {
150
+ const owner = this.owner;
151
+ const before = this.current;
152
+ for (const surface of owner.surfaces) if (surface !== this) surface.focus(null);
153
+ // A blur handler moved the focus: its move wins.
154
+ if (this.current !== before) return;
155
+ for (const surface of owner.surfaces) if (surface !== this && surface.current !== null) return;
156
+ owner.active = this;
157
+ }
158
+ super.focus(item, ring);
159
+ }
160
+
161
+ /**
162
+ * Whether the item under a point, or an ancestor, hears a drag or a drop:
163
+ * where the overlay takes files dragged over it though nothing is painted
164
+ * there (a bare View with `onDrop`), as the DOM's element under them.
165
+ * @param {number} x @param {number} y
166
+ */
167
+ drops(x, y) {
168
+ return this.dropTarget(x, y) !== null;
169
+ }
170
+
171
+ /**
172
+ * Where a box of the page shows on screen: the overlay's is the canvas's;
173
+ * a panel's corners are projected through the camera.
174
+ * @param {any} canvas @param {number} x @param {number} y @param {number} right @param {number} bottom
175
+ * @returns {[number, number, number, number]}
176
+ */
177
+ screen(canvas, x, y, right, bottom) {
178
+ if (!this.panel) return super.screen(canvas, x, y, right, bottom);
179
+ const owner = this.owner;
180
+ let left = Infinity;
181
+ let top = Infinity;
182
+ let r = -Infinity;
183
+ let b = -Infinity;
184
+ for (const [px, py] of [[x, y], [right, y], [x, bottom], [right, bottom]]) {
185
+ const [sx, sy] = owner.project(this, px, py);
186
+ left = Math.min(left, sx);
187
+ top = Math.min(top, sy);
188
+ r = Math.max(r, sx);
189
+ b = Math.max(b, sy);
190
+ }
191
+ return [(canvas.offsetLeft ?? 0) + left, (canvas.offsetTop ?? 0) + top, r - left, b - top];
192
+ }
193
+
194
+ close() {
195
+ if (this.closed) return;
196
+ if (this.stop !== null) this.stop();
197
+ this.stop = null;
198
+ super.close();
199
+ this.mesh.parent?.remove(this.mesh);
200
+ this.mesh.geometry.dispose();
201
+ this.mesh.material.dispose();
202
+ this.texture.dispose();
203
+ }
204
+ }
@@ -0,0 +1,473 @@
1
+ import { Item } from 'ren-canv';
2
+ export { loadLayout, loadShaper, remoteLayout } from 'ren-canv';
3
+ import { Surface } from './surface.js';
4
+ export type Host = import('ren-core/host').Host;
5
+ export type Kit = Record<string, any>;
6
+ export type Drawer = {
7
+ render: (scene: any, camera: any) => void;
8
+ setSize: (width: number, height: number, style?: boolean) => void;
9
+ setPixelRatio?: ((ratio: number) => void) | undefined;
10
+ dispose?: (() => void) | undefined;
11
+ /**
12
+ * Loses the WebGL context now (a three.js WebGLRenderer has it).
13
+ */
14
+ forceContextLoss?: (() => void) | undefined;
15
+ /**
16
+ * its canvas
17
+ */
18
+ domElement?: any | undefined;
19
+ };
20
+ export type Options = {
21
+ /**
22
+ * The canvas width in CSS pixels; by default the host element's, followed as it resizes (300 without one).
23
+ */
24
+ width?: number | undefined;
25
+ /**
26
+ * The canvas height in CSS pixels; as width (150 without one).
27
+ */
28
+ height?: number | undefined;
29
+ /**
30
+ * The device pixel ratio (the window's by default).
31
+ */
32
+ scale?: number | undefined;
33
+ /**
34
+ * What draws: a WebGLRenderer made on the canvas by default (antialiased), or one given, or a function making it from the canvas.
35
+ */
36
+ renderer?: (Drawer | ((canvas: any) => Drawer)) | undefined;
37
+ /**
38
+ * The camera: a three.js camera, or `{ fov, near, far, position }` for a PerspectiveCamera (50°, 0.1, 1000, at [0, 0, 5] by default). A `<perspectiveCamera main>` in the view replaces it.
39
+ */
40
+ camera?: any | undefined;
41
+ /**
42
+ * The scene's background color.
43
+ */
44
+ background?: (number | string) | undefined;
45
+ /**
46
+ * `frame` (default) renders on animation frames; false renders only when `frame()` is called (tests, a host that drives its own loop).
47
+ */
48
+ schedule?: ('frame' | false) | undefined;
49
+ /**
50
+ * The bytes of the typeface the primitives are measured and drawn with (needed once a primitive renders).
51
+ */
52
+ font?: (ArrayBuffer | Uint8Array) | undefined;
53
+ /**
54
+ * The bytes of a monospace typeface: text whose `fontFamily` names monospace is measured and drawn in it (in `font` without it).
55
+ */
56
+ mono?: (ArrayBuffer | Uint8Array) | undefined;
57
+ /**
58
+ * Typefaces by family name: text whose `fontFamily` names one (the first of its list given here, before a generic family) is measured and drawn in it.
59
+ */
60
+ families?: Record<string, ArrayBuffer | Uint8Array> | undefined;
61
+ /**
62
+ * Typefaces for the characters a typeface lacks: each such character is measured and drawn in the first of them that has it.
63
+ */
64
+ fallback?: (ArrayBuffer | Uint8Array)[] | undefined;
65
+ /**
66
+ * The world units of one pixel of a panel (0.01).
67
+ */
68
+ pixel?: number | undefined;
69
+ /**
70
+ * Theme overrides for the primitives.
71
+ */
72
+ theme?: import('ren-core/host').Tokens | undefined;
73
+ /**
74
+ * The accessibility mirror of the primitives, as ren-canv's.
75
+ */
76
+ aria?: (boolean | 'demand') | undefined;
77
+ /**
78
+ * Where the primitives are laid out: this thread by default, or the layout worker `remoteLayout(port)` reaches (ren-canv's).
79
+ */
80
+ layout?: import('ren-canv').LayoutPort | undefined;
81
+ /**
82
+ * Loads an Image source into something a 2D canvas draws (an HTMLImageElement by default).
83
+ */
84
+ image?: import('ren-canv/backend').Picture | undefined;
85
+ };
86
+ /**
87
+ * The props `element` reads at creation: the Host's `construct` (compiled
88
+ * templates pass them too), and what a worker serving a ren-three view
89
+ * passes as `serve`'s `construct`. `of` (`<existing>`) cannot cross
90
+ * to a worker: an object made elsewhere belongs to the direct runtime.
91
+ */
92
+ export declare const CONSTRUCT: Set<string>;
93
+ /**
94
+ * The viewport a primitive's components read (the Host's `viewportOf`):
95
+ * its panel's size when it is placed in a panel whose primitive sets its
96
+ * width and height, else the root's (the canvas's). A panel sized by its
97
+ * content reports the root's: its size follows what it shows, so a view
98
+ * reading its own size could swing between two layouts. The color scheme
99
+ * and motion are the root's either way. A component in a panel runs before
100
+ * its nodes are placed: the source reports the root's until its primitive
101
+ * is placed, then binds to the panel.
102
+ */
103
+ declare class Region {
104
+ owner: Renderer;
105
+ item: Item;
106
+ /** @type {Set<(width: number, height: number, flags: number) => void>} */
107
+ viewers: Set<(width: number, height: number, flags: number) => void>;
108
+ /** The root's viewport, as it last reported. */
109
+ root: number[];
110
+ /** The primitive placed in the panel it is bound to, whose size is the panel's when it sets one. @type {Item | null} */
111
+ top: Item | null;
112
+ /** @type {(() => void) | null} */
113
+ unroot: (() => void) | null;
114
+ /** @type {(() => void) | null} */
115
+ unpanel: (() => void) | null;
116
+ /** @param {Renderer} owner @param {Item} item */
117
+ constructor(owner: Renderer, item: Item);
118
+ /** @param {(width: number, height: number, flags: number) => void} report @returns {() => void} */
119
+ viewport(report: (width: number, height: number, flags: number) => void): () => void;
120
+ /**
121
+ * Finds where its primitive is placed: a panel (followed), the overlay
122
+ * (the root's). False while it is not placed yet.
123
+ */
124
+ bind(): boolean;
125
+ /** What it reports now: the panel's size when its primitive sets one, else the root's. @returns {number[]} */
126
+ now(): number[];
127
+ /** Tells every reader. */
128
+ tell(): void;
129
+ }
130
+ /**
131
+ * The three.js renderer: the Host `mount` renders into, and the scene,
132
+ * camera and frame loop it draws.
133
+ */
134
+ export declare class Renderer {
135
+ kit: Kit;
136
+ construct: Set<string>;
137
+ options: Options;
138
+ /** The scene, and the container views render into. */
139
+ scene: any;
140
+ camera: any;
141
+ /** @type {Drawer | null} */
142
+ drawer: Drawer | null;
143
+ /** The canvas, once open. @type {any} */
144
+ canvas: any;
145
+ /** The host element that open marked (`data-ren-root`), unmarked on close. @type {any} */
146
+ host: any;
147
+ width: number;
148
+ height: number;
149
+ /** Rendered frames. */
150
+ frames: number;
151
+ /** True when the scene changed since the last frame. */
152
+ dirty: boolean;
153
+ /** Per-frame callbacks (`$animate`): false when one threw and nothing handled it. @type {Set<(frame: Tick) => boolean>} */
154
+ animations: Set<(frame: Tick) => boolean>;
155
+ /** The callbacks that had a frame: a callback's first frame has delta 0, whatever time passed before it. @type {WeakSet<(frame: Tick) => boolean>} */
156
+ animated: WeakSet<(frame: Tick) => boolean>;
157
+ /** The pending animation frame, or null. @type {any} */
158
+ pending: any;
159
+ time: number;
160
+ opened: boolean;
161
+ closed: boolean;
162
+ /** Objects with handlers, for the raycast. */
163
+ listening: number;
164
+ /** Objects with a `cursor`: while any, the pointer is raycast for them too. */
165
+ cursors: number;
166
+ /** `<gl>`'s settings by property name, applied to the drawer. @type {any} */
167
+ gl: any;
168
+ /** Object3D's own fields, which a rebuild from new params leaves alone. @type {Set<string> | null} */
169
+ base: Set<string> | null;
170
+ /** The objects under the pointer, nearest first (pointerover/out). @type {any[]} */
171
+ hovered: any[];
172
+ /** Removed nodes whose resources go at the next frame unless they come back. @type {any[]} */
173
+ removed: any[];
174
+ /** @type {(() => void) | null} */
175
+ detach: (() => void) | null;
176
+ /** @type {any} */
177
+ observer: any;
178
+ raycaster: any;
179
+ pointer: any;
180
+ /** The overlay of the primitives placed in the scene, once there is one. @type {Surface | null} */
181
+ overlay: Surface | null;
182
+ /** Its scene and camera, drawn over the scene. @type {any} */
183
+ overlayScene: any;
184
+ /** @type {any} */
185
+ overlayCamera: any;
186
+ /** Every surface, the overlay first. @type {Set<Surface>} */
187
+ surfaces: Set<Surface>;
188
+ /** The root's root-wide listeners (ren-core's `$keys`, `$scrolls` on the scene), heard on every surface; `off` by surface, which goes with it. @type {Set<{ name: string, fn: (event: any) => void, off: Map<Surface, () => void> }>} */
189
+ rooted: Set<{
190
+ name: string;
191
+ fn: (event: any) => void;
192
+ off: Map<Surface, () => void>;
193
+ }>;
194
+ /** The surfaces by their page's root item. @type {WeakMap<Item, Surface>} */
195
+ pages: WeakMap<Item, Surface>;
196
+ /** The measure of the primitives' text. @type {import('ren-canv').Fonts | null} */
197
+ measure: import('ren-canv').Fonts | null;
198
+ /** The font family the 2D canvas draws them in, and its monospace one (when `mono` is given). */
199
+ family: string;
200
+ monoFamily: string | null;
201
+ /** The font family each typeface slot of the measure draws in (the named typefaces, then the fallbacks; none for slot 0). @type {(string | null)[]} */
202
+ typefaces: (string | null)[];
203
+ /** The faces it added to the document's fonts, deleted on close. @type {any[]} */
204
+ faces: any[];
205
+ pixel: number;
206
+ scale: number;
207
+ /** @type {import('ren-canv/backend').Picture | null} */
208
+ picture: import('ren-canv/backend').Picture | null;
209
+ /** The surface keys, copy and select all go to; the one a press grabbed (a drag); the panel under the pointer. @type {Surface | null} */
210
+ active: Surface | null;
211
+ /** @type {Surface | null} */
212
+ grab: Surface | null;
213
+ /** @type {Surface | null} */
214
+ over: Surface | null;
215
+ /** True when the last press went to a surface (its click does not reach the scene). */
216
+ took: boolean;
217
+ /** The surface under a drag over the canvas (null: none). @type {Surface | null} */
218
+ dragged: Surface | null;
219
+ /** Who follows the viewport (ren-core's `$viewport`), and the window's preference queries while one does. @type {Set<(width: number, height: number, flags: number) => void>} */
220
+ viewers: Set<(width: number, height: number, flags: number) => void>;
221
+ /** @type {any[] | null} */
222
+ queries: any[] | null;
223
+ tell: () => void;
224
+ /** Each primitive's viewport source (`viewportOf`), made on first use. @type {WeakMap<Item, Region>} */
225
+ regions: WeakMap<Item, Region>;
226
+ /** The sources followed whose primitive is not placed yet: bound as it is. @type {Set<Region>} */
227
+ unbound: Set<Region>;
228
+ /** The drawer is this renderer's (made here, or by the `renderer` function for its canvas): closing loses its WebGL context. */
229
+ owned: boolean | undefined;
230
+ /** @param {Kit} kit @param {Options} [options] */
231
+ constructor(kit: Kit, options?: Options);
232
+ /** The measure of the primitives' text, read from the `font` (and `mono`) option on first use. @returns {import('ren-canv').Fonts} */
233
+ fonts(): import('ren-canv').Fonts;
234
+ /** The overlay, made on first use. */
235
+ makeOverlay(): Surface;
236
+ /** A new surface: one of this renderer's, hearing the root-wide listeners. @param {Surface} surface */
237
+ adopt(surface: Surface): void;
238
+ /** The surface an item belongs to (the overlay for one not placed yet). @param {Item} item */
239
+ page(item: Item): Surface;
240
+ get kind(): string;
241
+ /** @param {string} tag @param {any} props */
242
+ element(tag: string, props: any): any;
243
+ /** A text node: an item, drawn inside a primitive and nothing among three.js objects. @param {string} value */
244
+ text(value: string): Item;
245
+ /** @param {any} node @param {string} value */
246
+ content(node: any, value: string): void;
247
+ /** @param {any} node @param {string} name @param {any} value @param {any} [previous] */
248
+ set(node: any, name: string, value: any, previous?: any): void;
249
+ /** Writes a property on a three.js object: a dashed name reaches into it. @param {any} node @param {string} name @param {any} value */
250
+ apply(node: any, name: string, value: any): void;
251
+ /**
252
+ * Rebuilds an object in place from new constructor `params`: the node keeps
253
+ * its identity (the view, its parent and its handlers hold it). A fresh
254
+ * object is made and copied in: a scene object takes only what its class
255
+ * sets beyond Object3D's own fields (not its transform or children);
256
+ * anything else (a geometry, a material, a curve) takes its whole state,
257
+ * a geometry's old GPU buffers freed first. The properties the view set
258
+ * apply again after.
259
+ * @param {any} node @param {any} params
260
+ */
261
+ rebuild(node: any, params: any): void;
262
+ /** @param {any} node @param {string} name @param {(event: any) => void} handler */
263
+ listen(node: any, name: string, handler: (event: any) => void): () => void;
264
+ /** @param {any} parent @param {any} child @param {any} before */
265
+ insert(parent: any, child: any, before: any): void;
266
+ /**
267
+ * Places a primitive linked among three.js objects: in the overlay, in
268
+ * order among the overlay's other primitives, for the scene; in a panel
269
+ * of its own for any other object.
270
+ * @param {any} parent @param {Item} child @param {boolean} moving
271
+ */
272
+ place(parent: any, child: Item, moving: boolean): void;
273
+ /** @param {any} parent @param {any} child */
274
+ remove(parent: any, child: any): void;
275
+ /** @param {any} parent @param {any} child @param {boolean} moving */
276
+ unlink(parent: any, child: any, moving: boolean): void;
277
+ marker(): Item;
278
+ /** @param {any} node */
279
+ parent(node: any): any;
280
+ /** @param {any} node */
281
+ next(node: any): any;
282
+ /** @param {any} value */
283
+ owns(value: any): boolean;
284
+ layer(): any;
285
+ /**
286
+ * The viewport (ren-core's `$viewport`, `$media`): the canvas's size in
287
+ * CSS pixels, and the color scheme and motion preferences of the window
288
+ * it is in (none without one); now, then on each resize or change.
289
+ * @param {(width: number, height: number, flags: number) => void} report
290
+ * @returns {() => void}
291
+ */
292
+ viewport(report: (width: number, height: number, flags: number) => void): () => void;
293
+ /**
294
+ * The viewport of the region `node` is in (ren-core's `$viewport` and
295
+ * `$media` in a component built there): a primitive's is its panel's
296
+ * once it is placed in one with a width and height of its own (see
297
+ * Region), else the root's; null (the root's) for a three.js object.
298
+ * @param {any} node
299
+ * @returns {Region | null}
300
+ */
301
+ viewportOf(node: any): Region | null;
302
+ /** Binds the followed sources whose primitive is placed now. */
303
+ bind(): void;
304
+ /** The viewport's flags: 1 a dark color scheme, 2 reduced motion (the window's media queries). */
305
+ flags(): number;
306
+ /** Follows the window's color scheme and motion preferences, or stops. @param {boolean} on */
307
+ prefer(on: boolean): void;
308
+ /** Reports the viewport to its followers. */
309
+ viewed(): void;
310
+ present(): void;
311
+ /**
312
+ * Prepares an application root: a canvas in its host element (none
313
+ * without a document), the drawer, pointer events and sizing.
314
+ * @param {any} element @param {string} id
315
+ */
316
+ open(element: any, id: string): any;
317
+ close(): void;
318
+ /** Keeps the camera's aspect ratio to the canvas. */
319
+ aspect(): void;
320
+ /** Sizes the canvas and the camera. @param {number} width @param {number} height */
321
+ resize(width: number, height: number): void;
322
+ /** Follows the host element's size where the options leave it open. @param {any} element */
323
+ fit(element: any): void;
324
+ /** Asks for a frame: on the next animation frame, unless one is pending or frames are driven by hand. */
325
+ request(): void;
326
+ cancel(): void;
327
+ /** @param {number} time */
328
+ tick(time: number): void;
329
+ /**
330
+ * One frame: runs the `$animate` callbacks, then renders if anything changed
331
+ * (an animation always counts as a change).
332
+ * @param {number} [time] milliseconds
333
+ */
334
+ frame(time?: number): boolean;
335
+ /**
336
+ * The objects at a canvas point, nearest first: three.js intersections
337
+ * (`object`, `point`, `distance`, …).
338
+ * @param {number} x @param {number} y CSS pixels from the canvas's top left
339
+ * @returns {any[]}
340
+ */
341
+ pick(x: number, y: number): any[];
342
+ /**
343
+ * Dispatches a pointer event at a canvas point: to the nearest object
344
+ * with a handler for `type` and then its ancestors, until one stops it.
345
+ * `pointermove` also sends pointerover and pointerout as the objects
346
+ * under the pointer change. Returns true when a handler ran.
347
+ * @param {string} type a ren-core event name (`click`, `pointerdown`, …)
348
+ * @param {number} x @param {number} y
349
+ * @param {any} [native] the browser event
350
+ * @param {Record<string, any>} [more] fields the event also carries (a drop's `files`)
351
+ */
352
+ dispatch(type: string, x: number, y: number, native?: any, more?: Record<string, any>): boolean;
353
+ /** The nearest hit and its ancestors that are part of the view. @param {any[]} hits */
354
+ chain(hits: any[]): any[];
355
+ /** @param {any} object @param {string} type @param {any} hit @param {number} x @param {number} y @param {any} native */
356
+ call(object: any, type: string, hit: any, x: number, y: number, native: any): boolean;
357
+ /**
358
+ * The surface and its pixel under a canvas point: the overlay where it
359
+ * has something there, else the nearest panel the ray hits (from its
360
+ * texture coordinate). Null when neither. For a `drag` of files, the
361
+ * overlay also where an item under the point hears drags or drops.
362
+ * @param {number} x @param {number} y @param {boolean} [drag]
363
+ * @returns {[Surface, number, number] | null}
364
+ */
365
+ surfaceAt(x: number, y: number, drag?: boolean): [Surface, number, number] | null;
366
+ /**
367
+ * A canvas point on a panel's plane, in the panel's pixels, whether the
368
+ * panel is under it or not (a drag that leaves it). Null when the ray
369
+ * misses the plane.
370
+ * @param {Surface} surface @param {number} x @param {number} y
371
+ * @returns {[number, number] | null}
372
+ */
373
+ onPanel(surface: Surface, x: number, y: number): [number, number] | null;
374
+ /**
375
+ * Where a panel's pixel shows on the canvas, in CSS pixels.
376
+ * @param {Surface} surface @param {number} px @param {number} py
377
+ * @returns {[number, number]}
378
+ */
379
+ project(surface: Surface, px: number, py: number): [number, number];
380
+ /**
381
+ * One input event at a canvas point: to the primitives first (the overlay,
382
+ * then a panel under the pointer; a drag stays with the surface it
383
+ * started on), then, when they take nothing, raycast into the scene.
384
+ * Returns true when anything handled it.
385
+ * @param {string} type `pointerdown`, `pointermove`, `pointerup`, `pointercancel`, `pointerleave`, `click`, `dblclick`, `contextmenu` or `wheel`
386
+ * @param {number} x @param {number} y @param {any} [native]
387
+ */
388
+ input(type: string, x: number, y: number, native?: any): boolean;
389
+ /**
390
+ * A drag over the canvas at a point, carrying `files` files of these MIME
391
+ * `types` (all a drag tells before its drop): to the surface under it, as
392
+ * a press (the overlay by point, a panel by the raycast's texture
393
+ * coordinate), whose items hear it as ren-canv's `dragOver` sends it.
394
+ * Moving to another surface leaves the first, then enters the second.
395
+ * Over no surface, the scene's objects under it hear `dragover` through
396
+ * the raycast. Returns whether a surface or an object took it (the
397
+ * browser's default is prevented only then).
398
+ * @param {number} x @param {number} y @param {number} [files] @param {readonly string[]} [types] @param {any} [native]
399
+ */
400
+ dragOver(x: number, y: number, files?: number, types?: readonly string[], native?: any): boolean;
401
+ /** The drag left the canvas (or was cancelled): the surface under it leaves. */
402
+ dragLeave(): void;
403
+ /**
404
+ * Files dropped at a point: on the surface under it (its items hear
405
+ * `drop` with the files and the point in its pixels), else on the scene's
406
+ * objects through the raycast (`onDrop` with `files`). A drop ends the
407
+ * drag without a leave where it lands. Returns whether a surface or an
408
+ * object took it.
409
+ * @param {number} x @param {number} y @param {readonly any[]} files @param {any} [native]
410
+ */
411
+ dropFiles(x: number, y: number, files: readonly any[], native?: any): boolean;
412
+ /** Shows a three.js object's cursor on the canvas (null: the page's own). @param {any} object */
413
+ shown(object: any): void;
414
+ /**
415
+ * Takes a new theme for the primitives at once: the overlay and every
416
+ * panel resolve, lay out and repaint; the scene and all state stay.
417
+ * @param {import('ren-core/host').Tokens} tokens
418
+ */
419
+ setTheme(tokens: import('ren-core/host').Tokens): void;
420
+ /**
421
+ * Shows the cursor of the primitives under the pointer on the canvas (their
422
+ * style's `cursor`); leaves the page's own cursor over the scene.
423
+ * @param {Surface | null} surface
424
+ */
425
+ show(surface: Surface | null): void;
426
+ /**
427
+ * Routes a canvas element's pointer, wheel, key and copy events: to the
428
+ * primitives and the scene (`input`), keys and copy to the surface last
429
+ * pressed (keys with none to the overlay or the first panel, for the
430
+ * root's `$keys`; a chord reaches the handlers, as on ren-canv's attach).
431
+ * Returns the function that stops.
432
+ * @param {any} canvas
433
+ */
434
+ attach(canvas: any): () => void;
435
+ }
436
+ /**
437
+ * What a `$animate` callback receives each frame. In a worker there is no
438
+ * renderer, scene or camera: they are null there, and the callback changes
439
+ * signals instead.
440
+ */
441
+ export declare class Tick {
442
+ renderer: Renderer | null;
443
+ scene: any;
444
+ camera: any;
445
+ time: number;
446
+ delta: number;
447
+ /** @param {Renderer | null} renderer @param {number} time seconds @param {number} delta seconds since the last frame */
448
+ constructor(renderer: Renderer | null, time: number, delta: number);
449
+ }
450
+ /**
451
+ * A three.js renderer for `mount` or an application root's `renderer`.
452
+ * @param {Kit} kit the three.js namespace
453
+ * @param {Options} [options]
454
+ */
455
+ export declare function $three(kit: Kit, options?: Options): Renderer;
456
+ /**
457
+ * Renders `view()` into a renderer's scene; returns the dispose function.
458
+ * @param {() => any} view
459
+ * @param {Renderer} target
460
+ * @param {import('ren-core/host').Options} [options]
461
+ * @returns {() => void}
462
+ */
463
+ export declare function render(view: () => any, target: Renderer, options?: import('ren-core/host').Options): () => void;
464
+ /**
465
+ * Runs `fn` before every frame while the calling component lives (its
466
+ * owner's cleanup stops it). Rendered by ren-three, it runs in the
467
+ * renderer's frame loop, which draws every animation frame while any runs.
468
+ * Anywhere else (a worker serving the view), it runs on that thread's own
469
+ * frames (`requestAnimationFrame` where the thread has it, 16 ms timers
470
+ * otherwise), with a Tick whose renderer, scene and camera are null.
471
+ * @param {(frame: Tick) => void} fn
472
+ */
473
+ export declare function $animate(fn: (frame: Tick) => void): void;