angular-three 2.0.0-beta.242 → 2.0.0-beta.244
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/esm2022/index.mjs +2 -2
- package/esm2022/lib/canvas.mjs +19 -27
- package/esm2022/lib/directives/args.mjs +52 -14
- package/esm2022/lib/instance.mjs +10 -9
- package/esm2022/lib/loop.mjs +2 -2
- package/esm2022/lib/portal.mjs +119 -111
- package/esm2022/lib/renderer/catalogue.mjs +2 -2
- package/esm2022/lib/renderer/constants.mjs +3 -5
- package/esm2022/lib/renderer/index.mjs +276 -194
- package/esm2022/lib/renderer/state.mjs +49 -0
- package/esm2022/lib/renderer/utils.mjs +40 -24
- package/esm2022/lib/roots.mjs +25 -25
- package/esm2022/lib/routed-scene.mjs +3 -3
- package/esm2022/lib/store.mjs +14 -12
- package/esm2022/lib/three-types.mjs +1 -1
- package/esm2022/lib/utils/apply-props.mjs +3 -3
- package/esm2022/lib/utils/before-render.mjs +4 -3
- package/esm2022/lib/utils/parameters.mjs +33 -28
- package/esm2022/lib/utils/resolve-ref.mjs +8 -0
- package/esm2022/lib/utils/signal-store.mjs +3 -14
- package/fesm2022/angular-three.mjs +720 -1089
- package/fesm2022/angular-three.mjs.map +1 -1
- package/index.d.ts +2 -2
- package/lib/canvas.d.ts +278 -1001
- package/lib/directives/args.d.ts +11 -4
- package/lib/instance.d.ts +8 -13
- package/lib/loop.d.ts +1 -1
- package/lib/portal.d.ts +41 -31
- package/lib/renderer/catalogue.d.ts +1 -1
- package/lib/renderer/constants.d.ts +2 -4
- package/lib/renderer/index.d.ts +15 -5
- package/lib/renderer/state.d.ts +23 -0
- package/lib/renderer/utils.d.ts +5 -22
- package/lib/roots.d.ts +5 -0
- package/lib/store.d.ts +12 -12
- package/lib/three-types.d.ts +8 -5
- package/lib/utils/parameters.d.ts +6 -9
- package/lib/utils/resolve-ref.d.ts +2 -0
- package/lib/utils/signal-store.d.ts +1 -5
- package/metadata.json +1 -1
- package/package.json +71 -72
- package/web-types.json +1 -1
- package/esm2022/lib/directives/common.mjs +0 -67
- package/esm2022/lib/directives/parent.mjs +0 -20
- package/esm2022/lib/ref.mjs +0 -50
- package/esm2022/lib/renderer/store.mjs +0 -439
- package/lib/directives/common.d.ts +0 -31
- package/lib/directives/parent.d.ts +0 -11
- package/lib/ref.d.ts +0 -7
- package/lib/renderer/store.d.ts +0 -65
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { untracked, computed, signal, ElementRef,
|
|
2
|
+
import { untracked, computed, signal, ElementRef, input, inject, ViewContainerRef, NgZone, TemplateRef, afterNextRender, DestroyRef, Directive, effect, InjectionToken, getDebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, EnvironmentInjector, Injector, booleanAttribute, output, viewChild, createEnvironmentInjector, Component, ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, contentChild, forwardRef } from '@angular/core';
|
|
3
3
|
import { outputFromObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { injectAutoEffect } from 'ngxtension/auto-effect';
|
|
5
5
|
import { provideResizeOptions, NgxResize } from 'ngxtension/resize';
|
|
6
6
|
import { MathUtils, WebGLRenderer, OrthographicCamera, PerspectiveCamera, Vector3, Layers, Color, ColorManagement, Texture, RGBAFormat, UnsignedByteType, Raycaster, Scene, PCFSoftShadowMap, BasicShadowMap, PCFShadowMap, VSMShadowMap, NoToneMapping, ACESFilmicToneMapping, Vector2, Clock } from 'three';
|
|
7
7
|
import { DOCUMENT } from '@angular/common';
|
|
8
|
+
import { Subject, filter } from 'rxjs';
|
|
8
9
|
import { createInjectionToken } from 'ngxtension/create-injection-token';
|
|
9
|
-
import { Subject, ReplaySubject, filter } from 'rxjs';
|
|
10
10
|
import { assertInjector } from 'ngxtension/assert-injector';
|
|
11
11
|
import * as i1 from '@angular/router';
|
|
12
12
|
import { ActivationEnd, RouterOutlet } from '@angular/router';
|
|
@@ -32,14 +32,6 @@ function updater(_source) {
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
function patcher(_source) {
|
|
36
|
-
return (state) => {
|
|
37
|
-
const updater = reducer(state);
|
|
38
|
-
untracked(() => {
|
|
39
|
-
_source.update((previous) => ({ ...updater(previous), ...previous }));
|
|
40
|
-
});
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
35
|
function getter(_source) {
|
|
44
36
|
return (...keys) => {
|
|
45
37
|
const root = untracked(_source);
|
|
@@ -78,7 +70,6 @@ function signalStore(initialState = {}, options) {
|
|
|
78
70
|
let source;
|
|
79
71
|
let update;
|
|
80
72
|
let get;
|
|
81
|
-
let patch;
|
|
82
73
|
let select;
|
|
83
74
|
let state;
|
|
84
75
|
const computedCache = new Map();
|
|
@@ -90,19 +81,17 @@ function signalStore(initialState = {}, options) {
|
|
|
90
81
|
state = source.asReadonly();
|
|
91
82
|
get = getter(source);
|
|
92
83
|
update = updater(source);
|
|
93
|
-
patch = patcher(source);
|
|
94
84
|
select = selector(state, computedCache);
|
|
95
|
-
source.set(initialState({ update, get,
|
|
85
|
+
source.set(initialState({ update, get, select }));
|
|
96
86
|
}
|
|
97
87
|
else {
|
|
98
88
|
source = signal(initialState, options);
|
|
99
89
|
state = source.asReadonly();
|
|
100
90
|
get = getter(source);
|
|
101
91
|
update = updater(source);
|
|
102
|
-
patch = patcher(source);
|
|
103
92
|
select = selector(state, computedCache);
|
|
104
93
|
}
|
|
105
|
-
const store = { select, get, update,
|
|
94
|
+
const store = { select, get, update, state };
|
|
106
95
|
Object.defineProperty(store, 'snapshot', {
|
|
107
96
|
get: untracked.bind({}, state),
|
|
108
97
|
configurable: false,
|
|
@@ -201,16 +190,21 @@ function getLocalState(obj) {
|
|
|
201
190
|
return obj['__ngt__'];
|
|
202
191
|
}
|
|
203
192
|
function invalidateInstance(instance) {
|
|
204
|
-
|
|
205
|
-
if (
|
|
206
|
-
|
|
193
|
+
let store = getLocalState(instance)?.store;
|
|
194
|
+
if (store) {
|
|
195
|
+
while (store.snapshot.previousRoot) {
|
|
196
|
+
store = store.snapshot.previousRoot;
|
|
197
|
+
}
|
|
198
|
+
if (store.snapshot.internal.frames === 0) {
|
|
199
|
+
store.snapshot.invalidate();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
207
202
|
checkUpdate(instance);
|
|
208
203
|
}
|
|
209
204
|
function prepare(object, localState) {
|
|
210
205
|
const instance = object;
|
|
211
206
|
if (localState?.primitive || !instance.__ngt__) {
|
|
212
207
|
const { instanceStore = signalStore({
|
|
213
|
-
nativeProps: {},
|
|
214
208
|
parent: null,
|
|
215
209
|
objects: [],
|
|
216
210
|
nonObjects: [],
|
|
@@ -225,7 +219,6 @@ function prepare(object, localState) {
|
|
|
225
219
|
parent: instanceStore.select('parent'),
|
|
226
220
|
objects: instanceStore.select('objects'),
|
|
227
221
|
nonObjects: instanceStore.select('nonObjects'),
|
|
228
|
-
nativeProps: instanceStore.select('nativeProps'),
|
|
229
222
|
add(object, type) {
|
|
230
223
|
const current = instance.__ngt__.instanceStore.get(type);
|
|
231
224
|
const foundIndex = current.indexOf((node) => object === node);
|
|
@@ -242,9 +235,6 @@ function prepare(object, localState) {
|
|
|
242
235
|
instance.__ngt__.instanceStore.update((prev) => ({ [type]: prev[type].filter((node) => node !== object) }));
|
|
243
236
|
notifyAncestors(instance.__ngt__.instanceStore.get('parent'));
|
|
244
237
|
},
|
|
245
|
-
setNativeProps(key, value) {
|
|
246
|
-
instance.__ngt__.instanceStore.update((prev) => ({ nativeProps: { ...prev.nativeProps, [key]: value } }));
|
|
247
|
-
},
|
|
248
238
|
setParent(parent) {
|
|
249
239
|
instance.__ngt__.instanceStore.update({ parent });
|
|
250
240
|
},
|
|
@@ -743,6 +733,83 @@ function createPointerEvents(store) {
|
|
|
743
733
|
};
|
|
744
734
|
}
|
|
745
735
|
|
|
736
|
+
const ROUTED_SCENE = '__ngt_renderer_is_routed_scene__';
|
|
737
|
+
const HTML = '__ngt_renderer_is_html';
|
|
738
|
+
const SPECIAL_INTERNAL_ADD_COMMENT = '__ngt_renderer_add_comment__';
|
|
739
|
+
const SPECIAL_DOM_TAG = {
|
|
740
|
+
NGT_PORTAL: 'ngt-portal',
|
|
741
|
+
NGT_PRIMITIVE: 'ngt-primitive',
|
|
742
|
+
NGT_VALUE: 'ngt-value',
|
|
743
|
+
};
|
|
744
|
+
const SPECIAL_PROPERTIES = {
|
|
745
|
+
RENDER_PRIORITY: 'priority',
|
|
746
|
+
ATTACH: 'attach',
|
|
747
|
+
RAW_VALUE: 'rawValue',
|
|
748
|
+
PARAMETERS: 'parameters',
|
|
749
|
+
};
|
|
750
|
+
const SPECIAL_EVENTS = {
|
|
751
|
+
BEFORE_RENDER: 'beforeRender',
|
|
752
|
+
UPDATED: 'updated',
|
|
753
|
+
ATTACHED: 'attached',
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
class NgtArgs {
|
|
757
|
+
constructor() {
|
|
758
|
+
this.args = input.required();
|
|
759
|
+
this.vcr = inject(ViewContainerRef);
|
|
760
|
+
this.zone = inject(NgZone);
|
|
761
|
+
this.template = inject(TemplateRef);
|
|
762
|
+
this.autoEffect = injectAutoEffect();
|
|
763
|
+
this.injected = false;
|
|
764
|
+
this.injectedArgs = null;
|
|
765
|
+
const commentNode = this.vcr.element.nativeElement;
|
|
766
|
+
if (commentNode[SPECIAL_INTERNAL_ADD_COMMENT]) {
|
|
767
|
+
commentNode[SPECIAL_INTERNAL_ADD_COMMENT]('args');
|
|
768
|
+
delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
|
|
769
|
+
}
|
|
770
|
+
afterNextRender(() => {
|
|
771
|
+
this.autoEffect(() => {
|
|
772
|
+
const value = this.args();
|
|
773
|
+
if (value == null || !Array.isArray(value) || (value.length === 1 && value[0] === null))
|
|
774
|
+
return;
|
|
775
|
+
this.injected = false;
|
|
776
|
+
this.injectedArgs = value;
|
|
777
|
+
untracked(() => {
|
|
778
|
+
this.createView();
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
inject(DestroyRef).onDestroy(() => {
|
|
783
|
+
this.view?.destroy();
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
get value() {
|
|
787
|
+
if (this.validate()) {
|
|
788
|
+
this.injected = true;
|
|
789
|
+
return this.injectedArgs;
|
|
790
|
+
}
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
validate() {
|
|
794
|
+
return !this.injected && !!this.injectedArgs?.length;
|
|
795
|
+
}
|
|
796
|
+
createView() {
|
|
797
|
+
this.zone.runOutsideAngular(() => {
|
|
798
|
+
if (this.view && !this.view.destroyed) {
|
|
799
|
+
this.view.destroy();
|
|
800
|
+
}
|
|
801
|
+
this.view = this.vcr.createEmbeddedView(this.template);
|
|
802
|
+
this.view.detectChanges();
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtArgs, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
806
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.0.6", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: { classPropertyName: "args", publicName: "args", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
807
|
+
}
|
|
808
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtArgs, decorators: [{
|
|
809
|
+
type: Directive,
|
|
810
|
+
args: [{ selector: 'ng-template[args]', standalone: true }]
|
|
811
|
+
}], ctorParameters: () => [] });
|
|
812
|
+
|
|
746
813
|
// This function prepares a set of changes to be applied to the instance
|
|
747
814
|
function diffProps(instance, props) {
|
|
748
815
|
const propsEntries = Object.entries(props);
|
|
@@ -856,8 +923,8 @@ function applyProps(instance, props) {
|
|
|
856
923
|
if (localState?.eventCount)
|
|
857
924
|
rootState.internal.interaction.push(instance);
|
|
858
925
|
}
|
|
859
|
-
if (parent && localState?.
|
|
860
|
-
localState.
|
|
926
|
+
if (parent && localState?.onUpdate && changes.length) {
|
|
927
|
+
localState.onUpdate(instance);
|
|
861
928
|
}
|
|
862
929
|
return instance;
|
|
863
930
|
}
|
|
@@ -866,8 +933,8 @@ const shallowLoose = { objects: 'shallow', strict: false };
|
|
|
866
933
|
const roots = new Map();
|
|
867
934
|
function injectCanvasRootInitializer(injector) {
|
|
868
935
|
return assertInjector(injectCanvasRootInitializer, injector, () => {
|
|
869
|
-
const injectedStore =
|
|
870
|
-
const loop =
|
|
936
|
+
const injectedStore = injectStore();
|
|
937
|
+
const loop = injectLoop();
|
|
871
938
|
return (canvas) => {
|
|
872
939
|
const exist = roots.has(canvas);
|
|
873
940
|
let store = roots.get(canvas);
|
|
@@ -889,21 +956,19 @@ function injectCanvasRootInitializer(injector) {
|
|
|
889
956
|
const root = roots.get(canvas);
|
|
890
957
|
if (root) {
|
|
891
958
|
root.update((state) => ({ internal: { ...state.internal, active: false } }));
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
}, timeout);
|
|
959
|
+
try {
|
|
960
|
+
const state = root.get();
|
|
961
|
+
state.events.disconnect?.();
|
|
962
|
+
state.gl?.renderLists?.dispose?.();
|
|
963
|
+
state.gl?.forceContextLoss?.();
|
|
964
|
+
if (state.gl?.xr)
|
|
965
|
+
state.xr.disconnect();
|
|
966
|
+
dispose(state);
|
|
967
|
+
roots.delete(canvas);
|
|
968
|
+
}
|
|
969
|
+
catch (e) {
|
|
970
|
+
console.error('[NGT] Unexpected error while destroying Canvas Root', e);
|
|
971
|
+
}
|
|
907
972
|
}
|
|
908
973
|
},
|
|
909
974
|
configure: (inputs) => {
|
|
@@ -1057,9 +1122,9 @@ function injectCanvasRootInitializer(injector) {
|
|
|
1057
1122
|
if (state.flat !== flat)
|
|
1058
1123
|
stateToUpdate.flat = flat;
|
|
1059
1124
|
// Set gl props
|
|
1060
|
-
gl.setClearAlpha(0);
|
|
1061
|
-
gl.setPixelRatio(makeDpr(state.viewport.dpr));
|
|
1062
|
-
gl.setSize(state.size.width, state.size.height);
|
|
1125
|
+
// gl.setClearAlpha(0);
|
|
1126
|
+
// gl.setPixelRatio(makeDpr(state.viewport.dpr));
|
|
1127
|
+
// gl.setSize(state.size.width, state.size.height);
|
|
1063
1128
|
if (is.obj(glOptions) &&
|
|
1064
1129
|
!(typeof glOptions === 'function') &&
|
|
1065
1130
|
!is.renderer(glOptions) &&
|
|
@@ -1073,7 +1138,9 @@ function injectCanvasRootInitializer(injector) {
|
|
|
1073
1138
|
if (performance && !is.equ(performance, state.performance, shallowLoose)) {
|
|
1074
1139
|
stateToUpdate.performance = { ...state.performance, ...performance };
|
|
1075
1140
|
}
|
|
1076
|
-
|
|
1141
|
+
if (Object.keys(stateToUpdate).length) {
|
|
1142
|
+
store.update(stateToUpdate);
|
|
1143
|
+
}
|
|
1077
1144
|
// Check size, allow it to take on container bounds initially
|
|
1078
1145
|
const size = computeInitialSize(canvas, sizeOptions);
|
|
1079
1146
|
if (!is.equ(size, state.size, shallowLoose)) {
|
|
@@ -1250,7 +1317,7 @@ function createLoop(roots) {
|
|
|
1250
1317
|
}
|
|
1251
1318
|
return { loop, invalidate, advance };
|
|
1252
1319
|
}
|
|
1253
|
-
const [
|
|
1320
|
+
const [injectLoop] = createInjectionToken(() => createLoop(roots));
|
|
1254
1321
|
|
|
1255
1322
|
function storeFactory(previousStore) {
|
|
1256
1323
|
const document = inject(DOCUMENT);
|
|
@@ -1259,7 +1326,7 @@ function storeFactory(previousStore) {
|
|
|
1259
1326
|
// TODO: revisit this when we need to support multiple platforms
|
|
1260
1327
|
throw new Error(`[NGT] Window is not available.`);
|
|
1261
1328
|
}
|
|
1262
|
-
const loop =
|
|
1329
|
+
const loop = injectLoop();
|
|
1263
1330
|
// NOTE: using Subject because we do not care about late-subscribers
|
|
1264
1331
|
const pointerMissed$ = new Subject();
|
|
1265
1332
|
const store = signalStore(({ get, update }) => {
|
|
@@ -1393,9 +1460,8 @@ function storeFactory(previousStore) {
|
|
|
1393
1460
|
});
|
|
1394
1461
|
Object.defineProperty(store, 'pointerMissed$', { get: () => pointerMissed$ });
|
|
1395
1462
|
let { size: oldSize, viewport: { dpr: oldDpr }, camera: oldCamera, } = store.snapshot;
|
|
1396
|
-
const [camera, size, viewportDpr] = [store.select('camera'), store.select('size'), store.select('viewport', 'dpr')];
|
|
1397
1463
|
effect(() => {
|
|
1398
|
-
const
|
|
1464
|
+
const { camera: newCamera, size: newSize, viewport: { dpr: newDpr }, gl, } = store.state();
|
|
1399
1465
|
// Resize camera and renderer on changes to size and pixel-ratio
|
|
1400
1466
|
if (newSize !== oldSize || newDpr !== oldDpr) {
|
|
1401
1467
|
oldSize = newSize;
|
|
@@ -1417,138 +1483,69 @@ function storeFactory(previousStore) {
|
|
|
1417
1483
|
return store;
|
|
1418
1484
|
}
|
|
1419
1485
|
const NGT_STORE = new InjectionToken('NgtStore Token');
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
}
|
|
1486
|
+
function provideStore(store) {
|
|
1487
|
+
if (store) {
|
|
1488
|
+
return { provide: NGT_STORE, useFactory: store };
|
|
1489
|
+
}
|
|
1490
|
+
return { provide: NGT_STORE, useFactory: storeFactory };
|
|
1491
|
+
}
|
|
1492
|
+
function injectStore(options) {
|
|
1493
|
+
return inject(NGT_STORE, options);
|
|
1494
|
+
}
|
|
1425
1495
|
|
|
1426
1496
|
const catalogue = {};
|
|
1427
1497
|
function extend(objects) {
|
|
1428
1498
|
Object.assign(catalogue, objects);
|
|
1429
1499
|
}
|
|
1430
|
-
const [
|
|
1431
|
-
|
|
1432
|
-
const ROUTED_SCENE = '__ngt_renderer_is_routed_scene__';
|
|
1433
|
-
const HTML = '__ngt_renderer_is_html';
|
|
1434
|
-
const SPECIAL_INTERNAL_ADD_COMMENT = '__ngt_renderer_add_comment__';
|
|
1435
|
-
const SPECIAL_DOM_TAG = {
|
|
1436
|
-
NGT_PORTAL: 'ngt-portal',
|
|
1437
|
-
NGT_PRIMITIVE: 'ngt-primitive',
|
|
1438
|
-
NGT_VALUE: 'ngt-value',
|
|
1439
|
-
};
|
|
1440
|
-
const SPECIAL_PROPERTIES = {
|
|
1441
|
-
COMPOUND: 'ngtCompound',
|
|
1442
|
-
RENDER_PRIORITY: 'priority',
|
|
1443
|
-
ATTACH: 'attach',
|
|
1444
|
-
RAW_VALUE: 'rawValue',
|
|
1445
|
-
PARAMETERS: 'parameters',
|
|
1446
|
-
REF: 'ref',
|
|
1447
|
-
};
|
|
1448
|
-
const SPECIAL_EVENTS = {
|
|
1449
|
-
BEFORE_RENDER: 'beforeRender',
|
|
1450
|
-
AFTER_UPDATE: 'afterUpdate',
|
|
1451
|
-
AFTER_ATTACH: 'afterAttach',
|
|
1452
|
-
};
|
|
1500
|
+
const [injectCatalogue] = createInjectionToken(() => catalogue);
|
|
1453
1501
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
});
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
this.injected = false;
|
|
1465
|
-
this.injectedValue = null;
|
|
1466
|
-
this.shouldCreateView = true;
|
|
1467
|
-
const commentNode = this.vcr.element.nativeElement;
|
|
1468
|
-
if (commentNode[SPECIAL_INTERNAL_ADD_COMMENT]) {
|
|
1469
|
-
commentNode[SPECIAL_INTERNAL_ADD_COMMENT](this.nodeType);
|
|
1470
|
-
delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
|
|
1471
|
-
}
|
|
1472
|
-
afterNextRender(() => {
|
|
1473
|
-
this.autoEffect(() => {
|
|
1474
|
-
const value = this.inputValue();
|
|
1475
|
-
if (this.shouldSkipCreateView(value))
|
|
1476
|
-
return;
|
|
1477
|
-
this.injected = false;
|
|
1478
|
-
this.injectedValue = value;
|
|
1479
|
-
untracked(() => {
|
|
1480
|
-
this.createView();
|
|
1481
|
-
});
|
|
1482
|
-
});
|
|
1483
|
-
});
|
|
1484
|
-
inject(DestroyRef).onDestroy(() => {
|
|
1485
|
-
this.view?.destroy();
|
|
1486
|
-
});
|
|
1487
|
-
}
|
|
1488
|
-
shouldSkipCreateView(value) {
|
|
1489
|
-
return !value;
|
|
1490
|
-
}
|
|
1491
|
-
get value() {
|
|
1492
|
-
if (this.validate()) {
|
|
1493
|
-
this.injected = true;
|
|
1494
|
-
return this.injectedValue;
|
|
1495
|
-
}
|
|
1496
|
-
return null;
|
|
1497
|
-
}
|
|
1498
|
-
createView() {
|
|
1499
|
-
this.zone.runOutsideAngular(() => {
|
|
1500
|
-
if (this.shouldCreateView) {
|
|
1501
|
-
if (this.view && !this.view.destroyed) {
|
|
1502
|
-
this.view.destroy();
|
|
1503
|
-
}
|
|
1504
|
-
this.view = this.vcr.createEmbeddedView(this.template);
|
|
1505
|
-
this.view.detectChanges();
|
|
1506
|
-
}
|
|
1507
|
-
});
|
|
1502
|
+
function createNode(type, node, document) {
|
|
1503
|
+
const state = [type, null, [], false, undefined, undefined, undefined];
|
|
1504
|
+
const rendererNode = Object.assign(node, { __ngt_renderer__: state });
|
|
1505
|
+
// NOTE: assign ownerDocument to node so we can use HostListener in Component
|
|
1506
|
+
if (!rendererNode['ownerDocument'])
|
|
1507
|
+
rendererNode['ownerDocument'] = document;
|
|
1508
|
+
// NOTE: assign injectorFactory on non-three type since
|
|
1509
|
+
// rendererNode is an instance of DOM Node
|
|
1510
|
+
if (state[0 /* NgtRendererClassId.type */] !== 'three') {
|
|
1511
|
+
state[6 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode)?.injector;
|
|
1508
1512
|
}
|
|
1509
|
-
|
|
1510
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.3", type: NgtCommonDirective, ngImport: i0 }); }
|
|
1513
|
+
return rendererNode;
|
|
1511
1514
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1515
|
+
function isDOM(node) {
|
|
1516
|
+
const rS = node['__ngt_renderer__'];
|
|
1517
|
+
return !rS || node instanceof Element || node instanceof Document || node instanceof Window;
|
|
1518
|
+
}
|
|
1519
|
+
function getClosestParentWithInstance(node) {
|
|
1520
|
+
let parent = node.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1521
|
+
if (parent &&
|
|
1522
|
+
parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'portal' &&
|
|
1523
|
+
parent.__ngt_renderer__[5 /* NgtRendererClassId.portalContainer */]?.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three') {
|
|
1524
|
+
return parent.__ngt_renderer__[5 /* NgtRendererClassId.portalContainer */];
|
|
1521
1525
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1526
|
+
while (parent && parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] !== 'three') {
|
|
1527
|
+
parent = parent.__ngt_renderer__[5 /* NgtRendererClassId.portalContainer */]
|
|
1528
|
+
? parent.__ngt_renderer__[5 /* NgtRendererClassId.portalContainer */]
|
|
1529
|
+
: parent.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1524
1530
|
}
|
|
1525
|
-
|
|
1526
|
-
|
|
1531
|
+
return parent;
|
|
1532
|
+
}
|
|
1533
|
+
function setParent(node, parent) {
|
|
1534
|
+
if (!node.__ngt_renderer__[1 /* NgtRendererClassId.parent */]) {
|
|
1535
|
+
node.__ngt_renderer__[1 /* NgtRendererClassId.parent */] = parent;
|
|
1527
1536
|
}
|
|
1528
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtArgs, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1529
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.0.3", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: { classPropertyName: "args", publicName: "args", isSignal: true, isRequired: true, transformFunction: null } }, providers: [provideNodeType('args')], usesInheritance: true, ngImport: i0 }); }
|
|
1530
1537
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
}] });
|
|
1535
|
-
|
|
1536
|
-
class NgtParent extends NgtCommonDirective {
|
|
1537
|
-
constructor() {
|
|
1538
|
-
super(...arguments);
|
|
1539
|
-
this.parent = input.required();
|
|
1540
|
-
this.inputValue = this.parent;
|
|
1538
|
+
function addChild(node, child) {
|
|
1539
|
+
if (!node.__ngt_renderer__[2 /* NgtRendererClassId.children */].includes(child)) {
|
|
1540
|
+
node.__ngt_renderer__[2 /* NgtRendererClassId.children */].push(child);
|
|
1541
1541
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1542
|
+
}
|
|
1543
|
+
function removeChild(node, child) {
|
|
1544
|
+
const index = node.__ngt_renderer__?.[2 /* NgtRendererClassId.children */].findIndex((c) => child === c);
|
|
1545
|
+
if (index >= 0) {
|
|
1546
|
+
node.__ngt_renderer__[2 /* NgtRendererClassId.children */].splice(index, 1);
|
|
1544
1547
|
}
|
|
1545
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtParent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1546
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.0.3", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: true, transformFunction: null } }, providers: [provideNodeType('parent')], usesInheritance: true, ngImport: i0 }); }
|
|
1547
1548
|
}
|
|
1548
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtParent, decorators: [{
|
|
1549
|
-
type: Directive,
|
|
1550
|
-
args: [{ selector: 'ng-template[parent]', standalone: true, providers: [provideNodeType('parent')] }]
|
|
1551
|
-
}] });
|
|
1552
1549
|
|
|
1553
1550
|
function attach(object, value, paths = []) {
|
|
1554
1551
|
const [base, ...remaining] = paths;
|
|
@@ -1596,10 +1593,22 @@ function attachThreeChild(parent, child) {
|
|
|
1596
1593
|
}
|
|
1597
1594
|
// whether the child is added to the parent with parent.add()
|
|
1598
1595
|
let added = false;
|
|
1596
|
+
let attached = false;
|
|
1599
1597
|
// assign store on child if not already exist
|
|
1598
|
+
// or child store is not the same as parent store
|
|
1600
1599
|
// or child store is the parent of parent store
|
|
1601
|
-
if (!cLS.store || cLS.store === pLS.store.get('previousRoot')) {
|
|
1600
|
+
if (!cLS.store || cLS.store !== pLS.store || cLS.store === pLS.store.get('previousRoot')) {
|
|
1602
1601
|
cLS.store = pLS.store;
|
|
1602
|
+
const grandchildren = [
|
|
1603
|
+
...(cLS.objects ? untracked(cLS.objects) : []),
|
|
1604
|
+
...(cLS.nonObjects ? untracked(cLS.nonObjects) : []),
|
|
1605
|
+
];
|
|
1606
|
+
for (const grandchild of grandchildren) {
|
|
1607
|
+
const grandChildLS = getLocalState(grandchild);
|
|
1608
|
+
if (!grandChildLS)
|
|
1609
|
+
continue;
|
|
1610
|
+
grandChildLS.store = cLS.store;
|
|
1611
|
+
}
|
|
1603
1612
|
}
|
|
1604
1613
|
if (cLS.attach) {
|
|
1605
1614
|
const attachProp = cLS.attach;
|
|
@@ -1628,9 +1637,9 @@ function attachThreeChild(parent, child) {
|
|
|
1628
1637
|
cLS.setParent(parent);
|
|
1629
1638
|
}
|
|
1630
1639
|
// at this point we don't have rawValue yet, so we bail and wait until the Renderer recalls attach
|
|
1631
|
-
if (child.__ngt_renderer__[
|
|
1640
|
+
if (child.__ngt_renderer__[4 /* NgtRendererClassId.rawValue */] === undefined)
|
|
1632
1641
|
return;
|
|
1633
|
-
attach(parent, child.__ngt_renderer__[
|
|
1642
|
+
attach(parent, child.__ngt_renderer__[4 /* NgtRendererClassId.rawValue */], attachProp);
|
|
1634
1643
|
}
|
|
1635
1644
|
else {
|
|
1636
1645
|
attach(parent, child, attachProp);
|
|
@@ -1644,11 +1653,13 @@ function attachThreeChild(parent, child) {
|
|
|
1644
1653
|
added = true;
|
|
1645
1654
|
}
|
|
1646
1655
|
pLS.add(child, added ? 'objects' : 'nonObjects');
|
|
1647
|
-
if (cLS.
|
|
1656
|
+
if (cLS.parent && untracked(cLS.parent) !== parent) {
|
|
1648
1657
|
cLS.setParent(parent);
|
|
1649
1658
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1659
|
+
// NOTE: this does not mean that the child is actually attached to the parent on the scenegraph.
|
|
1660
|
+
// a child on the Angular template can also emit onAttach
|
|
1661
|
+
if (cLS.onAttach)
|
|
1662
|
+
cLS.onAttach({ parent, node: child });
|
|
1652
1663
|
invalidateInstance(child);
|
|
1653
1664
|
invalidateInstance(parent);
|
|
1654
1665
|
}
|
|
@@ -1695,22 +1706,19 @@ function processThreeEvent(instance, priority, eventName, callback) {
|
|
|
1695
1706
|
.get('internal')
|
|
1696
1707
|
.subscribe((state) => callback({ state, object: instance }), priority || lS.priority || 0);
|
|
1697
1708
|
}
|
|
1698
|
-
if (eventName === SPECIAL_EVENTS.
|
|
1699
|
-
|
|
1700
|
-
if (
|
|
1701
|
-
|
|
1702
|
-
const sub = emitter.subscribe(callback);
|
|
1703
|
-
// NOTE: for afterAttach event, if the instance already has a parent,
|
|
1704
|
-
// then we'll emit the event immediately
|
|
1705
|
-
if (eventName === SPECIAL_EVENTS.AFTER_ATTACH && untracked(lS.parent)) {
|
|
1706
|
-
emitter.next({ parent: untracked(lS.parent), node: instance });
|
|
1709
|
+
if (eventName === SPECIAL_EVENTS.ATTACHED) {
|
|
1710
|
+
lS.onAttach = callback;
|
|
1711
|
+
if (untracked(lS.parent)) {
|
|
1712
|
+
lS.onAttach({ parent: untracked(lS.parent), node: instance });
|
|
1707
1713
|
}
|
|
1708
1714
|
return () => {
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1715
|
+
lS.onAttach = undefined;
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
if (eventName === SPECIAL_EVENTS.UPDATED) {
|
|
1719
|
+
lS.onUpdate = callback;
|
|
1720
|
+
return () => {
|
|
1721
|
+
lS.onUpdate = undefined;
|
|
1714
1722
|
};
|
|
1715
1723
|
}
|
|
1716
1724
|
if (!lS.handlers)
|
|
@@ -1728,8 +1736,14 @@ function processThreeEvent(instance, priority, eventName, callback) {
|
|
|
1728
1736
|
lS.eventCount += 1;
|
|
1729
1737
|
// but only add the instance (target) to the interaction array (so that it is handled by the EventManager with Raycast)
|
|
1730
1738
|
// the first time eventCount is incremented
|
|
1731
|
-
if (lS.eventCount === 1 && instance['raycast'])
|
|
1732
|
-
lS.store
|
|
1739
|
+
if (lS.eventCount === 1 && instance['raycast']) {
|
|
1740
|
+
let root = lS.store;
|
|
1741
|
+
while (root.get('previousRoot')) {
|
|
1742
|
+
root = root.get('previousRoot');
|
|
1743
|
+
}
|
|
1744
|
+
const interactions = root.get('internal', 'interaction') || [];
|
|
1745
|
+
interactions.push(instance);
|
|
1746
|
+
}
|
|
1733
1747
|
// clean up the event listener by removing the target from the interaction array
|
|
1734
1748
|
return () => {
|
|
1735
1749
|
const lS = getLocalState(instance);
|
|
@@ -1743,590 +1757,146 @@ function processThreeEvent(instance, priority, eventName, callback) {
|
|
|
1743
1757
|
};
|
|
1744
1758
|
}
|
|
1745
1759
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
this.
|
|
1750
|
-
this.
|
|
1751
|
-
this.
|
|
1760
|
+
class NgtRendererFactory {
|
|
1761
|
+
constructor() {
|
|
1762
|
+
this.delegateRendererFactory = inject(RendererFactory2, { skipSelf: true });
|
|
1763
|
+
this.document = inject(DOCUMENT);
|
|
1764
|
+
this.catalogue = injectCatalogue();
|
|
1765
|
+
this.rootStore = injectStore();
|
|
1752
1766
|
this.portalCommentsNodes = [];
|
|
1767
|
+
this.rendererMap = new Map();
|
|
1768
|
+
this.routedSet = new Set();
|
|
1753
1769
|
}
|
|
1754
|
-
|
|
1755
|
-
const
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
undefined,
|
|
1766
|
-
undefined,
|
|
1767
|
-
undefined,
|
|
1768
|
-
undefined,
|
|
1769
|
-
undefined,
|
|
1770
|
-
undefined,
|
|
1771
|
-
];
|
|
1772
|
-
const rendererNode = Object.assign(node, { __ngt_renderer__: state });
|
|
1773
|
-
// NOTE: assign ownerDocument to node so we can use HostListener in Component
|
|
1774
|
-
if (!rendererNode['ownerDocument'])
|
|
1775
|
-
rendererNode['ownerDocument'] = this.rootState.document;
|
|
1776
|
-
// NOTE: assign injectorFactory on non-three type since
|
|
1777
|
-
// rendererNode is an instance of DOM Node
|
|
1778
|
-
if (state[0 /* NgtRendererClassId.type */] !== 'three') {
|
|
1779
|
-
state[14 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode)?.injector;
|
|
1780
|
-
}
|
|
1781
|
-
if (state[0 /* NgtRendererClassId.type */] === 'comment') {
|
|
1782
|
-
// NOTE: we attach an arrow function to the Comment node
|
|
1783
|
-
// In our directives, we can call this function to then start tracking the RendererNode
|
|
1784
|
-
// this is done to limit the amount of Nodes we need to process for getCreationState
|
|
1785
|
-
rendererNode[SPECIAL_INTERNAL_ADD_COMMENT] = (node) => {
|
|
1786
|
-
if (node === 'args') {
|
|
1787
|
-
this.argsCommentNodes.push(rendererNode);
|
|
1788
|
-
}
|
|
1789
|
-
else if (node === 'parent') {
|
|
1790
|
-
this.parentCommentNodes.push(rendererNode);
|
|
1791
|
-
}
|
|
1792
|
-
else if (typeof node === 'object') {
|
|
1793
|
-
this.portalCommentsNodes.push(node);
|
|
1794
|
-
}
|
|
1795
|
-
};
|
|
1796
|
-
return rendererNode;
|
|
1797
|
-
}
|
|
1798
|
-
if (state[0 /* NgtRendererClassId.type */] === 'compound') {
|
|
1799
|
-
state[8 /* NgtRendererClassId.queueOps */] = new Set();
|
|
1800
|
-
state[9 /* NgtRendererClassId.attributes */] = state[10 /* NgtRendererClassId.properties */] = {};
|
|
1801
|
-
return rendererNode;
|
|
1802
|
-
}
|
|
1803
|
-
return rendererNode;
|
|
1804
|
-
}
|
|
1805
|
-
isCompound(name) {
|
|
1806
|
-
return this.rootState.compoundPrefixes.some((prefix) => name.startsWith(prefix));
|
|
1807
|
-
}
|
|
1808
|
-
isDOM(node) {
|
|
1809
|
-
const rS = node['__ngt_renderer__'];
|
|
1810
|
-
return (!rS ||
|
|
1811
|
-
(rS[0 /* NgtRendererClassId.type */] !== 'compound' &&
|
|
1812
|
-
(node instanceof Element || node instanceof Document || node instanceof Window)));
|
|
1813
|
-
}
|
|
1814
|
-
getClosestParentWithInstance(node) {
|
|
1815
|
-
let parent = node.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1816
|
-
if (parent &&
|
|
1817
|
-
parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'compound' &&
|
|
1818
|
-
parent.__ngt_renderer__[7 /* NgtRendererClassId.compounded */] &&
|
|
1819
|
-
parent.__ngt_renderer__[7 /* NgtRendererClassId.compounded */].__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three') {
|
|
1820
|
-
return parent.__ngt_renderer__[7 /* NgtRendererClassId.compounded */];
|
|
1821
|
-
}
|
|
1822
|
-
if (parent &&
|
|
1823
|
-
parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'portal' &&
|
|
1824
|
-
parent.__ngt_renderer__[13 /* NgtRendererClassId.portalContainer */]?.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three') {
|
|
1825
|
-
return parent.__ngt_renderer__[13 /* NgtRendererClassId.portalContainer */];
|
|
1826
|
-
}
|
|
1827
|
-
while (parent && parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] !== 'three') {
|
|
1828
|
-
parent = parent.__ngt_renderer__[13 /* NgtRendererClassId.portalContainer */]
|
|
1829
|
-
? parent.__ngt_renderer__[13 /* NgtRendererClassId.portalContainer */]
|
|
1830
|
-
: parent.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1831
|
-
}
|
|
1832
|
-
return parent;
|
|
1833
|
-
}
|
|
1834
|
-
getClosestParentWithCompound(node) {
|
|
1835
|
-
if (node.__ngt_renderer__[6 /* NgtRendererClassId.compoundParent */]) {
|
|
1836
|
-
return node.__ngt_renderer__[6 /* NgtRendererClassId.compoundParent */];
|
|
1837
|
-
}
|
|
1838
|
-
let parent = node.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1839
|
-
if (parent &&
|
|
1840
|
-
parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'compound' &&
|
|
1841
|
-
!parent.__ngt_renderer__[7 /* NgtRendererClassId.compounded */]) {
|
|
1842
|
-
return parent;
|
|
1843
|
-
}
|
|
1844
|
-
while (parent &&
|
|
1845
|
-
(parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three' ||
|
|
1846
|
-
!parent.__ngt_renderer__[6 /* NgtRendererClassId.compoundParent */] ||
|
|
1847
|
-
parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] !== 'compound')) {
|
|
1848
|
-
parent = parent.__ngt_renderer__[1 /* NgtRendererClassId.parent */];
|
|
1849
|
-
}
|
|
1850
|
-
if (!parent)
|
|
1851
|
-
return null;
|
|
1852
|
-
if (parent.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three' &&
|
|
1853
|
-
parent.__ngt_renderer__[6 /* NgtRendererClassId.compoundParent */]) {
|
|
1854
|
-
return parent.__ngt_renderer__[6 /* NgtRendererClassId.compoundParent */];
|
|
1770
|
+
createRenderer(hostElement, type) {
|
|
1771
|
+
const delegateRenderer = this.delegateRendererFactory.createRenderer(hostElement, type);
|
|
1772
|
+
if (!type)
|
|
1773
|
+
return delegateRenderer;
|
|
1774
|
+
// NOTE: might need to revisit this
|
|
1775
|
+
if (type['type'][HTML]) {
|
|
1776
|
+
this.rendererMap.set(type.id, delegateRenderer);
|
|
1777
|
+
return delegateRenderer;
|
|
1778
|
+
}
|
|
1779
|
+
if (type['type'][ROUTED_SCENE]) {
|
|
1780
|
+
this.routedSet.add(type.id);
|
|
1855
1781
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1782
|
+
let renderer = this.rendererMap.get(type.id);
|
|
1783
|
+
if (!renderer) {
|
|
1784
|
+
this.rendererMap.set(type.id, (renderer = new NgtRenderer(delegateRenderer, this.rootStore, this.document, this.portalCommentsNodes, this.catalogue,
|
|
1785
|
+
// setting root scene if there's no routed scene OR this component is the routed Scene
|
|
1786
|
+
!hostElement && (this.routedSet.size === 0 || this.routedSet.has(type.id)))));
|
|
1858
1787
|
}
|
|
1859
|
-
return
|
|
1860
|
-
}
|
|
1861
|
-
processPortalContainer(portal) {
|
|
1862
|
-
const injector = portal.__ngt_renderer__[14 /* NgtRendererClassId.injectorFactory */]?.();
|
|
1863
|
-
if (!injector)
|
|
1864
|
-
return;
|
|
1865
|
-
const portalStore = injector.get(NGT_STORE, null);
|
|
1866
|
-
if (!portalStore)
|
|
1867
|
-
return;
|
|
1868
|
-
const portalContainer = portalStore.get('scene');
|
|
1869
|
-
if (!portalContainer)
|
|
1870
|
-
return;
|
|
1871
|
-
portal.__ngt_renderer__[13 /* NgtRendererClassId.portalContainer */] = this.createNode('three', portalContainer);
|
|
1788
|
+
return renderer;
|
|
1872
1789
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
];
|
|
1790
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1791
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtRendererFactory }); }
|
|
1792
|
+
}
|
|
1793
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtRendererFactory, decorators: [{
|
|
1794
|
+
type: Injectable
|
|
1795
|
+
}] });
|
|
1796
|
+
class NgtRenderer {
|
|
1797
|
+
constructor(delegate, rootStore, document, portalCommentsNodes, catalogue, isRoot = true) {
|
|
1798
|
+
this.delegate = delegate;
|
|
1799
|
+
this.rootStore = rootStore;
|
|
1800
|
+
this.document = document;
|
|
1801
|
+
this.portalCommentsNodes = portalCommentsNodes;
|
|
1802
|
+
this.catalogue = catalogue;
|
|
1803
|
+
this.isRoot = isRoot;
|
|
1804
|
+
this.argsCommentNodes = [];
|
|
1805
|
+
this.createText = this.delegate.createText.bind(this.delegate);
|
|
1806
|
+
this.destroy = this.delegate.destroy.bind(this.delegate);
|
|
1807
|
+
this.destroyNode = null;
|
|
1808
|
+
this.selectRootElement = this.delegate.selectRootElement.bind(this.delegate);
|
|
1809
|
+
this.nextSibling = this.delegate.nextSibling.bind(this.delegate);
|
|
1810
|
+
this.addClass = this.delegate.addClass.bind(this.delegate);
|
|
1811
|
+
this.removeClass = this.delegate.removeClass.bind(this.delegate);
|
|
1812
|
+
this.setStyle = this.delegate.setStyle.bind(this.delegate);
|
|
1813
|
+
this.removeStyle = this.delegate.removeStyle.bind(this.delegate);
|
|
1814
|
+
this.setValue = this.delegate.setValue.bind(this.delegate);
|
|
1879
1815
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1816
|
+
createElement(name, namespace) {
|
|
1817
|
+
const element = this.delegate.createElement(name, namespace);
|
|
1818
|
+
// on first pass, we return the Root Scene as the root node
|
|
1819
|
+
if (this.isRoot) {
|
|
1820
|
+
this.isRoot = false;
|
|
1821
|
+
const node = createNode('three', this.rootStore.snapshot.scene, this.document);
|
|
1822
|
+
node.__ngt_renderer__[6 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(element)?.injector;
|
|
1823
|
+
return node;
|
|
1883
1824
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
if (!node.__ngt_renderer__[3 /* NgtRendererClassId.children */].includes(child)) {
|
|
1887
|
-
node.__ngt_renderer__[3 /* NgtRendererClassId.children */].push(child);
|
|
1825
|
+
if (name === SPECIAL_DOM_TAG.NGT_PORTAL) {
|
|
1826
|
+
return createNode('portal', element, this.document);
|
|
1888
1827
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
node
|
|
1828
|
+
if (name === SPECIAL_DOM_TAG.NGT_VALUE) {
|
|
1829
|
+
const instanceStore = signalStore({ parent: null, objects: [], nonObjects: [] });
|
|
1830
|
+
return createNode('three', Object.assign({ __ngt_renderer__: { rawValue: undefined } },
|
|
1831
|
+
// NOTE: we assign this manually to a raw value node
|
|
1832
|
+
// because we say it is a 'three' node but we're not using prepare()
|
|
1833
|
+
{
|
|
1834
|
+
__ngt__: {
|
|
1835
|
+
isRaw: true,
|
|
1836
|
+
instanceStore,
|
|
1837
|
+
setParent(parent) {
|
|
1838
|
+
instanceStore.update({ parent });
|
|
1839
|
+
},
|
|
1840
|
+
},
|
|
1841
|
+
}), this.document);
|
|
1894
1842
|
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
if (
|
|
1902
|
-
|
|
1843
|
+
const [injectedArgs] = [this.getNgtArgs()?.value || []];
|
|
1844
|
+
if (name === SPECIAL_DOM_TAG.NGT_PRIMITIVE) {
|
|
1845
|
+
if (!injectedArgs[0])
|
|
1846
|
+
throw new Error(`[NGT] ngt-primitive without args is invalid`);
|
|
1847
|
+
const object = injectedArgs[0];
|
|
1848
|
+
let localState = getLocalState(object);
|
|
1849
|
+
if (!localState) {
|
|
1850
|
+
// NOTE: if an object isn't already "prepared", we prepare it
|
|
1851
|
+
prepare(object, { store: this.rootStore, primitive: true });
|
|
1903
1852
|
}
|
|
1853
|
+
return createNode('three', object, this.document);
|
|
1904
1854
|
}
|
|
1905
|
-
const
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1855
|
+
const threeName = kebabToPascal(name.startsWith('ngt-') ? name.slice(4) : name);
|
|
1856
|
+
const threeTarget = this.catalogue[threeName];
|
|
1857
|
+
// we have the THREE constructor here, handle it
|
|
1858
|
+
if (threeTarget) {
|
|
1859
|
+
const instance = prepare(new threeTarget(...injectedArgs), { store: this.rootStore });
|
|
1860
|
+
const node = createNode('three', instance, this.document);
|
|
1861
|
+
const localState = getLocalState(instance);
|
|
1862
|
+
// auto-attach for geometry and material
|
|
1863
|
+
if (is.geometry(instance)) {
|
|
1864
|
+
localState.attach = ['geometry'];
|
|
1865
|
+
}
|
|
1866
|
+
else if (is.material(instance)) {
|
|
1867
|
+
localState.attach = ['material'];
|
|
1868
|
+
}
|
|
1869
|
+
return node;
|
|
1912
1870
|
}
|
|
1913
|
-
this.
|
|
1871
|
+
return createNode('dom', element, this.document);
|
|
1914
1872
|
}
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
if (op[0 /* NgtQueueOpClassId.type */] === type) {
|
|
1924
|
-
op[1 /* NgtQueueOpClassId.op */]();
|
|
1925
|
-
rS[8 /* NgtRendererClassId.queueOps */].delete(op);
|
|
1926
|
-
}
|
|
1927
|
-
});
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
applyAttribute(node, name, value) {
|
|
1931
|
-
const rS = node.__ngt_renderer__;
|
|
1932
|
-
if (rS[4 /* NgtRendererClassId.destroyed */])
|
|
1933
|
-
return;
|
|
1934
|
-
if (name === SPECIAL_PROPERTIES.RENDER_PRIORITY) {
|
|
1935
|
-
// NOTE: priority needs to be set as an attribute string so that they can be set as early as possible
|
|
1936
|
-
// we convert that string to a number. if it's invalid, default 0
|
|
1937
|
-
let priority = Number(value);
|
|
1938
|
-
if (isNaN(priority)) {
|
|
1939
|
-
priority = 0;
|
|
1940
|
-
console.warn(`[NGT] "priority" is an invalid number, default to 0`);
|
|
1941
|
-
}
|
|
1942
|
-
const localState = getLocalState(node);
|
|
1943
|
-
if (localState) {
|
|
1944
|
-
localState.priority = priority;
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
if (name === SPECIAL_PROPERTIES.COMPOUND) {
|
|
1948
|
-
// NOTE: we set the compound property on instance node now so we know that this instance is being compounded
|
|
1949
|
-
rS[5 /* NgtRendererClassId.compound */] = [value === '' || value === 'first', {}];
|
|
1950
|
-
return;
|
|
1951
|
-
}
|
|
1952
|
-
if (name === SPECIAL_PROPERTIES.ATTACH) {
|
|
1953
|
-
// NOTE: handle attach as tring
|
|
1954
|
-
const paths = value.split('.');
|
|
1955
|
-
if (paths.length) {
|
|
1956
|
-
const localState = getLocalState(node);
|
|
1957
|
-
if (localState) {
|
|
1958
|
-
localState.attach = paths;
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
return;
|
|
1962
|
-
}
|
|
1963
|
-
if (name === SPECIAL_PROPERTIES.RAW_VALUE) {
|
|
1964
|
-
// NOTE: coercion
|
|
1965
|
-
let maybeCoerced = value;
|
|
1966
|
-
if (maybeCoerced === '' || maybeCoerced === 'true' || maybeCoerced === 'false') {
|
|
1967
|
-
maybeCoerced = maybeCoerced === 'true' || maybeCoerced === '';
|
|
1968
|
-
}
|
|
1969
|
-
else if (!isNaN(Number(maybeCoerced))) {
|
|
1970
|
-
maybeCoerced = Number(maybeCoerced);
|
|
1971
|
-
}
|
|
1972
|
-
rS[11 /* NgtRendererClassId.rawValue */] = maybeCoerced;
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
applyProps(node, { [name]: value });
|
|
1976
|
-
this.updateNativeProps(node, name, value);
|
|
1977
|
-
}
|
|
1978
|
-
applyProperty(node, name, value) {
|
|
1979
|
-
const rS = node.__ngt_renderer__;
|
|
1980
|
-
if (rS[4 /* NgtRendererClassId.destroyed */])
|
|
1981
|
-
return;
|
|
1982
|
-
// [ref]
|
|
1983
|
-
if (name === SPECIAL_PROPERTIES.REF && is.ref(value)) {
|
|
1984
|
-
rS[12 /* NgtRendererClassId.ref */] = value;
|
|
1985
|
-
value.nativeElement = node;
|
|
1986
|
-
return;
|
|
1987
|
-
}
|
|
1988
|
-
const localState = getLocalState(node);
|
|
1989
|
-
const parent = localState?.instanceStore.get('parent') || rS[1 /* NgtRendererClassId.parent */];
|
|
1990
|
-
// [rawValue]
|
|
1991
|
-
if (localState?.isRaw && name === SPECIAL_PROPERTIES.RAW_VALUE) {
|
|
1992
|
-
rS[11 /* NgtRendererClassId.rawValue */] = value;
|
|
1993
|
-
if (parent)
|
|
1994
|
-
attachThreeChild(parent, node);
|
|
1995
|
-
return;
|
|
1996
|
-
}
|
|
1997
|
-
// [attach]
|
|
1998
|
-
if (name === SPECIAL_PROPERTIES.ATTACH) {
|
|
1999
|
-
if (localState)
|
|
2000
|
-
localState.attach = Array.isArray(value) ? value.map((v) => v.toString()) : value;
|
|
2001
|
-
if (parent)
|
|
2002
|
-
attachThreeChild(parent, node);
|
|
2003
|
-
return;
|
|
2004
|
-
}
|
|
2005
|
-
const compound = rS[5 /* NgtRendererClassId.compound */];
|
|
2006
|
-
if (compound?.[1 /* NgtCompoundClassId.props */] &&
|
|
2007
|
-
name in compound[1 /* NgtCompoundClassId.props */] &&
|
|
2008
|
-
!compound[0 /* NgtCompoundClassId.applyFirst */]) {
|
|
2009
|
-
value = compound[1 /* NgtCompoundClassId.props */][name];
|
|
2010
|
-
}
|
|
2011
|
-
applyProps(node, { [name]: value });
|
|
2012
|
-
this.updateNativeProps(node, name, value);
|
|
2013
|
-
}
|
|
2014
|
-
applyParameters(node, parameters) {
|
|
2015
|
-
const rS = node.__ngt_renderer__;
|
|
2016
|
-
if (rS[4 /* NgtRendererClassId.destroyed */])
|
|
2017
|
-
return;
|
|
2018
|
-
applyProps(node, parameters);
|
|
2019
|
-
this.updateNativeProps(node, 'parameters', parameters);
|
|
2020
|
-
}
|
|
2021
|
-
get rootScene() {
|
|
2022
|
-
return this.rootState.store.get('scene');
|
|
2023
|
-
}
|
|
2024
|
-
destroy(node, parent) {
|
|
2025
|
-
const rS = node.__ngt_renderer__;
|
|
2026
|
-
if (!rS || rS[4 /* NgtRendererClassId.destroyed */])
|
|
2027
|
-
return;
|
|
2028
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2029
|
-
rS[5 /* NgtRendererClassId.compound */] = undefined;
|
|
2030
|
-
rS[6 /* NgtRendererClassId.compoundParent */] = undefined;
|
|
2031
|
-
const localState = getLocalState(node);
|
|
2032
|
-
if (localState?.instanceStore) {
|
|
2033
|
-
localState.instanceStore.get('objects').forEach((obj) => this.destroy(obj, parent));
|
|
2034
|
-
localState.instanceStore.get('nonObjects').forEach((obj) => this.destroy(obj, parent));
|
|
2035
|
-
}
|
|
2036
|
-
if (localState?.afterUpdate)
|
|
2037
|
-
localState.afterUpdate.complete();
|
|
2038
|
-
if (localState?.afterAttach)
|
|
2039
|
-
localState.afterAttach.complete();
|
|
2040
|
-
delete localState['objects'];
|
|
2041
|
-
delete localState['nonObjects'];
|
|
2042
|
-
delete localState['parent'];
|
|
2043
|
-
delete localState['nativeProps'];
|
|
2044
|
-
delete localState['add'];
|
|
2045
|
-
delete localState['remove'];
|
|
2046
|
-
delete localState['afterUpdate'];
|
|
2047
|
-
delete localState['afterAttach'];
|
|
2048
|
-
delete localState['store'];
|
|
2049
|
-
delete localState['handlers'];
|
|
2050
|
-
if (!localState?.primitive) {
|
|
2051
|
-
delete node['__ngt__'];
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'comment') {
|
|
2055
|
-
rS[14 /* NgtRendererClassId.injectorFactory */] = null;
|
|
2056
|
-
delete node[SPECIAL_INTERNAL_ADD_COMMENT];
|
|
2057
|
-
if (!this.removeCommentNode(node, this.argsCommentNodes)) {
|
|
2058
|
-
this.removeCommentNode(node, this.parentCommentNodes);
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'portal') {
|
|
2062
|
-
rS[14 /* NgtRendererClassId.injectorFactory */] = null;
|
|
2063
|
-
this.removeCommentNode(node, this.portalCommentsNodes);
|
|
2064
|
-
}
|
|
2065
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'compound') {
|
|
2066
|
-
rS[7 /* NgtRendererClassId.compounded */] = undefined;
|
|
2067
|
-
rS[9 /* NgtRendererClassId.attributes */] = null;
|
|
2068
|
-
rS[10 /* NgtRendererClassId.properties */] = null;
|
|
2069
|
-
this.executeOperation(node, 'cleanUp');
|
|
2070
|
-
rS[8 /* NgtRendererClassId.queueOps */].clear();
|
|
2071
|
-
rS[8 /* NgtRendererClassId.queueOps */] = null;
|
|
2072
|
-
}
|
|
2073
|
-
if (rS[12 /* NgtRendererClassId.ref */]) {
|
|
2074
|
-
// nullify ref
|
|
2075
|
-
// but we do it later so that it doesn't hinder render
|
|
2076
|
-
// TODO: will this cause memory leak?
|
|
2077
|
-
requestAnimationFrame(() => {
|
|
2078
|
-
rS[12 /* NgtRendererClassId.ref */].nativeElement = null;
|
|
2079
|
-
rS[12 /* NgtRendererClassId.ref */] = undefined;
|
|
2080
|
-
});
|
|
2081
|
-
}
|
|
2082
|
-
// nullify parent
|
|
2083
|
-
rS[1 /* NgtRendererClassId.parent */] = null;
|
|
2084
|
-
for (const renderChild of rS[3 /* NgtRendererClassId.children */] || []) {
|
|
2085
|
-
if (renderChild.__ngt_renderer__?.[0 /* NgtRendererClassId.type */] === 'three' && parent) {
|
|
2086
|
-
if (parent.__ngt_renderer__?.[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2087
|
-
removeThreeChild(parent, renderChild, true);
|
|
2088
|
-
continue;
|
|
2089
|
-
}
|
|
2090
|
-
const closestInstance = this.getClosestParentWithInstance(parent);
|
|
2091
|
-
if (closestInstance) {
|
|
2092
|
-
removeThreeChild(closestInstance, renderChild, true);
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
this.destroy(renderChild, parent);
|
|
2096
|
-
}
|
|
2097
|
-
rS[3 /* NgtRendererClassId.children */] = [];
|
|
2098
|
-
rS[4 /* NgtRendererClassId.destroyed */] = true;
|
|
2099
|
-
if (parent) {
|
|
2100
|
-
this.removeChild(parent, node);
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
removeCommentNode(node, nodes) {
|
|
2104
|
-
const index = nodes.findIndex((comment) => comment === node);
|
|
2105
|
-
if (index > -1) {
|
|
2106
|
-
nodes.splice(index, 1);
|
|
2107
|
-
return true;
|
|
2108
|
-
}
|
|
2109
|
-
return false;
|
|
2110
|
-
}
|
|
2111
|
-
updateNativeProps(node, key, value) {
|
|
2112
|
-
const localState = getLocalState(node);
|
|
2113
|
-
localState?.setNativeProps(key, value);
|
|
2114
|
-
}
|
|
2115
|
-
firstNonInjectedDirective(listProperty, dir) {
|
|
2116
|
-
let directive;
|
|
2117
|
-
const destroyed = [];
|
|
2118
|
-
let i = this[listProperty].length - 1;
|
|
2119
|
-
while (i >= 0) {
|
|
2120
|
-
const comment = this[listProperty][i];
|
|
2121
|
-
if (comment.__ngt_renderer__[4 /* NgtRendererClassId.destroyed */]) {
|
|
2122
|
-
destroyed.push(i);
|
|
2123
|
-
i--;
|
|
2124
|
-
continue;
|
|
2125
|
-
}
|
|
2126
|
-
const injector = comment.__ngt_renderer__[14 /* NgtRendererClassId.injectorFactory */]();
|
|
2127
|
-
if (!injector) {
|
|
2128
|
-
i--;
|
|
2129
|
-
continue;
|
|
2130
|
-
}
|
|
2131
|
-
const instance = injector.get(dir, null);
|
|
2132
|
-
if (instance && instance.validate()) {
|
|
2133
|
-
directive = instance;
|
|
2134
|
-
break;
|
|
2135
|
-
}
|
|
2136
|
-
i--;
|
|
2137
|
-
}
|
|
2138
|
-
destroyed.forEach((index) => {
|
|
2139
|
-
this[listProperty].splice(index, 1);
|
|
2140
|
-
});
|
|
2141
|
-
return directive;
|
|
2142
|
-
}
|
|
2143
|
-
tryGetPortalStore() {
|
|
2144
|
-
let store;
|
|
2145
|
-
const destroyed = [];
|
|
2146
|
-
// we only care about the portal states because NgtStore only differs per Portal
|
|
2147
|
-
let i = this.portalCommentsNodes.length - 1;
|
|
2148
|
-
while (i >= 0) {
|
|
2149
|
-
// loop through the portal state backwards to find the closest NgtStore
|
|
2150
|
-
const portal = this.portalCommentsNodes[i];
|
|
2151
|
-
if (portal.__ngt_renderer__[4 /* NgtRendererClassId.destroyed */]) {
|
|
2152
|
-
destroyed.push(i);
|
|
2153
|
-
i--;
|
|
2154
|
-
continue;
|
|
2155
|
-
}
|
|
2156
|
-
const injector = portal.__ngt_renderer__[14 /* NgtRendererClassId.injectorFactory */]();
|
|
2157
|
-
if (!injector) {
|
|
2158
|
-
i--;
|
|
2159
|
-
continue;
|
|
2160
|
-
}
|
|
2161
|
-
const instance = injector.get(NGT_STORE, null);
|
|
2162
|
-
// only the instance with previousRoot should pass
|
|
2163
|
-
if (instance && instance.get('previousRoot')) {
|
|
2164
|
-
store = instance;
|
|
2165
|
-
break;
|
|
2166
|
-
}
|
|
2167
|
-
i--;
|
|
2168
|
-
}
|
|
2169
|
-
destroyed.forEach((index) => {
|
|
2170
|
-
this.portalCommentsNodes.splice(index, 1);
|
|
2171
|
-
});
|
|
2172
|
-
return store || this.rootState.store;
|
|
2173
|
-
}
|
|
2174
|
-
}
|
|
2175
|
-
|
|
2176
|
-
class NgtRendererFactory {
|
|
2177
|
-
constructor() {
|
|
2178
|
-
this.delegateRendererFactory = inject(RendererFactory2, { skipSelf: true });
|
|
2179
|
-
this.catalogue = injectNgtCatalogue();
|
|
2180
|
-
this.rendererMap = new Map();
|
|
2181
|
-
this.routedSet = new Set();
|
|
2182
|
-
// NOTE: all Renderer instances under the same NgtCanvas share the same Store
|
|
2183
|
-
this.rendererStore = new NgtRendererStore({
|
|
2184
|
-
store: injectNgtStore(),
|
|
2185
|
-
compoundPrefixes: inject(NGT_COMPOUND_PREFIXES),
|
|
2186
|
-
document: inject(DOCUMENT),
|
|
2187
|
-
});
|
|
2188
|
-
}
|
|
2189
|
-
createRenderer(hostElement, type) {
|
|
2190
|
-
const delegateRenderer = this.delegateRendererFactory.createRenderer(hostElement, type);
|
|
2191
|
-
if (!type)
|
|
2192
|
-
return delegateRenderer;
|
|
2193
|
-
// NOTE: might need to revisit this
|
|
2194
|
-
if (type['type'][HTML]) {
|
|
2195
|
-
this.rendererMap.set(type.id, delegateRenderer);
|
|
2196
|
-
return delegateRenderer;
|
|
2197
|
-
}
|
|
2198
|
-
if (type['type'][ROUTED_SCENE]) {
|
|
2199
|
-
this.routedSet.add(type.id);
|
|
2200
|
-
}
|
|
2201
|
-
let renderer = this.rendererMap.get(type.id);
|
|
2202
|
-
if (!renderer) {
|
|
2203
|
-
this.rendererMap.set(type.id, (renderer = new NgtRenderer(delegateRenderer, this.rendererStore, this.catalogue,
|
|
2204
|
-
// setting root scene if there's no routed scene OR this component is the routed Scene
|
|
2205
|
-
!hostElement && (this.routedSet.size === 0 || this.routedSet.has(type.id)))));
|
|
2206
|
-
}
|
|
2207
|
-
return renderer;
|
|
2208
|
-
}
|
|
2209
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2210
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtRendererFactory }); }
|
|
2211
|
-
}
|
|
2212
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtRendererFactory, decorators: [{
|
|
2213
|
-
type: Injectable
|
|
2214
|
-
}] });
|
|
2215
|
-
class NgtRenderer {
|
|
2216
|
-
constructor(delegate, store, catalogue, isRoot = true) {
|
|
2217
|
-
this.delegate = delegate;
|
|
2218
|
-
this.store = store;
|
|
2219
|
-
this.catalogue = catalogue;
|
|
2220
|
-
this.isRoot = isRoot;
|
|
2221
|
-
this.createText = this.delegate.createText.bind(this.delegate);
|
|
2222
|
-
this.destroy = this.delegate.destroy.bind(this.delegate);
|
|
2223
|
-
this.destroyNode = null;
|
|
2224
|
-
this.selectRootElement = this.delegate.selectRootElement.bind(this.delegate);
|
|
2225
|
-
this.nextSibling = this.delegate.nextSibling.bind(this.delegate);
|
|
2226
|
-
this.addClass = this.delegate.addClass.bind(this.delegate);
|
|
2227
|
-
this.removeClass = this.delegate.removeClass.bind(this.delegate);
|
|
2228
|
-
this.setStyle = this.delegate.setStyle.bind(this.delegate);
|
|
2229
|
-
this.removeStyle = this.delegate.removeStyle.bind(this.delegate);
|
|
2230
|
-
this.setValue = this.delegate.setValue.bind(this.delegate);
|
|
2231
|
-
}
|
|
2232
|
-
createElement(name, namespace) {
|
|
2233
|
-
const element = this.delegate.createElement(name, namespace);
|
|
2234
|
-
// on first pass, we return the Root Scene as the root node
|
|
2235
|
-
if (this.isRoot) {
|
|
2236
|
-
this.isRoot = false;
|
|
2237
|
-
const node = this.store.createNode('three', this.store.rootScene);
|
|
2238
|
-
node.__ngt_renderer__[14 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(element)?.injector;
|
|
2239
|
-
return node;
|
|
2240
|
-
}
|
|
2241
|
-
if (this.store.isCompound(name)) {
|
|
2242
|
-
return this.store.createNode('compound', element);
|
|
2243
|
-
}
|
|
2244
|
-
if (name === SPECIAL_DOM_TAG.NGT_PORTAL) {
|
|
2245
|
-
return this.store.createNode('portal', element);
|
|
2246
|
-
}
|
|
2247
|
-
if (name === SPECIAL_DOM_TAG.NGT_VALUE) {
|
|
2248
|
-
const instanceStore = signalStore({
|
|
2249
|
-
nativeProps: {},
|
|
2250
|
-
parent: null,
|
|
2251
|
-
objects: [],
|
|
2252
|
-
nonObjects: [],
|
|
2253
|
-
});
|
|
2254
|
-
return this.store.createNode('three', Object.assign({ __ngt_renderer__: { rawValue: undefined } },
|
|
2255
|
-
// NOTE: we assign this manually to a raw value node
|
|
2256
|
-
// because we say it is a 'three' node but we're not using prepare()
|
|
2257
|
-
{
|
|
2258
|
-
__ngt__: {
|
|
2259
|
-
isRaw: true,
|
|
2260
|
-
instanceStore,
|
|
2261
|
-
setNativeProps(key, value) {
|
|
2262
|
-
instanceStore.update((prev) => ({ nativeProps: { ...prev.nativeProps, [key]: value } }));
|
|
2263
|
-
},
|
|
2264
|
-
setParent(parent) {
|
|
2265
|
-
instanceStore.update({ parent });
|
|
2266
|
-
},
|
|
2267
|
-
},
|
|
2268
|
-
}));
|
|
2269
|
-
}
|
|
2270
|
-
const [injectedArgs, injectedParent, store] = this.store.getCreationState();
|
|
2271
|
-
let parent = injectedParent;
|
|
2272
|
-
if (typeof injectedParent === 'string') {
|
|
2273
|
-
parent = store
|
|
2274
|
-
.get('scene')
|
|
2275
|
-
.getObjectByName(injectedParent);
|
|
2276
|
-
}
|
|
2277
|
-
if (name === SPECIAL_DOM_TAG.NGT_PRIMITIVE) {
|
|
2278
|
-
if (!injectedArgs[0])
|
|
2279
|
-
throw new Error(`[NGT] ngt-primitive without args is invalid`);
|
|
2280
|
-
const object = injectedArgs[0];
|
|
2281
|
-
let localState = getLocalState(object);
|
|
2282
|
-
if (!localState) {
|
|
2283
|
-
// NOTE: if an object isn't already "prepared", we prepare it
|
|
2284
|
-
localState = getLocalState(prepare(object, { store, args: injectedArgs, primitive: true }));
|
|
2285
|
-
}
|
|
2286
|
-
if (!localState.store)
|
|
2287
|
-
localState.store = store;
|
|
2288
|
-
const node = this.store.createNode('three', object);
|
|
2289
|
-
if (parent) {
|
|
2290
|
-
node.__ngt_renderer__[2 /* NgtRendererClassId.injectedParent */] = parent;
|
|
2291
|
-
}
|
|
2292
|
-
return node;
|
|
2293
|
-
}
|
|
2294
|
-
const threeName = kebabToPascal(name.startsWith('ngt') ? name.slice(4) : name);
|
|
2295
|
-
const threeTarget = this.catalogue[threeName];
|
|
2296
|
-
// we have the THREE constructor here, handle it
|
|
2297
|
-
if (threeTarget) {
|
|
2298
|
-
const instance = prepare(new threeTarget(...injectedArgs), { store, args: injectedArgs });
|
|
2299
|
-
const node = this.store.createNode('three', instance);
|
|
2300
|
-
const localState = getLocalState(instance);
|
|
2301
|
-
// auto-attach for geometry and material
|
|
2302
|
-
if (is.geometry(instance)) {
|
|
2303
|
-
localState.attach = ['geometry'];
|
|
2304
|
-
}
|
|
2305
|
-
else if (is.material(instance)) {
|
|
2306
|
-
localState.attach = ['material'];
|
|
1873
|
+
createComment(value) {
|
|
1874
|
+
const comment = this.delegate.createComment(value);
|
|
1875
|
+
// NOTE: we attach an arrow function to the Comment node
|
|
1876
|
+
// In our directives, we can call this function to then start tracking the RendererNode
|
|
1877
|
+
// this is done to limit the amount of Nodes we need to process for getCreationState
|
|
1878
|
+
comment[SPECIAL_INTERNAL_ADD_COMMENT] = (node) => {
|
|
1879
|
+
if (node === 'args') {
|
|
1880
|
+
this.argsCommentNodes.push(comment);
|
|
2307
1881
|
}
|
|
2308
|
-
if (
|
|
2309
|
-
|
|
1882
|
+
else if (typeof node === 'object') {
|
|
1883
|
+
this.portalCommentsNodes.push(node);
|
|
2310
1884
|
}
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
return this.store.createNode('dom', element);
|
|
2314
|
-
}
|
|
2315
|
-
createComment(value) {
|
|
2316
|
-
return this.store.createNode('comment', this.delegate.createComment(value));
|
|
1885
|
+
};
|
|
1886
|
+
return createNode('comment', comment, this.document);
|
|
2317
1887
|
}
|
|
2318
1888
|
appendChild(parent, newChild) {
|
|
2319
1889
|
const pRS = parent.__ngt_renderer__;
|
|
2320
1890
|
const cRS = newChild.__ngt_renderer__;
|
|
2321
1891
|
if (pRS[0 /* NgtRendererClassId.type */] === 'dom' &&
|
|
2322
1892
|
(newChild instanceof Text || cRS[0 /* NgtRendererClassId.type */] === 'dom')) {
|
|
2323
|
-
|
|
1893
|
+
addChild(parent, newChild);
|
|
2324
1894
|
this.delegate.appendChild(parent, newChild);
|
|
2325
1895
|
if (cRS) {
|
|
2326
|
-
|
|
1896
|
+
setParent(newChild, parent);
|
|
2327
1897
|
if (this.shouldFindGrandparentInstance(pRS, cRS, newChild)) {
|
|
2328
1898
|
// we'll try to get the grandparent instance here so that we can run appendChild with both instances
|
|
2329
|
-
const closestGrandparentInstance =
|
|
1899
|
+
const closestGrandparentInstance = getClosestParentWithInstance(parent);
|
|
2330
1900
|
if (closestGrandparentInstance)
|
|
2331
1901
|
this.appendChild(closestGrandparentInstance, newChild);
|
|
2332
1902
|
}
|
|
@@ -2334,48 +1904,26 @@ class NgtRenderer {
|
|
|
2334
1904
|
return;
|
|
2335
1905
|
}
|
|
2336
1906
|
if (cRS?.[0 /* NgtRendererClassId.type */] === 'comment') {
|
|
2337
|
-
|
|
1907
|
+
setParent(newChild, parent);
|
|
2338
1908
|
return;
|
|
2339
1909
|
}
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
const injector = cRS[14 /* NgtRendererClassId.injectorFactory */]()?.get(Injector, null);
|
|
2343
|
-
if (!injector) {
|
|
2344
|
-
console.warn(`[NGT] NgtRenderer is attempting to start an effect for injectedParent but no Injector is found.`);
|
|
2345
|
-
return;
|
|
2346
|
-
}
|
|
2347
|
-
const watcher = effect(() => {
|
|
2348
|
-
const injectedParent = cRS[2 /* NgtRendererClassId.injectedParent */]
|
|
2349
|
-
.nativeElement;
|
|
2350
|
-
if (injectedParent && injectedParent !== parent) {
|
|
2351
|
-
this.appendChild(injectedParent, newChild);
|
|
2352
|
-
// only run this effect once
|
|
2353
|
-
// as soon as we re-run appendChild with the injectedParent, we stop the effect
|
|
2354
|
-
watcher.destroy();
|
|
2355
|
-
}
|
|
2356
|
-
}, { injector, manualCleanup: true });
|
|
2357
|
-
return;
|
|
2358
|
-
}
|
|
2359
|
-
else if (parent !== cRS[2 /* NgtRendererClassId.injectedParent */]) {
|
|
2360
|
-
this.appendChild(cRS[2 /* NgtRendererClassId.injectedParent */], newChild);
|
|
2361
|
-
return;
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2364
|
-
this.store.setParent(newChild, parent);
|
|
2365
|
-
this.store.addChild(parent, newChild);
|
|
1910
|
+
setParent(newChild, parent);
|
|
1911
|
+
addChild(parent, newChild);
|
|
2366
1912
|
// if new child is a portal
|
|
2367
1913
|
if (cRS?.[0 /* NgtRendererClassId.type */] === 'portal') {
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
1914
|
+
if (!cRS[5 /* NgtRendererClassId.portalContainer */])
|
|
1915
|
+
this.processPortalContainer(newChild);
|
|
1916
|
+
if (cRS[5 /* NgtRendererClassId.portalContainer */]) {
|
|
1917
|
+
this.appendChild(parent, cRS[5 /* NgtRendererClassId.portalContainer */]);
|
|
2371
1918
|
}
|
|
2372
1919
|
return;
|
|
2373
1920
|
}
|
|
2374
1921
|
// if parent is a portal
|
|
2375
1922
|
if (pRS[0 /* NgtRendererClassId.type */] === 'portal') {
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
1923
|
+
if (!pRS[5 /* NgtRendererClassId.portalContainer */])
|
|
1924
|
+
this.processPortalContainer(parent);
|
|
1925
|
+
if (pRS[5 /* NgtRendererClassId.portalContainer */]) {
|
|
1926
|
+
this.appendChild(pRS[5 /* NgtRendererClassId.portalContainer */], newChild);
|
|
2379
1927
|
}
|
|
2380
1928
|
return;
|
|
2381
1929
|
}
|
|
@@ -2389,43 +1937,17 @@ class NgtRenderer {
|
|
|
2389
1937
|
return;
|
|
2390
1938
|
// attach THREE child
|
|
2391
1939
|
attachThreeChild(parent, newChild);
|
|
2392
|
-
// here, we handle the special case of if the parent has a compoundParent, which means this child is part of a compound parent template
|
|
2393
|
-
if (!cRS[5 /* NgtRendererClassId.compound */])
|
|
2394
|
-
return;
|
|
2395
|
-
const closestGrandparentWithCompound = this.store.getClosestParentWithCompound(parent);
|
|
2396
|
-
if (!closestGrandparentWithCompound)
|
|
2397
|
-
return;
|
|
2398
|
-
this.appendChild(closestGrandparentWithCompound, newChild);
|
|
2399
1940
|
return;
|
|
2400
1941
|
}
|
|
2401
1942
|
// if only the parent is the THREE instance
|
|
2402
1943
|
if (pRS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2403
|
-
for (const renderChild of cRS?.[
|
|
1944
|
+
for (const renderChild of cRS?.[2 /* NgtRendererClassId.children */] || []) {
|
|
2404
1945
|
this.appendChild(parent, renderChild);
|
|
2405
1946
|
}
|
|
2406
1947
|
}
|
|
2407
|
-
// if parent is a compound
|
|
2408
|
-
if (pRS[0 /* NgtRendererClassId.type */] === 'compound') {
|
|
2409
|
-
// if compound doesn't have a THREE instance set yet
|
|
2410
|
-
if (!pRS[7 /* NgtRendererClassId.compounded */] && cRS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2411
|
-
// if child is indeed an ngtCompound
|
|
2412
|
-
if (cRS[5 /* NgtRendererClassId.compound */])
|
|
2413
|
-
this.store.setCompound(parent, newChild);
|
|
2414
|
-
// if not, we track the parent (that is supposedly the compound component) on this three instance
|
|
2415
|
-
else if (!cRS[6 /* NgtRendererClassId.compoundParent */])
|
|
2416
|
-
cRS[6 /* NgtRendererClassId.compoundParent */] = parent;
|
|
2417
|
-
}
|
|
2418
|
-
// reset the compound if it's changed
|
|
2419
|
-
if (pRS[7 /* NgtRendererClassId.compounded */] &&
|
|
2420
|
-
cRS[0 /* NgtRendererClassId.type */] === 'three' &&
|
|
2421
|
-
cRS[5 /* NgtRendererClassId.compound */] &&
|
|
2422
|
-
pRS[7 /* NgtRendererClassId.compounded */] !== newChild) {
|
|
2423
|
-
this.store.setCompound(parent, newChild);
|
|
2424
|
-
}
|
|
2425
|
-
}
|
|
2426
1948
|
if (this.shouldFindGrandparentInstance(pRS, cRS, newChild)) {
|
|
2427
1949
|
// we'll try to get the grandparent instance here so that we can run appendChild with both instances
|
|
2428
|
-
const closestGrandparentInstance =
|
|
1950
|
+
const closestGrandparentInstance = getClosestParentWithInstance(parent);
|
|
2429
1951
|
if (closestGrandparentInstance)
|
|
2430
1952
|
this.appendChild(closestGrandparentInstance, newChild);
|
|
2431
1953
|
return;
|
|
@@ -2443,42 +1965,32 @@ class NgtRenderer {
|
|
|
2443
1965
|
parent instanceof Element &&
|
|
2444
1966
|
(oldChild instanceof Element || oldChild instanceof Text || oldChild instanceof Comment)) {
|
|
2445
1967
|
this.delegate.removeChild(parent, oldChild);
|
|
2446
|
-
this.
|
|
1968
|
+
this.destroyInternal(oldChild, parent);
|
|
2447
1969
|
return;
|
|
2448
1970
|
}
|
|
2449
1971
|
if (cRS[0 /* NgtRendererClassId.type */] === 'dom' && (!pRS || pRS[0 /* NgtRendererClassId.type */] === 'dom')) {
|
|
2450
1972
|
this.delegate.removeChild(parent, oldChild);
|
|
2451
|
-
this.
|
|
1973
|
+
this.destroyInternal(oldChild, parent);
|
|
2452
1974
|
return;
|
|
2453
1975
|
}
|
|
2454
1976
|
if (pRS[0 /* NgtRendererClassId.type */] === 'three' && cRS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2455
1977
|
removeThreeChild(parent, oldChild, true);
|
|
2456
|
-
this.
|
|
1978
|
+
this.destroyInternal(oldChild, parent);
|
|
2457
1979
|
return;
|
|
2458
1980
|
}
|
|
2459
|
-
if (pRS[0 /* NgtRendererClassId.type */] === 'compound') {
|
|
2460
|
-
if (pRS[7 /* NgtRendererClassId.compounded */]) {
|
|
2461
|
-
this.removeChild(pRS[7 /* NgtRendererClassId.compounded */], oldChild, isHostElement);
|
|
2462
|
-
return;
|
|
2463
|
-
}
|
|
2464
|
-
if (pRS[1 /* NgtRendererClassId.parent */]) {
|
|
2465
|
-
this.removeChild(pRS[1 /* NgtRendererClassId.parent */], oldChild, isHostElement);
|
|
2466
|
-
return;
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
1981
|
if (pRS[0 /* NgtRendererClassId.type */] === 'portal' &&
|
|
2470
|
-
pRS[
|
|
2471
|
-
this.removeChild(pRS[
|
|
1982
|
+
pRS[5 /* NgtRendererClassId.portalContainer */]?.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'three') {
|
|
1983
|
+
this.removeChild(pRS[5 /* NgtRendererClassId.portalContainer */], oldChild, isHostElement);
|
|
2472
1984
|
return;
|
|
2473
1985
|
}
|
|
2474
1986
|
if (pRS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2475
|
-
this.
|
|
1987
|
+
this.destroyInternal(oldChild, parent);
|
|
2476
1988
|
return;
|
|
2477
1989
|
}
|
|
2478
|
-
const closestGrandparentInstance =
|
|
1990
|
+
const closestGrandparentInstance = getClosestParentWithInstance(parent);
|
|
2479
1991
|
if (closestGrandparentInstance)
|
|
2480
1992
|
this.removeChild(closestGrandparentInstance, oldChild, isHostElement);
|
|
2481
|
-
this.
|
|
1993
|
+
this.destroyInternal(oldChild, closestGrandparentInstance);
|
|
2482
1994
|
}
|
|
2483
1995
|
parentNode(node) {
|
|
2484
1996
|
const rS = node.__ngt_renderer__;
|
|
@@ -2488,17 +2000,42 @@ class NgtRenderer {
|
|
|
2488
2000
|
}
|
|
2489
2001
|
setAttributeInternal(el, name, value, namespace) {
|
|
2490
2002
|
const rS = el.__ngt_renderer__;
|
|
2491
|
-
if (rS[
|
|
2492
|
-
|
|
2493
|
-
rS[9 /* NgtRendererClassId.attributes */][name] = value;
|
|
2494
|
-
if (!rS[7 /* NgtRendererClassId.compounded */]) {
|
|
2495
|
-
this.store.queueOperation(el, ['op', () => this.setAttribute(el, name, value, namespace)]);
|
|
2496
|
-
return false;
|
|
2497
|
-
}
|
|
2498
|
-
return this.setAttributeInternal(rS[7 /* NgtRendererClassId.compounded */], name, value, namespace);
|
|
2499
|
-
}
|
|
2003
|
+
if (rS[3 /* NgtRendererClassId.destroyed */])
|
|
2004
|
+
return false;
|
|
2500
2005
|
if (rS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2501
|
-
|
|
2006
|
+
if (name === SPECIAL_PROPERTIES.RENDER_PRIORITY) {
|
|
2007
|
+
// NOTE: priority needs to be set as an attribute string so that they can be set as early as possible
|
|
2008
|
+
// we convert that string to a number. if it's invalid, default 0
|
|
2009
|
+
let priority = Number(value);
|
|
2010
|
+
if (isNaN(priority)) {
|
|
2011
|
+
priority = 0;
|
|
2012
|
+
console.warn(`[NGT] "priority" is an invalid number, default to 0`);
|
|
2013
|
+
}
|
|
2014
|
+
const localState = getLocalState(el);
|
|
2015
|
+
if (localState)
|
|
2016
|
+
localState.priority = priority;
|
|
2017
|
+
}
|
|
2018
|
+
else if (name === SPECIAL_PROPERTIES.ATTACH) {
|
|
2019
|
+
// NOTE: handle attach as string
|
|
2020
|
+
const paths = value.split('.');
|
|
2021
|
+
if (paths.length) {
|
|
2022
|
+
const localState = getLocalState(el);
|
|
2023
|
+
if (localState)
|
|
2024
|
+
localState.attach = paths;
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
else if (name === SPECIAL_PROPERTIES.RAW_VALUE) {
|
|
2028
|
+
// NOTE: coercion
|
|
2029
|
+
let maybeCoerced = value;
|
|
2030
|
+
if (maybeCoerced === '' || maybeCoerced === 'true' || maybeCoerced === 'false') {
|
|
2031
|
+
maybeCoerced = maybeCoerced === 'true' || maybeCoerced === '';
|
|
2032
|
+
}
|
|
2033
|
+
else if (!isNaN(Number(maybeCoerced))) {
|
|
2034
|
+
maybeCoerced = Number(maybeCoerced);
|
|
2035
|
+
}
|
|
2036
|
+
rS[4 /* NgtRendererClassId.rawValue */] = maybeCoerced;
|
|
2037
|
+
}
|
|
2038
|
+
applyProps(el, { [name]: value });
|
|
2502
2039
|
return false;
|
|
2503
2040
|
}
|
|
2504
2041
|
return true;
|
|
@@ -2516,28 +2053,36 @@ class NgtRenderer {
|
|
|
2516
2053
|
}
|
|
2517
2054
|
}
|
|
2518
2055
|
setProperty(el, name, value) {
|
|
2519
|
-
// TODO: should we support ref value
|
|
2520
2056
|
const rS = el.__ngt_renderer__;
|
|
2521
|
-
if (rS[
|
|
2522
|
-
// we don't have the compound instance yet
|
|
2523
|
-
rS[10 /* NgtRendererClassId.properties */][name] = value;
|
|
2524
|
-
if (!rS[7 /* NgtRendererClassId.compounded */]) {
|
|
2525
|
-
this.store.queueOperation(el, ['op', () => this.setProperty(el, name, value)]);
|
|
2526
|
-
return;
|
|
2527
|
-
}
|
|
2528
|
-
if (rS[7 /* NgtRendererClassId.compounded */].__ngt_renderer__[5 /* NgtRendererClassId.compound */]) {
|
|
2529
|
-
Object.assign(rS[7 /* NgtRendererClassId.compounded */].__ngt_renderer__[5 /* NgtRendererClassId.compound */][1 /* NgtCompoundClassId.props */], { [name]: value });
|
|
2530
|
-
}
|
|
2531
|
-
this.setProperty(rS[7 /* NgtRendererClassId.compounded */], name, value);
|
|
2057
|
+
if (rS[3 /* NgtRendererClassId.destroyed */])
|
|
2532
2058
|
return;
|
|
2533
|
-
}
|
|
2534
2059
|
if (rS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2535
2060
|
if (name === SPECIAL_PROPERTIES.PARAMETERS) {
|
|
2536
|
-
|
|
2061
|
+
applyProps(el, value);
|
|
2062
|
+
return;
|
|
2537
2063
|
}
|
|
2538
|
-
|
|
2539
|
-
|
|
2064
|
+
const localState = getLocalState(el);
|
|
2065
|
+
const parent = localState?.instanceStore.get('parent') || rS[1 /* NgtRendererClassId.parent */];
|
|
2066
|
+
// [rawValue]
|
|
2067
|
+
if (localState?.isRaw && name === SPECIAL_PROPERTIES.RAW_VALUE) {
|
|
2068
|
+
rS[4 /* NgtRendererClassId.rawValue */] = value;
|
|
2069
|
+
if (parent)
|
|
2070
|
+
attachThreeChild(parent, el);
|
|
2071
|
+
return;
|
|
2540
2072
|
}
|
|
2073
|
+
// [attach]
|
|
2074
|
+
if (name === SPECIAL_PROPERTIES.ATTACH) {
|
|
2075
|
+
if (localState)
|
|
2076
|
+
localState.attach = Array.isArray(value)
|
|
2077
|
+
? value.map((v) => v.toString())
|
|
2078
|
+
: typeof value === 'function'
|
|
2079
|
+
? value
|
|
2080
|
+
: [value];
|
|
2081
|
+
if (parent)
|
|
2082
|
+
attachThreeChild(parent, el);
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
applyProps(el, { [name]: value });
|
|
2541
2086
|
return;
|
|
2542
2087
|
}
|
|
2543
2088
|
return this.delegate.setProperty(el, name, value);
|
|
@@ -2546,25 +2091,17 @@ class NgtRenderer {
|
|
|
2546
2091
|
const rS = target.__ngt_renderer__;
|
|
2547
2092
|
// if the target doesn't have __ngt_renderer__, we delegate
|
|
2548
2093
|
// if target is DOM node, we delegate
|
|
2549
|
-
if (!rS ||
|
|
2094
|
+
if (!rS || isDOM(target)) {
|
|
2550
2095
|
return this.delegate.listen(target, eventName, callback);
|
|
2551
2096
|
}
|
|
2552
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'three'
|
|
2553
|
-
|
|
2554
|
-
const instance = rS[7 /* NgtRendererClassId.compounded */] || target;
|
|
2097
|
+
if (rS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2098
|
+
const instance = target;
|
|
2555
2099
|
const localState = getLocalState(instance);
|
|
2556
2100
|
const priority = localState?.priority ?? 0;
|
|
2557
2101
|
return processThreeEvent(instance, priority, eventName, callback);
|
|
2558
2102
|
}
|
|
2559
|
-
if (rS[0 /* NgtRendererClassId.type */] === 'compound' && !rS[7 /* NgtRendererClassId.compounded */]) {
|
|
2560
|
-
this.store.queueOperation(target, [
|
|
2561
|
-
'op',
|
|
2562
|
-
() => this.store.queueOperation(target, ['cleanUp', this.listen(target, eventName, callback)]),
|
|
2563
|
-
]);
|
|
2564
|
-
return () => { };
|
|
2565
|
-
}
|
|
2566
2103
|
// @ts-expect-error - we know that target is not DOM node
|
|
2567
|
-
if (target === this.
|
|
2104
|
+
if (target === this.rootStore.snapshot.scene) {
|
|
2568
2105
|
let [domTarget, event] = eventName.split(':');
|
|
2569
2106
|
if (event == null) {
|
|
2570
2107
|
event = domTarget;
|
|
@@ -2577,43 +2114,170 @@ class NgtRenderer {
|
|
|
2577
2114
|
}
|
|
2578
2115
|
return () => { };
|
|
2579
2116
|
}
|
|
2117
|
+
destroyInternal(node, parent) {
|
|
2118
|
+
const rS = node.__ngt_renderer__;
|
|
2119
|
+
if (!rS || rS[3 /* NgtRendererClassId.destroyed */])
|
|
2120
|
+
return;
|
|
2121
|
+
if (rS[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2122
|
+
const localState = getLocalState(node);
|
|
2123
|
+
if (localState?.instanceStore) {
|
|
2124
|
+
localState.instanceStore.get('objects').forEach((obj) => this.destroyInternal(obj, parent));
|
|
2125
|
+
localState.instanceStore.get('nonObjects').forEach((obj) => this.destroyInternal(obj, parent));
|
|
2126
|
+
}
|
|
2127
|
+
if (localState?.onUpdate)
|
|
2128
|
+
delete localState.onUpdate;
|
|
2129
|
+
if (localState?.onAttach)
|
|
2130
|
+
delete localState.onAttach;
|
|
2131
|
+
delete localState['objects'];
|
|
2132
|
+
delete localState['nonObjects'];
|
|
2133
|
+
delete localState['parent'];
|
|
2134
|
+
delete localState['add'];
|
|
2135
|
+
delete localState['remove'];
|
|
2136
|
+
delete localState['store'];
|
|
2137
|
+
delete localState['handlers'];
|
|
2138
|
+
if (!localState?.primitive) {
|
|
2139
|
+
delete node['__ngt__'];
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
if (rS[0 /* NgtRendererClassId.type */] === 'comment') {
|
|
2143
|
+
rS[6 /* NgtRendererClassId.injectorFactory */] = null;
|
|
2144
|
+
delete node[SPECIAL_INTERNAL_ADD_COMMENT];
|
|
2145
|
+
this.removeCommentNode(node, this.argsCommentNodes);
|
|
2146
|
+
}
|
|
2147
|
+
if (rS[0 /* NgtRendererClassId.type */] === 'portal') {
|
|
2148
|
+
rS[6 /* NgtRendererClassId.injectorFactory */] = null;
|
|
2149
|
+
this.removeCommentNode(node, this.portalCommentsNodes);
|
|
2150
|
+
}
|
|
2151
|
+
// nullify parent
|
|
2152
|
+
rS[1 /* NgtRendererClassId.parent */] = null;
|
|
2153
|
+
for (const renderChild of rS[2 /* NgtRendererClassId.children */] || []) {
|
|
2154
|
+
if (renderChild.__ngt_renderer__?.[0 /* NgtRendererClassId.type */] === 'three' && parent) {
|
|
2155
|
+
if (parent.__ngt_renderer__?.[0 /* NgtRendererClassId.type */] === 'three') {
|
|
2156
|
+
removeThreeChild(parent, renderChild, true);
|
|
2157
|
+
continue;
|
|
2158
|
+
}
|
|
2159
|
+
const closestInstance = getClosestParentWithInstance(parent);
|
|
2160
|
+
if (closestInstance) {
|
|
2161
|
+
removeThreeChild(closestInstance, renderChild, true);
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
this.destroyInternal(renderChild, parent);
|
|
2165
|
+
}
|
|
2166
|
+
rS[2 /* NgtRendererClassId.children */] = [];
|
|
2167
|
+
rS[3 /* NgtRendererClassId.destroyed */] = true;
|
|
2168
|
+
if (parent) {
|
|
2169
|
+
removeChild(parent, node);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
removeCommentNode(node, nodes) {
|
|
2173
|
+
const index = nodes.findIndex((comment) => comment === node);
|
|
2174
|
+
if (index > -1) {
|
|
2175
|
+
nodes.splice(index, 1);
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
processPortalContainer(portal) {
|
|
2179
|
+
const injector = portal.__ngt_renderer__[6 /* NgtRendererClassId.injectorFactory */]?.();
|
|
2180
|
+
if (!injector)
|
|
2181
|
+
return;
|
|
2182
|
+
const portalStore = injector.get(NGT_STORE, null);
|
|
2183
|
+
if (!portalStore)
|
|
2184
|
+
return;
|
|
2185
|
+
const portalContainer = portalStore.get('scene');
|
|
2186
|
+
if (!portalContainer)
|
|
2187
|
+
return;
|
|
2188
|
+
const localState = getLocalState(portalContainer);
|
|
2189
|
+
if (localState) {
|
|
2190
|
+
localState.store = portalStore;
|
|
2191
|
+
}
|
|
2192
|
+
portal.__ngt_renderer__[5 /* NgtRendererClassId.portalContainer */] = createNode('three', portalContainer, this.document);
|
|
2193
|
+
}
|
|
2580
2194
|
shouldFindGrandparentInstance(pRS, cRS, child) {
|
|
2581
2195
|
const pType = pRS[0 /* NgtRendererClassId.type */];
|
|
2582
2196
|
const cType = cRS[0 /* NgtRendererClassId.type */];
|
|
2583
|
-
const isParentCompounded = pRS[7 /* NgtRendererClassId.compounded */];
|
|
2584
|
-
const isChildCompounded = cRS[7 /* NgtRendererClassId.compounded */];
|
|
2585
2197
|
const cLS = getLocalState(child);
|
|
2586
2198
|
// if child is three but haven't been attached to a parent yet
|
|
2587
2199
|
const isDanglingThreeChild = cType === 'three' && !cLS?.instanceStore?.get('parent');
|
|
2588
2200
|
// or both parent and child are DOM elements
|
|
2589
2201
|
// or they are compound AND haven't had a THREE instance yet
|
|
2590
|
-
const isParentStillDOM = pType === 'dom'
|
|
2591
|
-
const isChildStillDOM = cType === 'dom'
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2202
|
+
const isParentStillDOM = pType === 'dom';
|
|
2203
|
+
const isChildStillDOM = cType === 'dom';
|
|
2204
|
+
return isDanglingThreeChild || (isParentStillDOM && isChildStillDOM) || isParentStillDOM;
|
|
2205
|
+
}
|
|
2206
|
+
getNgtArgs() {
|
|
2207
|
+
let directive;
|
|
2208
|
+
const destroyed = [];
|
|
2209
|
+
let i = this.argsCommentNodes.length - 1;
|
|
2210
|
+
while (i >= 0) {
|
|
2211
|
+
const comment = this.argsCommentNodes[i];
|
|
2212
|
+
if (comment.__ngt_renderer__[3 /* NgtRendererClassId.destroyed */]) {
|
|
2213
|
+
destroyed.push(i);
|
|
2214
|
+
i--;
|
|
2215
|
+
continue;
|
|
2216
|
+
}
|
|
2217
|
+
const injector = comment.__ngt_renderer__[6 /* NgtRendererClassId.injectorFactory */]();
|
|
2218
|
+
if (!injector) {
|
|
2219
|
+
i--;
|
|
2220
|
+
continue;
|
|
2221
|
+
}
|
|
2222
|
+
const instance = injector.get(NgtArgs, null);
|
|
2223
|
+
if (instance && instance.validate()) {
|
|
2224
|
+
directive = instance;
|
|
2225
|
+
break;
|
|
2226
|
+
}
|
|
2227
|
+
i--;
|
|
2228
|
+
}
|
|
2229
|
+
destroyed.forEach((index) => {
|
|
2230
|
+
this.argsCommentNodes.splice(index, 1);
|
|
2231
|
+
});
|
|
2232
|
+
return directive;
|
|
2233
|
+
}
|
|
2234
|
+
tryGetPortalStore() {
|
|
2235
|
+
let store;
|
|
2236
|
+
const destroyed = [];
|
|
2237
|
+
// we only care about the portal states because NgtStore only differs per Portal
|
|
2238
|
+
let i = this.portalCommentsNodes.length - 1;
|
|
2239
|
+
while (i >= 0) {
|
|
2240
|
+
// loop through the portal state backwards to find the closest NgtStore
|
|
2241
|
+
const portal = this.portalCommentsNodes[i];
|
|
2242
|
+
if (portal.__ngt_renderer__[3 /* NgtRendererClassId.destroyed */]) {
|
|
2243
|
+
destroyed.push(i);
|
|
2244
|
+
i--;
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
const injector = portal.__ngt_renderer__[6 /* NgtRendererClassId.injectorFactory */]();
|
|
2248
|
+
if (!injector) {
|
|
2249
|
+
i--;
|
|
2250
|
+
continue;
|
|
2251
|
+
}
|
|
2252
|
+
const instance = injector.get(NGT_STORE, null);
|
|
2253
|
+
// only the instance with previousRoot should pass
|
|
2254
|
+
if (instance && instance.get('previousRoot')) {
|
|
2255
|
+
store = instance;
|
|
2256
|
+
break;
|
|
2257
|
+
}
|
|
2258
|
+
i--;
|
|
2259
|
+
}
|
|
2260
|
+
destroyed.forEach((index) => {
|
|
2261
|
+
this.portalCommentsNodes.splice(index, 1);
|
|
2262
|
+
});
|
|
2263
|
+
return store || this.rootStore;
|
|
2595
2264
|
}
|
|
2596
2265
|
get data() {
|
|
2597
2266
|
return this.delegate.data;
|
|
2598
2267
|
}
|
|
2599
2268
|
}
|
|
2600
|
-
function provideNgtRenderer(store
|
|
2601
|
-
if (!compoundPrefixes.includes('ngts'))
|
|
2602
|
-
compoundPrefixes.push('ngts');
|
|
2603
|
-
if (!compoundPrefixes.includes('ngtp'))
|
|
2604
|
-
compoundPrefixes.push('ngtp');
|
|
2269
|
+
function provideNgtRenderer(store) {
|
|
2605
2270
|
const providers = [
|
|
2606
2271
|
NgtRendererFactory,
|
|
2607
2272
|
{ provide: RendererFactory2, useExisting: NgtRendererFactory },
|
|
2608
|
-
|
|
2609
|
-
provideNgtStore(store),
|
|
2273
|
+
provideStore(() => store),
|
|
2610
2274
|
];
|
|
2611
2275
|
return makeEnvironmentProviders(providers);
|
|
2612
2276
|
}
|
|
2613
2277
|
|
|
2614
2278
|
class NgtCanvas {
|
|
2615
2279
|
constructor() {
|
|
2616
|
-
this.store =
|
|
2280
|
+
this.store = injectStore();
|
|
2617
2281
|
this.initRoot = injectCanvasRootInitializer();
|
|
2618
2282
|
this.autoEffect = injectAutoEffect();
|
|
2619
2283
|
this.host = inject(ElementRef);
|
|
@@ -2622,8 +2286,6 @@ class NgtCanvas {
|
|
|
2622
2286
|
this.environmentInjector = inject(EnvironmentInjector);
|
|
2623
2287
|
this.injector = inject(Injector);
|
|
2624
2288
|
this.sceneGraph = input.required();
|
|
2625
|
-
this.compoundPrefixes = input([]);
|
|
2626
|
-
this.sceneGraphInputs = input({});
|
|
2627
2289
|
this.gl = input();
|
|
2628
2290
|
this.size = input();
|
|
2629
2291
|
this.shadows = input(false, {
|
|
@@ -2658,7 +2320,6 @@ class NgtCanvas {
|
|
|
2658
2320
|
this.zone.runOutsideAngular(() => {
|
|
2659
2321
|
this.configurator = this.initRoot(this.glCanvas().nativeElement);
|
|
2660
2322
|
this.noZoneResizeEffect();
|
|
2661
|
-
this.noZoneSceneGraphInputsEffect();
|
|
2662
2323
|
});
|
|
2663
2324
|
});
|
|
2664
2325
|
inject(DestroyRef).onDestroy(() => {
|
|
@@ -2734,38 +2395,29 @@ class NgtCanvas {
|
|
|
2734
2395
|
this.store.get('events').connect?.(untracked(this.glCanvas).nativeElement);
|
|
2735
2396
|
}
|
|
2736
2397
|
untracked(() => {
|
|
2737
|
-
this.glEnvironmentInjector = createEnvironmentInjector([provideNgtRenderer(this.store
|
|
2398
|
+
this.glEnvironmentInjector = createEnvironmentInjector([provideNgtRenderer(this.store)], this.environmentInjector);
|
|
2738
2399
|
this.glRef = this.viewContainerRef.createComponent(untracked(this.sceneGraph), {
|
|
2739
2400
|
environmentInjector: this.glEnvironmentInjector,
|
|
2740
2401
|
injector: this.injector,
|
|
2741
2402
|
});
|
|
2742
2403
|
this.glRef.changeDetectorRef.detectChanges();
|
|
2743
|
-
this.setSceneGraphInputs(this.sceneGraphInputs());
|
|
2744
2404
|
});
|
|
2745
2405
|
}
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
this.glRef.setInput(key, value);
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
}
|
|
2758
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2759
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.0.3", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: { classPropertyName: "sceneGraph", publicName: "sceneGraph", isSignal: true, isRequired: true, transformFunction: null }, compoundPrefixes: { classPropertyName: "compoundPrefixes", publicName: "compoundPrefixes", isSignal: true, isRequired: false, transformFunction: null }, sceneGraphInputs: { classPropertyName: "sceneGraphInputs", publicName: "sceneGraphInputs", isSignal: true, isRequired: false, transformFunction: null }, gl: { classPropertyName: "gl", publicName: "gl", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shadows: { classPropertyName: "shadows", publicName: "shadows", isSignal: true, isRequired: false, transformFunction: null }, legacy: { classPropertyName: "legacy", publicName: "legacy", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, orthographic: { classPropertyName: "orthographic", publicName: "orthographic", isSignal: true, isRequired: false, transformFunction: null }, frameloop: { classPropertyName: "frameloop", publicName: "frameloop", isSignal: true, isRequired: false, transformFunction: null }, performance: { classPropertyName: "performance", publicName: "performance", isSignal: true, isRequired: false, transformFunction: null }, dpr: { classPropertyName: "dpr", publicName: "dpr", isSignal: true, isRequired: false, transformFunction: null }, raycaster: { classPropertyName: "raycaster", publicName: "raycaster", isSignal: true, isRequired: false, transformFunction: null }, scene: { classPropertyName: "scene", publicName: "scene", isSignal: true, isRequired: false, transformFunction: null }, camera: { classPropertyName: "camera", publicName: "camera", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, eventSource: { classPropertyName: "eventSource", publicName: "eventSource", isSignal: true, isRequired: false, transformFunction: null }, eventPrefix: { classPropertyName: "eventPrefix", publicName: "eventPrefix", isSignal: true, isRequired: false, transformFunction: null }, lookAt: { classPropertyName: "lookAt", publicName: "lookAt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { created: "created", pointerMissed: "pointerMissed" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
|
|
2760
|
-
provideResizeOptions({ emitInZone: false, emitInitialResult: true, debounce: 250 }),
|
|
2761
|
-
provideNgtStore(),
|
|
2406
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2407
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.0.6", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: { classPropertyName: "sceneGraph", publicName: "sceneGraph", isSignal: true, isRequired: true, transformFunction: null }, gl: { classPropertyName: "gl", publicName: "gl", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shadows: { classPropertyName: "shadows", publicName: "shadows", isSignal: true, isRequired: false, transformFunction: null }, legacy: { classPropertyName: "legacy", publicName: "legacy", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, orthographic: { classPropertyName: "orthographic", publicName: "orthographic", isSignal: true, isRequired: false, transformFunction: null }, frameloop: { classPropertyName: "frameloop", publicName: "frameloop", isSignal: true, isRequired: false, transformFunction: null }, performance: { classPropertyName: "performance", publicName: "performance", isSignal: true, isRequired: false, transformFunction: null }, dpr: { classPropertyName: "dpr", publicName: "dpr", isSignal: true, isRequired: false, transformFunction: null }, raycaster: { classPropertyName: "raycaster", publicName: "raycaster", isSignal: true, isRequired: false, transformFunction: null }, scene: { classPropertyName: "scene", publicName: "scene", isSignal: true, isRequired: false, transformFunction: null }, camera: { classPropertyName: "camera", publicName: "camera", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, eventSource: { classPropertyName: "eventSource", publicName: "eventSource", isSignal: true, isRequired: false, transformFunction: null }, eventPrefix: { classPropertyName: "eventPrefix", publicName: "eventPrefix", isSignal: true, isRequired: false, transformFunction: null }, lookAt: { classPropertyName: "lookAt", publicName: "lookAt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { created: "created", pointerMissed: "pointerMissed" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
|
|
2408
|
+
provideResizeOptions({
|
|
2409
|
+
emitInZone: false,
|
|
2410
|
+
emitInitialResult: true,
|
|
2411
|
+
debounce: { scroll: 50, resize: 0 },
|
|
2412
|
+
}),
|
|
2413
|
+
provideStore(),
|
|
2762
2414
|
], viewQueries: [{ propertyName: "glCanvas", first: true, predicate: ["glCanvas"], descendants: true, isSignal: true }, { propertyName: "glCanvasViewContainerRef", first: true, predicate: ["glCanvas"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
|
|
2763
2415
|
<div (ngxResize)="resizeResult.set($event)" style="height: 100%; width: 100%;">
|
|
2764
2416
|
<canvas #glCanvas style="display: block;"></canvas>
|
|
2765
2417
|
</div>
|
|
2766
2418
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgxResize, selector: "[ngxResize]", inputs: ["ngxResizeOptions"], outputs: ["ngxResize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2767
2419
|
}
|
|
2768
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
2420
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtCanvas, decorators: [{
|
|
2769
2421
|
type: Component,
|
|
2770
2422
|
args: [{
|
|
2771
2423
|
selector: 'ngt-canvas',
|
|
@@ -2777,8 +2429,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImpor
|
|
|
2777
2429
|
`,
|
|
2778
2430
|
imports: [NgxResize],
|
|
2779
2431
|
providers: [
|
|
2780
|
-
provideResizeOptions({
|
|
2781
|
-
|
|
2432
|
+
provideResizeOptions({
|
|
2433
|
+
emitInZone: false,
|
|
2434
|
+
emitInitialResult: true,
|
|
2435
|
+
debounce: { scroll: 50, resize: 0 },
|
|
2436
|
+
}),
|
|
2437
|
+
provideStore(),
|
|
2782
2438
|
],
|
|
2783
2439
|
host: {
|
|
2784
2440
|
style: 'display: block;position: relative;width: 100%;height: 100%;overflow: hidden;',
|
|
@@ -2870,12 +2526,13 @@ const injectLoader = _injectLoader;
|
|
|
2870
2526
|
|
|
2871
2527
|
function injectBeforeRender(cb, { priority = 0, injector } = {}) {
|
|
2872
2528
|
return assertInjector(injectBeforeRender, injector, () => {
|
|
2873
|
-
const store =
|
|
2529
|
+
const store = injectStore();
|
|
2874
2530
|
const sub = store.get('internal').subscribe(cb, priority, store);
|
|
2875
2531
|
inject(DestroyRef).onDestroy(() => void sub());
|
|
2876
2532
|
return sub;
|
|
2877
2533
|
});
|
|
2878
2534
|
}
|
|
2535
|
+
// TODO (chau): clean this up
|
|
2879
2536
|
function injectNextBeforeRender(cb, { priority = 0, injector } = {}) {
|
|
2880
2537
|
return assertInjector(injectNextBeforeRender, injector, () => {
|
|
2881
2538
|
const assertedInjector = inject(Injector);
|
|
@@ -2887,30 +2544,19 @@ function injectNextBeforeRender(cb, { priority = 0, injector } = {}) {
|
|
|
2887
2544
|
});
|
|
2888
2545
|
}
|
|
2889
2546
|
|
|
2890
|
-
const privateKeys = [
|
|
2891
|
-
'get',
|
|
2892
|
-
'set',
|
|
2893
|
-
'select',
|
|
2894
|
-
'setSize',
|
|
2895
|
-
'setDpr',
|
|
2896
|
-
'setFrameloop',
|
|
2897
|
-
'events',
|
|
2898
|
-
'invalidate',
|
|
2899
|
-
'advance',
|
|
2900
|
-
'size',
|
|
2901
|
-
'viewport',
|
|
2902
|
-
];
|
|
2903
2547
|
class NgtPortalBeforeRender {
|
|
2904
2548
|
constructor() {
|
|
2905
|
-
this.portalStore =
|
|
2906
|
-
this.injector = inject(Injector);
|
|
2549
|
+
this.portalStore = injectStore();
|
|
2907
2550
|
this.renderPriority = input(1);
|
|
2908
2551
|
this.parentScene = input.required();
|
|
2909
2552
|
this.parentCamera = input.required();
|
|
2910
|
-
|
|
2553
|
+
injectAutoEffect()((injector) => {
|
|
2554
|
+
// track state
|
|
2555
|
+
this.portalStore.state();
|
|
2556
|
+
const priority = this.renderPriority();
|
|
2911
2557
|
let oldClear;
|
|
2912
|
-
injectBeforeRender(() => {
|
|
2913
|
-
const { gl, scene, camera } = this.portalStore.
|
|
2558
|
+
return injectBeforeRender(() => {
|
|
2559
|
+
const { gl, scene, camera } = this.portalStore.snapshot;
|
|
2914
2560
|
oldClear = gl.autoClear;
|
|
2915
2561
|
if (this.renderPriority() === 1) {
|
|
2916
2562
|
// clear scene and render with default
|
|
@@ -2923,19 +2569,19 @@ class NgtPortalBeforeRender {
|
|
|
2923
2569
|
gl.render(scene, camera);
|
|
2924
2570
|
// restore
|
|
2925
2571
|
gl.autoClear = oldClear;
|
|
2926
|
-
}, { priority
|
|
2572
|
+
}, { priority, injector });
|
|
2927
2573
|
});
|
|
2928
2574
|
}
|
|
2929
2575
|
onPointerOver() {
|
|
2930
2576
|
/* noop */
|
|
2931
2577
|
}
|
|
2932
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.
|
|
2933
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.
|
|
2578
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2579
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.6", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: { classPropertyName: "renderPriority", publicName: "renderPriority", isSignal: true, isRequired: false, transformFunction: null }, parentScene: { classPropertyName: "parentScene", publicName: "parentScene", isSignal: true, isRequired: true, transformFunction: null }, parentCamera: { classPropertyName: "parentCamera", publicName: "parentCamera", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
2934
2580
|
<!-- Without an element that receives pointer events state.pointer will always be 0/0 -->
|
|
2935
2581
|
<ngt-group (pointerover)="onPointerOver()" attach="none" />
|
|
2936
2582
|
`, isInline: true }); }
|
|
2937
2583
|
}
|
|
2938
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
2584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
|
|
2939
2585
|
type: Component,
|
|
2940
2586
|
args: [{
|
|
2941
2587
|
selector: 'ngt-portal-before-render',
|
|
@@ -2948,194 +2594,167 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImpor
|
|
|
2948
2594
|
}]
|
|
2949
2595
|
}], ctorParameters: () => [] });
|
|
2950
2596
|
class NgtPortalContent {
|
|
2951
|
-
constructor(
|
|
2952
|
-
const
|
|
2597
|
+
constructor() {
|
|
2598
|
+
const { element: comment } = inject(ViewContainerRef);
|
|
2599
|
+
const { element: parentComment } = inject(ViewContainerRef, { skipSelf: true });
|
|
2600
|
+
const commentNode = comment.nativeElement;
|
|
2953
2601
|
if (commentNode[SPECIAL_INTERNAL_ADD_COMMENT]) {
|
|
2954
|
-
commentNode[SPECIAL_INTERNAL_ADD_COMMENT](
|
|
2602
|
+
commentNode[SPECIAL_INTERNAL_ADD_COMMENT](parentComment.nativeElement);
|
|
2955
2603
|
delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
|
|
2956
2604
|
}
|
|
2957
2605
|
}
|
|
2958
|
-
static
|
|
2959
|
-
|
|
2606
|
+
static ngTemplateContextGuard(_, ctx) {
|
|
2607
|
+
return true;
|
|
2608
|
+
}
|
|
2609
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortalContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2610
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.6", type: NgtPortalContent, isStandalone: true, selector: "ng-template[portalContent]", ngImport: i0 }); }
|
|
2960
2611
|
}
|
|
2961
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
2612
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortalContent, decorators: [{
|
|
2962
2613
|
type: Directive,
|
|
2963
2614
|
args: [{ selector: 'ng-template[portalContent]', standalone: true }]
|
|
2964
|
-
}], ctorParameters: () => [
|
|
2965
|
-
|
|
2966
|
-
|
|
2615
|
+
}], ctorParameters: () => [] });
|
|
2616
|
+
// Keys that shouldn't be copied between stores
|
|
2617
|
+
const privateKeys = [
|
|
2618
|
+
'setSize',
|
|
2619
|
+
'setFrameloop',
|
|
2620
|
+
'setDpr',
|
|
2621
|
+
'events',
|
|
2622
|
+
'setEvents',
|
|
2623
|
+
'invalidate',
|
|
2624
|
+
'advance',
|
|
2625
|
+
'size',
|
|
2626
|
+
'viewport',
|
|
2627
|
+
];
|
|
2967
2628
|
class NgtPortal {
|
|
2968
2629
|
constructor() {
|
|
2969
|
-
this.container = input(
|
|
2970
|
-
this.
|
|
2971
|
-
|
|
2630
|
+
this.container = input.required();
|
|
2631
|
+
this.state = input({});
|
|
2632
|
+
/**
|
|
2633
|
+
* @decsription turn this on to enable "HUD" like rendering
|
|
2634
|
+
*/
|
|
2972
2635
|
this.autoRender = input(false);
|
|
2973
2636
|
this.autoRenderPriority = input(1);
|
|
2974
|
-
this.
|
|
2975
|
-
this.
|
|
2976
|
-
this.
|
|
2977
|
-
this.
|
|
2978
|
-
this.parentStore =
|
|
2979
|
-
this.
|
|
2980
|
-
this.
|
|
2981
|
-
this.renderAutoBeforeRender = computed(() => this.portalRendered() && this.autoRender());
|
|
2982
|
-
this.parentScene = this.parentStore.get('scene');
|
|
2983
|
-
this.parentCamera = this.parentStore.get('camera');
|
|
2637
|
+
this.portalContent = contentChild.required(NgtPortalContent, { read: TemplateRef });
|
|
2638
|
+
this.portalAnchor = viewChild.required('anchor', { read: ViewContainerRef });
|
|
2639
|
+
this.injector = inject(Injector);
|
|
2640
|
+
this.portalStore = injectStore({ self: true });
|
|
2641
|
+
this.parentStore = injectStore({ skipSelf: true });
|
|
2642
|
+
this.parentScene = this.parentStore.select('scene');
|
|
2643
|
+
this.parentCamera = this.parentStore.select('camera');
|
|
2984
2644
|
this.raycaster = new Raycaster();
|
|
2985
2645
|
this.pointer = new Vector2();
|
|
2646
|
+
this.portalRendered = signal(false);
|
|
2647
|
+
this.renderAutoBeforeRender = computed(() => this.portalRendered() && this.autoRender());
|
|
2648
|
+
const autoEffect = injectAutoEffect();
|
|
2649
|
+
const parentState = this.parentStore.select();
|
|
2986
2650
|
afterNextRender(() => {
|
|
2987
|
-
const
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
this.state(),
|
|
2991
|
-
this.autoRender(),
|
|
2992
|
-
this.autoRenderPriority(),
|
|
2993
|
-
];
|
|
2994
|
-
let stateFromInput = state;
|
|
2995
|
-
if (!stateFromInput && autoRender) {
|
|
2996
|
-
stateFromInput = { events: { priority: autoRenderPriority + 1 } };
|
|
2997
|
-
}
|
|
2998
|
-
const { events = {}, size = {}, ...rest } = stateFromInput || {};
|
|
2651
|
+
const previousState = this.parentStore.snapshot;
|
|
2652
|
+
const { events = {}, size = {}, ...rest } = this.state();
|
|
2653
|
+
let container = this.container();
|
|
2999
2654
|
if (!is.instance(container)) {
|
|
3000
|
-
container = prepare(container);
|
|
2655
|
+
container = prepare(container, { store: this.portalStore });
|
|
3001
2656
|
}
|
|
3002
2657
|
const localState = getLocalState(container);
|
|
3003
2658
|
if (localState && !localState.store) {
|
|
3004
2659
|
localState.store = this.portalStore;
|
|
3005
2660
|
}
|
|
3006
2661
|
this.portalStore.update({
|
|
3007
|
-
...
|
|
2662
|
+
...previousState,
|
|
3008
2663
|
scene: container,
|
|
3009
2664
|
raycaster: this.raycaster,
|
|
3010
2665
|
pointer: this.pointer,
|
|
2666
|
+
events: { ...previousState.events, ...events },
|
|
2667
|
+
size: { ...previousState.size, ...size },
|
|
3011
2668
|
previousRoot: this.parentStore,
|
|
3012
|
-
events: { ...parentState.events, ...events },
|
|
3013
|
-
size: { ...parentState.size, ...size },
|
|
3014
2669
|
...rest,
|
|
3015
2670
|
setEvents: (events) => this.portalStore.update((state) => ({ ...state, events: { ...state.events, ...events } })),
|
|
3016
2671
|
});
|
|
3017
|
-
|
|
3018
|
-
const
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
2672
|
+
autoEffect(() => {
|
|
2673
|
+
const state = this.state();
|
|
2674
|
+
const _parentState = parentState();
|
|
2675
|
+
this.portalStore.update((prev) => this.inject(_parentState, prev, state, untracked(this.container)));
|
|
2676
|
+
untracked(() => {
|
|
2677
|
+
if (this.portalView) {
|
|
2678
|
+
this.portalView.detectChanges();
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
this.portalView = this.portalAnchor().createEmbeddedView(this.portalContent(), { container: this.container(), injector: this.injector }, { injector: this.injector });
|
|
2682
|
+
this.portalView.detectChanges();
|
|
2683
|
+
this.portalRendered.set(true);
|
|
3026
2684
|
});
|
|
3027
2685
|
});
|
|
3028
|
-
|
|
2686
|
+
});
|
|
2687
|
+
inject(DestroyRef).onDestroy(() => {
|
|
2688
|
+
this.portalView?.destroy();
|
|
3029
2689
|
});
|
|
3030
2690
|
}
|
|
3031
|
-
inject(
|
|
3032
|
-
const
|
|
3033
|
-
|
|
2691
|
+
inject(parentState, portalState, injectedState, container) {
|
|
2692
|
+
const { events = {}, size, ...rest } = injectedState;
|
|
2693
|
+
const intersect = { ...parentState }; // all prev state props
|
|
2694
|
+
Object.keys(parentState).forEach((key) => {
|
|
3034
2695
|
if (privateKeys.includes(key) ||
|
|
3035
|
-
|
|
2696
|
+
(parentState[key] !== portalState[key] &&
|
|
2697
|
+
portalState[key])) {
|
|
3036
2698
|
delete intersect[key];
|
|
3037
2699
|
}
|
|
3038
2700
|
});
|
|
3039
|
-
const container = untracked(this.container);
|
|
3040
|
-
const { size, events, ...restInputsState } = untracked(this.state) || {};
|
|
3041
2701
|
let viewport = undefined;
|
|
3042
|
-
if (
|
|
3043
|
-
const camera =
|
|
3044
|
-
|
|
3045
|
-
|
|
2702
|
+
if (portalState && size) {
|
|
2703
|
+
const camera = portalState.camera;
|
|
2704
|
+
// Calculate the override viewport, if present
|
|
2705
|
+
viewport = parentState.viewport.getCurrentViewport(camera, new Vector3(), size);
|
|
2706
|
+
// Update the portal camera, if it differs from the previous layer
|
|
2707
|
+
if (camera !== parentState.camera) {
|
|
3046
2708
|
updateCamera(camera, size);
|
|
2709
|
+
}
|
|
3047
2710
|
}
|
|
3048
2711
|
return {
|
|
3049
2712
|
...intersect,
|
|
3050
2713
|
scene: container,
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
...
|
|
2714
|
+
raycaster: this.raycaster,
|
|
2715
|
+
pointer: this.pointer,
|
|
2716
|
+
events: { ...parentState.events, ...(portalState.events || {}), ...(events || {}) },
|
|
2717
|
+
size: { ...parentState.size, ...(size || {}) },
|
|
2718
|
+
viewport: { ...parentState.viewport, ...(viewport || {}) },
|
|
2719
|
+
...rest,
|
|
3056
2720
|
};
|
|
3057
2721
|
}
|
|
3058
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.
|
|
3059
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.
|
|
3060
|
-
<ng-container #
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
2722
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2723
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, autoRender: { classPropertyName: "autoRender", publicName: "autoRender", isSignal: true, isRequired: false, transformFunction: null }, autoRenderPriority: { classPropertyName: "autoRenderPriority", publicName: "autoRenderPriority", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideStore(() => signalStore({}))], queries: [{ propertyName: "portalContent", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "portalAnchor", first: true, predicate: ["anchor"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
|
|
2724
|
+
<ng-container #anchor />
|
|
2725
|
+
|
|
2726
|
+
@if (renderAutoBeforeRender()) {
|
|
2727
|
+
<ngt-portal-before-render
|
|
2728
|
+
[renderPriority]="autoRenderPriority()"
|
|
2729
|
+
[parentScene]="parentScene()"
|
|
2730
|
+
[parentCamera]="parentCamera()"
|
|
2731
|
+
/>
|
|
2732
|
+
}
|
|
3069
2733
|
`, isInline: true, dependencies: [{ kind: "component", type: NgtPortalBeforeRender, selector: "ngt-portal-before-render", inputs: ["renderPriority", "parentScene", "parentCamera"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3070
2734
|
}
|
|
3071
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
2735
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtPortal, decorators: [{
|
|
3072
2736
|
type: Component,
|
|
3073
2737
|
args: [{
|
|
3074
2738
|
selector: 'ngt-portal',
|
|
3075
2739
|
standalone: true,
|
|
3076
2740
|
template: `
|
|
3077
|
-
<ng-container #
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
2741
|
+
<ng-container #anchor />
|
|
2742
|
+
|
|
2743
|
+
@if (renderAutoBeforeRender()) {
|
|
2744
|
+
<ngt-portal-before-render
|
|
2745
|
+
[renderPriority]="autoRenderPriority()"
|
|
2746
|
+
[parentScene]="parentScene()"
|
|
2747
|
+
[parentCamera]="parentCamera()"
|
|
2748
|
+
/>
|
|
2749
|
+
}
|
|
3086
2750
|
`,
|
|
3087
2751
|
imports: [NgtPortalBeforeRender],
|
|
3088
|
-
|
|
2752
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
3089
2753
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2754
|
+
providers: [provideStore(() => signalStore({}))],
|
|
3090
2755
|
}]
|
|
3091
2756
|
}], ctorParameters: () => [] });
|
|
3092
2757
|
|
|
3093
|
-
function injectNgtRef(initial = null, injector) {
|
|
3094
|
-
if (initial && Reflect.get(initial, '__ngtType')) {
|
|
3095
|
-
return initial;
|
|
3096
|
-
}
|
|
3097
|
-
return assertInjector(injectNgtRef, injector, () => {
|
|
3098
|
-
const ref = is.ref(initial) ? initial : new ElementRef(initial);
|
|
3099
|
-
const refSignal = signal(ref.nativeElement, { equal: Object.is });
|
|
3100
|
-
const readonlyRef = refSignal.asReadonly();
|
|
3101
|
-
const computedCached = new Map();
|
|
3102
|
-
inject(DestroyRef).onDestroy(() => void computedCached.clear());
|
|
3103
|
-
const children = (type = 'objects') => {
|
|
3104
|
-
if (!computedCached.has(type)) {
|
|
3105
|
-
computedCached.set(type, computed(() => {
|
|
3106
|
-
const instance = readonlyRef();
|
|
3107
|
-
if (!instance)
|
|
3108
|
-
return [];
|
|
3109
|
-
const localState = getLocalState(instance);
|
|
3110
|
-
if (!localState?.instanceStore)
|
|
3111
|
-
return [];
|
|
3112
|
-
if (type === 'objects')
|
|
3113
|
-
return localState.objects();
|
|
3114
|
-
if (type === 'nonObjects')
|
|
3115
|
-
return localState.nonObjects();
|
|
3116
|
-
return [...localState.objects(), ...localState.nonObjects()];
|
|
3117
|
-
}));
|
|
3118
|
-
}
|
|
3119
|
-
return computedCached.get(type);
|
|
3120
|
-
};
|
|
3121
|
-
Object.defineProperties(ref, {
|
|
3122
|
-
nativeElement: {
|
|
3123
|
-
set: (newElement) => {
|
|
3124
|
-
untracked(() => {
|
|
3125
|
-
if (newElement !== readonlyRef()) {
|
|
3126
|
-
refSignal.set(newElement);
|
|
3127
|
-
}
|
|
3128
|
-
});
|
|
3129
|
-
},
|
|
3130
|
-
get: readonlyRef,
|
|
3131
|
-
},
|
|
3132
|
-
children: { value: children },
|
|
3133
|
-
__ngtType: { value: 'ngtRef' },
|
|
3134
|
-
});
|
|
3135
|
-
return ref;
|
|
3136
|
-
});
|
|
3137
|
-
}
|
|
3138
|
-
|
|
3139
2758
|
var _a;
|
|
3140
2759
|
class NgtRoutedScene {
|
|
3141
2760
|
static { _a = ROUTED_SCENE; }
|
|
@@ -3145,12 +2764,12 @@ class NgtRoutedScene {
|
|
|
3145
2764
|
.pipe(filter((event) => event instanceof ActivationEnd), takeUntilDestroyed())
|
|
3146
2765
|
.subscribe(cdr.detectChanges.bind(cdr));
|
|
3147
2766
|
}
|
|
3148
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.
|
|
3149
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.
|
|
2767
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2768
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.6", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
|
|
3150
2769
|
<router-outlet />
|
|
3151
2770
|
`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
|
|
3152
2771
|
}
|
|
3153
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
2772
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: NgtRoutedScene, decorators: [{
|
|
3154
2773
|
type: Component,
|
|
3155
2774
|
args: [{
|
|
3156
2775
|
standalone: true,
|
|
@@ -3173,63 +2792,75 @@ function createApiToken(forwardedObject) {
|
|
|
3173
2792
|
return [injectFn, () => provideFn()];
|
|
3174
2793
|
}
|
|
3175
2794
|
|
|
3176
|
-
function
|
|
2795
|
+
function omit(objFn, keysToOmit) {
|
|
3177
2796
|
return computed(() => {
|
|
3178
|
-
const
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
if (
|
|
3182
|
-
|
|
3183
|
-
}
|
|
3184
|
-
|
|
3185
|
-
|
|
2797
|
+
const obj = objFn();
|
|
2798
|
+
const result = {};
|
|
2799
|
+
for (const key of Object.keys(obj)) {
|
|
2800
|
+
if (keysToOmit.includes(key))
|
|
2801
|
+
continue;
|
|
2802
|
+
Object.assign(result, { [key]: obj[key] });
|
|
2803
|
+
}
|
|
2804
|
+
return result;
|
|
3186
2805
|
});
|
|
3187
2806
|
}
|
|
3188
|
-
function pick(
|
|
3189
|
-
if (Array.isArray(
|
|
2807
|
+
function pick(objFn, keyOrKeys) {
|
|
2808
|
+
if (Array.isArray(keyOrKeys)) {
|
|
3190
2809
|
return computed(() => {
|
|
3191
|
-
const
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
2810
|
+
const obj = objFn();
|
|
2811
|
+
const result = {};
|
|
2812
|
+
for (const key of keyOrKeys) {
|
|
2813
|
+
if (!(key in obj))
|
|
2814
|
+
continue;
|
|
2815
|
+
Object.assign(result, { [key]: obj[key] });
|
|
2816
|
+
}
|
|
2817
|
+
return result;
|
|
3197
2818
|
});
|
|
3198
2819
|
}
|
|
3199
|
-
return computed(() =>
|
|
2820
|
+
return computed(() => objFn()[keyOrKeys]);
|
|
3200
2821
|
}
|
|
3201
|
-
function merge(
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
});
|
|
2822
|
+
function merge(objFn, toMerge, mode = 'override') {
|
|
2823
|
+
if (mode === 'override')
|
|
2824
|
+
return computed(() => ({ ...objFn(), ...toMerge }));
|
|
2825
|
+
return computed(() => ({ ...toMerge, ...objFn() }));
|
|
3206
2826
|
}
|
|
3207
|
-
function vector2(options, key) {
|
|
2827
|
+
function vector2(options, key, keepUndefined = false) {
|
|
3208
2828
|
return computed(() => {
|
|
3209
2829
|
const value = options()[key];
|
|
2830
|
+
if (keepUndefined && value == undefined)
|
|
2831
|
+
return undefined;
|
|
3210
2832
|
if (typeof value === 'number')
|
|
3211
2833
|
return new Vector2(value, value);
|
|
3212
2834
|
else if (value)
|
|
3213
2835
|
return new Vector2(...value);
|
|
3214
2836
|
else
|
|
3215
2837
|
return new Vector2();
|
|
3216
|
-
});
|
|
2838
|
+
}, { equal: (a, b) => !!a && !!b && a.equals(b) });
|
|
3217
2839
|
}
|
|
3218
|
-
function vector3(options, key) {
|
|
2840
|
+
function vector3(options, key, keepUndefined = false) {
|
|
3219
2841
|
return computed(() => {
|
|
3220
2842
|
const value = options()[key];
|
|
2843
|
+
if (keepUndefined && value == undefined)
|
|
2844
|
+
return undefined;
|
|
3221
2845
|
if (typeof value === 'number')
|
|
3222
2846
|
return new Vector3(value, value, value);
|
|
3223
2847
|
else if (value)
|
|
3224
2848
|
return new Vector3(...value);
|
|
3225
2849
|
else
|
|
3226
2850
|
return new Vector3();
|
|
3227
|
-
});
|
|
2851
|
+
}, { equal: (a, b) => !!a && !!b && a.equals(b) });
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
function resolveRef(ref) {
|
|
2855
|
+
if (is.ref(ref)) {
|
|
2856
|
+
return ref.nativeElement;
|
|
2857
|
+
}
|
|
2858
|
+
return ref;
|
|
3228
2859
|
}
|
|
3229
2860
|
|
|
3230
2861
|
/**
|
|
3231
2862
|
* Generated bundle index. Do not edit.
|
|
3232
2863
|
*/
|
|
3233
2864
|
|
|
3234
|
-
export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtPortal, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, checkNeedsUpdate, checkUpdate, createApiToken, createAttachFunction,
|
|
2865
|
+
export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtPortal, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, checkNeedsUpdate, checkUpdate, createApiToken, createAttachFunction, extend, getLocalState, injectBeforeRender, injectLoader, injectNextBeforeRender, injectStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, merge, omit, pick, prepare, provideNgtRenderer, provideStore, resolveRef, signalStore, updateCamera, vector2, vector3 };
|
|
3235
2866
|
//# sourceMappingURL=angular-three.mjs.map
|