@zcomponent/core 2.0.0-alpha.4 → 2.0.0-alpha.5
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/package.json +2 -1
- package/prompt.md +611 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zcomponent/core",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.5",
|
|
4
4
|
"description": "The core component model and built-in functionality for Mattercraft.",
|
|
5
5
|
"author": "Zappar Limited",
|
|
6
6
|
"license": "Proprietary",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"files": [
|
|
40
40
|
"index.js",
|
|
41
41
|
"index.d.ts",
|
|
42
|
+
"prompt.md",
|
|
42
43
|
"lib/**/*",
|
|
43
44
|
"css/**/*",
|
|
44
45
|
"assets/**/*"
|
package/prompt.md
ADDED
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
# Scripting
|
|
2
|
+
|
|
3
|
+
## Component and Behavior Registration
|
|
4
|
+
|
|
5
|
+
Components and behaviors are registered using class decorators that provide metadata to the Mattercraft editor:
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
@zComponent({
|
|
9
|
+
icon: 'music_note',
|
|
10
|
+
group: 'Media',
|
|
11
|
+
tags: ['core/audio'],
|
|
12
|
+
})
|
|
13
|
+
export class Audio extends Component<undefined, AudioConstructorProps> {
|
|
14
|
+
// Component implementation
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
@zBehavior({
|
|
20
|
+
icon: 'volume_up',
|
|
21
|
+
group: BehaviorGroups.Actions,
|
|
22
|
+
runAtDesignTime: true,
|
|
23
|
+
})
|
|
24
|
+
export class PlaySound extends ActionBehavior<PlaySoundProps> {
|
|
25
|
+
// Behavior implementation
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Registration Options:**
|
|
30
|
+
|
|
31
|
+
- `icon`: Material Design icon name for the component/behavior
|
|
32
|
+
- `group`: Category grouping in the Mattercraft UI
|
|
33
|
+
- `tags`: Array of tags for search and categorization
|
|
34
|
+
- `parents`: Array of parent tags or glob patterns that limit where the entity can be created
|
|
35
|
+
- `runAtDesignTime`: (Behaviors only) Whether to execute in the editor
|
|
36
|
+
|
|
37
|
+
## Property Configuration with Decorators
|
|
38
|
+
|
|
39
|
+
### @zUI() - UI Customization and Actions
|
|
40
|
+
|
|
41
|
+
Public properties are visible in the Mattercraft UI by default. Use `@zUI()` to customize how a property is presented, or to expose an event or method as a UI action:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
public volume = 1;
|
|
45
|
+
|
|
46
|
+
@zUI({ group: 'Audio', priority: 20, type: 'proportion' })
|
|
47
|
+
public gain = 0.8;
|
|
48
|
+
|
|
49
|
+
@zUI()
|
|
50
|
+
public play() {
|
|
51
|
+
// Play implementation
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Configuration Options:**
|
|
56
|
+
|
|
57
|
+
- `group`: Groups properties under a header in the UI
|
|
58
|
+
- `priority`: Determines display order (higher values appear first)
|
|
59
|
+
- `type`: Specifies the UI widget type
|
|
60
|
+
- `values`: Constrains values to specific types (see Values section)
|
|
61
|
+
|
|
62
|
+
### @zObserve() - Change Handling
|
|
63
|
+
|
|
64
|
+
The `@zObserve()` decorator creates change handlers for properties:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
@zUI({ group: 'Audio' })
|
|
68
|
+
@zObserve((value, instance) => {
|
|
69
|
+
instance._updateVolume();
|
|
70
|
+
})
|
|
71
|
+
public volume = 1;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Observer patterns:**
|
|
75
|
+
|
|
76
|
+
Simple observers:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
@zObserve((v, instance: Audio) => {
|
|
80
|
+
instance._updateVolume();
|
|
81
|
+
})
|
|
82
|
+
public muted = false;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Context-aware observers:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
@zObserve((v, instance) =>
|
|
89
|
+
instance.contextManager.get(AudioContextContext).setVolumeForLayer(instance.constructorProps?.layer, v)
|
|
90
|
+
)
|
|
91
|
+
public volume = 1;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### @zIgnore() - Serialization and UI Control
|
|
95
|
+
|
|
96
|
+
Excludes a public property from serialization and the Mattercraft UI. Use it for internal state that should not be user-editable:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
@zIgnore()
|
|
100
|
+
public element: HTMLElement;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### @zLoad() - Async Loading
|
|
104
|
+
|
|
105
|
+
Marks methods as loadable processes that should complete before the experience starts:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
@zLoad()
|
|
109
|
+
private async _load() {
|
|
110
|
+
const response = await fetch(this.constructorProps?.source);
|
|
111
|
+
this.data = await response.arrayBuffer();
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### @zRegister() - Event Registration
|
|
116
|
+
|
|
117
|
+
Registers methods to listen to events:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const someEvent = new Event<[number]>();
|
|
121
|
+
|
|
122
|
+
@zRegister(someEvent)
|
|
123
|
+
private _handleChange(value: number) {
|
|
124
|
+
// Handle event
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The first argument can be an `Event` instance, an event property on this entity (for example, `@zRegister('onStateChange')`), or a context class followed by one of its event property names.
|
|
129
|
+
|
|
130
|
+
The string form resolves a property on the decorated entity itself. It does not resolve a behavior's attached component through `this.instance`. For an event on `this.instance` or another component selected at runtime, use `this.register(component.onEvent, handler)`; use the same managed-listener form for `Observable` values.
|
|
131
|
+
|
|
132
|
+
## Lifecycle Decorators
|
|
133
|
+
|
|
134
|
+
### @zOnStart() - Auto-Start Methods
|
|
135
|
+
|
|
136
|
+
Calls methods when the experience starts:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
@zOnStart()
|
|
140
|
+
private _initializeAudio() {
|
|
141
|
+
// Initialize audio when experience starts
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### @zOnConstructed() - Auto-Construction Methods
|
|
146
|
+
|
|
147
|
+
Calls methods when construction completes:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
@zOnConstructed()
|
|
151
|
+
private _setupInitialState() {
|
|
152
|
+
// Setup after construction
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### @zOnLaunch() - Auto-Launch Methods
|
|
157
|
+
|
|
158
|
+
Calls methods when the experience launches:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
@zOnLaunch()
|
|
162
|
+
private _requestPermissions() {
|
|
163
|
+
// Request permissions when user launches
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Environment Condition Decorators
|
|
168
|
+
|
|
169
|
+
### @zOnlyRuntime() - Runtime-Only Methods
|
|
170
|
+
|
|
171
|
+
Methods only execute during runtime (not in editor):
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
@zOnlyRuntime()
|
|
175
|
+
public startGame() {
|
|
176
|
+
// Only runs for end users
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### @zOnlyDesignTime() - Design-Time-Only Methods
|
|
181
|
+
|
|
182
|
+
Methods only execute in the Mattercraft editor:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
@zOnlyDesignTime()
|
|
186
|
+
public previewEffect() {
|
|
187
|
+
// Only runs in editor
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### @zOnlyEditTime() - Edit-Time-Only Methods
|
|
192
|
+
|
|
193
|
+
Methods only execute during edit time:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
@zOnlyEditTime()
|
|
197
|
+
public validateSettings() {
|
|
198
|
+
// Only runs during editing
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### @zOnlyProduction() - Production-Only Methods
|
|
203
|
+
|
|
204
|
+
Methods only execute in production builds:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
@zOnlyProduction()
|
|
208
|
+
public enableAnalytics() {
|
|
209
|
+
// Only runs in production
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### @zOnlyDevelopment() - Development-Only Methods
|
|
214
|
+
|
|
215
|
+
Methods only execute in development builds:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
@zOnlyDevelopment()
|
|
219
|
+
public enableDebugMode() {
|
|
220
|
+
// Only runs in development
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Rendering Event Decorators
|
|
225
|
+
|
|
226
|
+
### @zOnBeforeRender() - Before Render Methods
|
|
227
|
+
|
|
228
|
+
Registers methods for before render events:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
@zOnBeforeRender()
|
|
232
|
+
private _updateAnimation(deltaTime: number) {
|
|
233
|
+
// Called every frame before rendering
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### @zOnAfterRender() - After Render Methods
|
|
238
|
+
|
|
239
|
+
Registers methods for after render events:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
@zOnAfterRender()
|
|
243
|
+
private _updateUI(deltaTime: number) {
|
|
244
|
+
// Called every frame after rendering
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Analytics Decorators
|
|
249
|
+
|
|
250
|
+
### @zLogEvent() - Analytics Logging
|
|
251
|
+
|
|
252
|
+
Logs analytics events when methods are called:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
@zLogEvent('button_clicked')
|
|
256
|
+
public handleButtonClick() {
|
|
257
|
+
// Analytics event logged
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## UI Type System
|
|
262
|
+
|
|
263
|
+
### Built-in UI Types
|
|
264
|
+
|
|
265
|
+
The `type` option in `@zUI()` configures the UI widget:
|
|
266
|
+
|
|
267
|
+
**Numeric inputs:**
|
|
268
|
+
|
|
269
|
+
- `proportion`: 0-1 range with slider input
|
|
270
|
+
- `time-seconds`, `time-milliseconds`: Time inputs with unit conversion
|
|
271
|
+
- `angle-radians`, `angle-degrees`: Angle inputs with unit conversion
|
|
272
|
+
|
|
273
|
+
**Color inputs:**
|
|
274
|
+
|
|
275
|
+
- `color-hex`: Hex color picker (`#FF0000`)
|
|
276
|
+
- `color-norm-rgb`, `color-norm-rgba`: Normalized RGB/RGBA arrays (0-1)
|
|
277
|
+
- `color-unnorm-rgb`, `color-unnorm-rgba`: Unnormalized RGB/RGBA arrays (0-255)
|
|
278
|
+
|
|
279
|
+
**Text inputs:**
|
|
280
|
+
|
|
281
|
+
- `text-multiline`: Textarea for multiline text
|
|
282
|
+
|
|
283
|
+
**Function types:**
|
|
284
|
+
|
|
285
|
+
- `function-emit-component-prop-event`: Event emission function
|
|
286
|
+
|
|
287
|
+
### Value Constraints
|
|
288
|
+
|
|
289
|
+
The `values` option constrains property values:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
@zUI({ values: 'layerclipids' })
|
|
293
|
+
public state?: string;
|
|
294
|
+
|
|
295
|
+
@zUI({ values: 'streamids' })
|
|
296
|
+
public stream?: string;
|
|
297
|
+
|
|
298
|
+
@zUI({ values: 'easings' })
|
|
299
|
+
public easing: Easing = 'linear';
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Available value types:**
|
|
303
|
+
|
|
304
|
+
- `layerclipids`: Timeline/state IDs in the scene
|
|
305
|
+
- `layerids`: Layer IDs in the scene
|
|
306
|
+
- `streamids`: Available stream IDs
|
|
307
|
+
- `easings`: Animation easing functions
|
|
308
|
+
- `nodeids`: Scene node IDs
|
|
309
|
+
- `nodelabels`: Scene node labels
|
|
310
|
+
- `animations`: Animation names in the file-in-context
|
|
311
|
+
- `morphtargets`: Morph target names in the file-in-context
|
|
312
|
+
- `events`: Component events annotated with @zUI
|
|
313
|
+
|
|
314
|
+
## Constructor Props and Type System
|
|
315
|
+
|
|
316
|
+
Constructor props use TypeScript types to configure the UI. Import specialized types from `@zcomponent/core`:
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { Range, Angle, ProjectFile, Color, Time, Proportion, MultilineText } from '@zcomponent/core';
|
|
320
|
+
|
|
321
|
+
export interface MyComponentProps {
|
|
322
|
+
// File selection with glob patterns
|
|
323
|
+
model: ProjectFile<'*.glb'>;
|
|
324
|
+
texture: ProjectFile<'*.{png,jpg}'>;
|
|
325
|
+
|
|
326
|
+
// Numeric ranges with bounds
|
|
327
|
+
opacity: Range<0, 1>;
|
|
328
|
+
volume: Range<0, 100>;
|
|
329
|
+
|
|
330
|
+
// Angular values with units
|
|
331
|
+
rotation: Angle<'degrees'>;
|
|
332
|
+
phase: Angle<'radians'>;
|
|
333
|
+
|
|
334
|
+
// Color values with format
|
|
335
|
+
background: Color<'hex'>;
|
|
336
|
+
tint: Color<'norm-rgb'>;
|
|
337
|
+
overlay: Color<'rgba'>;
|
|
338
|
+
|
|
339
|
+
// Time values with units
|
|
340
|
+
duration: Time<'seconds'>;
|
|
341
|
+
delay: Time<'milliseconds'>;
|
|
342
|
+
|
|
343
|
+
// Proportional values (0-1)
|
|
344
|
+
progress: Proportion;
|
|
345
|
+
|
|
346
|
+
// Text inputs
|
|
347
|
+
description: MultilineText;
|
|
348
|
+
|
|
349
|
+
// Basic types
|
|
350
|
+
title: string;
|
|
351
|
+
count: number;
|
|
352
|
+
enabled: boolean;
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Available Types:**
|
|
357
|
+
|
|
358
|
+
- `Range<MIN, MAX>`: Numeric range with bounds
|
|
359
|
+
- `Angle<'radians' | 'degrees'>`: Angular measurement
|
|
360
|
+
- `ProjectFile<GLOB>`: File path with glob constraint
|
|
361
|
+
- `Color<FORMAT, SPACE>`: Color value with format/space
|
|
362
|
+
- `Time<'seconds' | 'milliseconds' | 'hertz'>`: Time duration
|
|
363
|
+
- `Proportion`: 0-1 range value
|
|
364
|
+
- `MultilineText`: Multiline text content
|
|
365
|
+
- `Url`: URL string
|
|
366
|
+
- `EmailAddress`: Email with validation
|
|
367
|
+
|
|
368
|
+
## Events
|
|
369
|
+
|
|
370
|
+
Events are type-safe and exposed to the UI with `@zUI()`:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
@zUI()
|
|
374
|
+
public readonly onEnded = new Event<[Audio]>();
|
|
375
|
+
|
|
376
|
+
@zUI()
|
|
377
|
+
public readonly onSave = new Event();
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Emit events with arguments:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
this.onEnded.emit(this);
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Register event handlers:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
this.register(otherComponent.onEnded, audio => {
|
|
390
|
+
// Handle audio end event
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Methods as UI Actions
|
|
395
|
+
|
|
396
|
+
Methods can be exposed as actions in the UI:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
@zUI()
|
|
400
|
+
public play(opts?: PlayOptions) {
|
|
401
|
+
// Play implementation
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
@zUI()
|
|
405
|
+
public preview() {
|
|
406
|
+
this.perform();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
@zUI({ type: 'time-milliseconds' })
|
|
410
|
+
public seek(t: number) {
|
|
411
|
+
// Seek implementation
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Property Groups
|
|
416
|
+
|
|
417
|
+
Group related properties using group objects or strings:
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
const audioGroup: ZPropGroup = {
|
|
421
|
+
name: 'Audio',
|
|
422
|
+
priority: 20,
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
@zUI({ group: audioGroup })
|
|
426
|
+
public muted = false;
|
|
427
|
+
|
|
428
|
+
@zUI({ group: 'Settings', priority: 10 })
|
|
429
|
+
public autoplay = true;
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Complete Example
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
@zComponent({ icon: 'music_note', group: 'Media' })
|
|
436
|
+
export class Audio extends Component<undefined, AudioConstructorProps> {
|
|
437
|
+
@zUI()
|
|
438
|
+
public readonly onEnded = new Event<[Audio]>();
|
|
439
|
+
|
|
440
|
+
@zUI({ group: 'Audio', priority: 20 })
|
|
441
|
+
@zObserve((v, instance: Audio) => {
|
|
442
|
+
instance._updateVolume();
|
|
443
|
+
})
|
|
444
|
+
public muted = false;
|
|
445
|
+
|
|
446
|
+
@zUI({ group: 'Audio', priority: 20, type: 'proportion' })
|
|
447
|
+
@zObserve((v, instance: Audio) => {
|
|
448
|
+
instance._updateVolume();
|
|
449
|
+
})
|
|
450
|
+
public volume = 1;
|
|
451
|
+
|
|
452
|
+
@zUI()
|
|
453
|
+
public play() {
|
|
454
|
+
// Play implementation
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@zUI({ type: 'time-milliseconds' })
|
|
458
|
+
public seek(t: number) {
|
|
459
|
+
// Seek implementation
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
private _updateVolume() {
|
|
463
|
+
// Volume update logic
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## Contexts
|
|
469
|
+
|
|
470
|
+
Contexts centralize state across components. Access contexts through the contextManager:
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
import { CanvasContext } from '@zcomponent/core';
|
|
474
|
+
|
|
475
|
+
const canvasContext = this.contextManager.get(CanvasContext);
|
|
476
|
+
canvasContext.canvas; // HTMLCanvasElement
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Hooks and Utilities
|
|
480
|
+
|
|
481
|
+
### Canvas and Rendering Hooks
|
|
482
|
+
|
|
483
|
+
- `useCanvas(mgr: ContextManager)`: Returns the HTMLCanvasElement
|
|
484
|
+
- `useOverlay(mgr: ContextManager)`: Returns an Observable<HTMLDivElement>
|
|
485
|
+
- `useCanvasSize(mgr: ContextManager)`: Returns canvas size observable
|
|
486
|
+
- `useOnBeforeRender(mgr: ContextManager)`: Frame event before 3D render
|
|
487
|
+
- `useOnAfterRender(mgr: ContextManager)`: Frame event after 3D render
|
|
488
|
+
- `useCanvasToDataURL(mgr: ContextManager)`: Canvas to data URL function
|
|
489
|
+
- `useCanvasToArrayBuffer(mgr: ContextManager)`: Canvas to array buffer function
|
|
490
|
+
|
|
491
|
+
### Lifecycle Hooks
|
|
492
|
+
|
|
493
|
+
- `useIsLoaded(mgr: ContextManager)`: Observable indicating if experience is loaded
|
|
494
|
+
- `useIsStarted(mgr: ContextManager)`: Observable indicating if experience is started
|
|
495
|
+
- `useIsConstructed(mgr: ContextManager)`: Observable indicating if experience is constructed
|
|
496
|
+
- `useIsLaunched(mgr: ContextManager)`: Observable indicating if experience is launched
|
|
497
|
+
- `useLoadPercent(mgr: ContextManager)`: Observable with loading progress percentage
|
|
498
|
+
|
|
499
|
+
### Audio Context Hooks
|
|
500
|
+
|
|
501
|
+
- `useAudioContext(ctx: ContextManager)`: Returns WebAudio AudioContext
|
|
502
|
+
|
|
503
|
+
### Analytics Hooks
|
|
504
|
+
|
|
505
|
+
- `useAnalyticsOnEvent(mgr: ContextManager)`: Analytics event emission hook
|
|
506
|
+
|
|
507
|
+
### Cookie Consent Hooks
|
|
508
|
+
|
|
509
|
+
- `useCookieConsentFunctional(mgr: ContextManager)`: Functional cookies consent status
|
|
510
|
+
- `useCookieConsentPerformance(mgr: ContextManager)`: Performance cookies consent status
|
|
511
|
+
- `useCookieConsentMarketing(mgr: ContextManager)`: Marketing cookies consent status
|
|
512
|
+
- `useCookieConsentStatus(mgr: ContextManager)`: Overall cookie consent status
|
|
513
|
+
- `usePerformanceVendors(mgr: ContextManager)`: Registered performance vendors
|
|
514
|
+
- `useMarketingVendors(mgr: ContextManager)`: Registered marketing vendors
|
|
515
|
+
- `useShowCookieSettings(mgr: ContextManager)`: Function to show cookie settings
|
|
516
|
+
|
|
517
|
+
### Orientation Hooks
|
|
518
|
+
|
|
519
|
+
- `useOnOrientationChange(mgr: ContextManager)`: Device orientation change events
|
|
520
|
+
|
|
521
|
+
### Snapshot Hooks
|
|
522
|
+
|
|
523
|
+
- `useCanvasImage(ctx: ContextManager)`: Canvas image data URL
|
|
524
|
+
- `useShareAPISupported(ctx: ContextManager)`: Whether Share API is supported
|
|
525
|
+
- `useCanShare(ctx: ContextManager)`: Whether canvas can be shared
|
|
526
|
+
- `useCanvasFile(ctx: ContextManager)`: Canvas image as File object
|
|
527
|
+
- `useFileName(ctx: ContextManager)`: File name for snapshots
|
|
528
|
+
- `useText(ctx: ContextManager)`: Share text
|
|
529
|
+
- `useTitle(ctx: ContextManager)`: Share title
|
|
530
|
+
- `useFileType(ctx: ContextManager)`: File type (e.g., 'image/png')
|
|
531
|
+
- `useQuality(ctx: ContextManager)`: Image quality value
|
|
532
|
+
|
|
533
|
+
### User Event Hooks
|
|
534
|
+
|
|
535
|
+
- `useOnUserEvent(mgr: ContextManager)`: User interaction events
|
|
536
|
+
|
|
537
|
+
### Environment Utilities
|
|
538
|
+
|
|
539
|
+
- `isDesignTime(ctx: ContextManager)`: Returns true in Mattercraft editor
|
|
540
|
+
- `isEditTime(ctx: ContextManager)`: Returns true during edit time
|
|
541
|
+
- `isDevelopmentBuild(ctx: ContextManager)`: Returns true in development
|
|
542
|
+
- `isProductionBuild(ctx: ContextManager)`: Returns true in production
|
|
543
|
+
|
|
544
|
+
### Orientation Utilities
|
|
545
|
+
|
|
546
|
+
- `isPortrait(mgr: ContextManager)`: Returns true if device is in portrait
|
|
547
|
+
- `isLandscape(mgr: ContextManager)`: Returns true if device is in landscape
|
|
548
|
+
- `isPortraitSecondary(mgr: ContextManager)`: Returns true if in secondary portrait
|
|
549
|
+
- `isLandscapeSecondary(mgr: ContextManager)`: Returns true if in secondary landscape
|
|
550
|
+
|
|
551
|
+
### Lifecycle Utilities
|
|
552
|
+
|
|
553
|
+
- `isLoaded(mgr: ContextManager)`: Returns current loaded state
|
|
554
|
+
- `isStarted(mgr: ContextManager)`: Returns current started state
|
|
555
|
+
- `isConstructed(mgr: ContextManager)`: Returns current constructed state
|
|
556
|
+
- `isLaunched(mgr: ContextManager)`: Returns current launched state
|
|
557
|
+
|
|
558
|
+
## Lifecycle
|
|
559
|
+
|
|
560
|
+
Use lifecycle decorators on methods. Keep constructors for synchronous field initialization rather than lifecycle registration:
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
import { zLoad, zOnConstructed, zOnLaunch, zOnStart } from '@zcomponent/core';
|
|
564
|
+
|
|
565
|
+
@zOnConstructed()
|
|
566
|
+
private _afterConstruction() {
|
|
567
|
+
// The full entity tree has been constructed
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
@zOnLaunch()
|
|
571
|
+
private _afterLaunch() {
|
|
572
|
+
// The user has launched the experience
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
@zOnStart()
|
|
576
|
+
private _afterStart() {
|
|
577
|
+
// Start audio, video, or animation
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
@zLoad()
|
|
581
|
+
private async _load() {
|
|
582
|
+
// The loader waits for this promise before completing
|
|
583
|
+
}
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## Accessing ZComponent Nodes and Animation
|
|
587
|
+
|
|
588
|
+
Access the ZComponent instance and its nodes:
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
import Scene from './Scene.zcomp';
|
|
592
|
+
|
|
593
|
+
const scene = this.getZComponentInstance(Scene);
|
|
594
|
+
|
|
595
|
+
// Access nodes by scriptName
|
|
596
|
+
scene.nodes.DirectionalLight.enabled = false;
|
|
597
|
+
|
|
598
|
+
// Access animation layers and clips
|
|
599
|
+
scene.animation.layers.MyLayer.clips.MyTimeline.play();
|
|
600
|
+
scene.animation.layers.MyLayer.active = null; // Fade out
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## File References
|
|
604
|
+
|
|
605
|
+
Reference files using the URL constructor with import.meta.url:
|
|
606
|
+
|
|
607
|
+
```typescript
|
|
608
|
+
const fileUrl = new URL('./myfile.png', import.meta.url);
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
This format ensures Mattercraft's bundler detects and includes the file in the output bundle.
|