@mirage-engine/core 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/mirage-engine.js +1443 -503
- package/dist/mirage-engine.umd.js +142 -72
- package/dist/src/animation/Animator.d.ts +6 -0
- package/dist/src/core/Engine.d.ts +5 -0
- package/dist/src/core/Syncer.d.ts +5 -16
- package/dist/src/dom/Extractor.d.ts +1 -2
- package/dist/src/renderer/Renderer.d.ts +14 -8
- package/dist/src/store/MeshRegistry.d.ts +9 -0
- package/dist/src/store/TextureLifecycleManager.d.ts +16 -0
- package/dist/src/types/animate.d.ts +19 -0
- package/dist/src/types/attributes.d.ts +63 -0
- package/dist/src/types/common.d.ts +9 -0
- package/dist/src/types/config.d.ts +2 -8
- package/dist/src/types/flags.d.ts +8 -7
- package/dist/src/types/index.d.ts +2 -0
- package/package.json +3 -2
- package/src/animation/Animator.ts +108 -0
- package/src/core/Engine.ts +69 -5
- package/src/core/Syncer.ts +49 -190
- package/src/dom/Extractor.ts +498 -64
- package/src/env.d.ts +4 -0
- package/src/renderer/Renderer.ts +430 -133
- package/src/store/MeshRegistry.ts +32 -0
- package/src/store/TextureLifecycleManager.ts +126 -0
- package/src/types/animate.ts +26 -0
- package/src/types/attributes.ts +57 -0
- package/src/types/common.ts +6 -0
- package/src/types/config.ts +5 -10
- package/src/types/flags.ts +20 -15
- package/src/types/index.ts +3 -1
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
export type Quality = "low" | "medium" | "high" | number;
|
|
2
|
+
export type LayerTarget = "base" | "selected";
|
|
2
3
|
export type MirageMode = "overlay" | "duplicate";
|
|
3
4
|
export type PxUnit = `${number}px`;
|
|
4
5
|
export type PercentUnit = `${number}%`;
|
|
5
6
|
export type travelerClipArea = PxUnit | PercentUnit | number;
|
|
6
|
-
export interface FilterConfig {
|
|
7
|
-
includeTree?: string[];
|
|
8
|
-
excludeTree?: string[];
|
|
9
|
-
includeSelf?: string[];
|
|
10
|
-
excludeSelf?: string[];
|
|
11
|
-
end?: string[];
|
|
12
|
-
}
|
|
13
7
|
export interface ResizeConfig {
|
|
14
8
|
delay?: number;
|
|
15
9
|
onStart?: () => void;
|
|
@@ -17,11 +11,11 @@ export interface ResizeConfig {
|
|
|
17
11
|
}
|
|
18
12
|
interface BaseConfig {
|
|
19
13
|
debug?: boolean;
|
|
14
|
+
layer?: number | LayerTarget;
|
|
20
15
|
quality?: Quality;
|
|
21
16
|
style?: {
|
|
22
17
|
zIndex?: string;
|
|
23
18
|
};
|
|
24
|
-
filter?: FilterConfig;
|
|
25
19
|
resizeDebounce?: boolean | ResizeConfig;
|
|
26
20
|
travelerClipArea?: travelerClipArea;
|
|
27
21
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare const DIRTY_RECT: number;
|
|
3
|
-
export declare const DIRTY_STYLE: number;
|
|
4
|
-
export declare const DIRTY_ZINDEX: number;
|
|
5
|
-
export declare const DIRTY_STRUCTURE: number;
|
|
6
|
-
export declare const DIRTY_CONTENT: number;
|
|
1
|
+
export { DIRTY_NONE, DIRTY_RECT, DIRTY_STYLE, DIRTY_ZINDEX, DIRTY_STRUCTURE, DIRTY_CONTENT, } from '@mirage-engine/dom-tracker';
|
|
7
2
|
export declare const USER_LAYER: number;
|
|
8
|
-
export declare const
|
|
3
|
+
export declare const SELECT_LAYER: number;
|
|
9
4
|
export declare const EXCLUDED = 0;
|
|
5
|
+
export declare const THREE_LAYERS: {
|
|
6
|
+
readonly BASE: 0;
|
|
7
|
+
readonly SELECTED: 1;
|
|
8
|
+
readonly getCaptureLayer: (layerNum: number) => number;
|
|
9
|
+
readonly HIDDEN: 31;
|
|
10
|
+
};
|
|
10
11
|
export type Visibility = 0 | 1 | 2 | 3;
|
|
11
12
|
export declare const ALLOWED_FILTERS: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirage-engine/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"types": "src/index.ts",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@types/three": "^0.181.0",
|
|
16
|
-
"@mirage-engine/painter": "0.
|
|
16
|
+
"@mirage-engine/painter": "1.0.1",
|
|
17
|
+
"@mirage-engine/dom-tracker": "0.3.0"
|
|
17
18
|
},
|
|
18
19
|
"private": false,
|
|
19
20
|
"publishConfig": {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { StyleData } from "@mirage-engine/dom-tracker";
|
|
2
|
+
import { MeshRegistry } from "../store/MeshRegistry";
|
|
3
|
+
import { Painter } from "@mirage-engine/painter";
|
|
4
|
+
import * as THREE from "three";
|
|
5
|
+
|
|
6
|
+
export function animateMeshByData(
|
|
7
|
+
registry: MeshRegistry,
|
|
8
|
+
data: Map<HTMLElement, StyleData>,
|
|
9
|
+
) {
|
|
10
|
+
if (data.size === 0) return;
|
|
11
|
+
|
|
12
|
+
data.forEach((styleData, element) => {
|
|
13
|
+
const mesh = registry.get(element);
|
|
14
|
+
if (!mesh || !mesh.userData.basePosition) return;
|
|
15
|
+
|
|
16
|
+
let { x: baseX, y: baseY } = mesh.userData.basePosition;
|
|
17
|
+
const { width: baseW, height: baseH } = mesh.userData.baseSize;
|
|
18
|
+
|
|
19
|
+
const currentW = styleData.width ?? baseW;
|
|
20
|
+
const currentH = styleData.height ?? baseH;
|
|
21
|
+
const widthDiff = currentW - baseW;
|
|
22
|
+
const heightDiff = currentH - baseH;
|
|
23
|
+
|
|
24
|
+
if (
|
|
25
|
+
styleData.width !== undefined &&
|
|
26
|
+
mesh.userData.originRatioX === undefined &&
|
|
27
|
+
Math.abs(widthDiff) > 0.1
|
|
28
|
+
) {
|
|
29
|
+
const rect = element.getBoundingClientRect();
|
|
30
|
+
const tx = styleData.x ?? 0;
|
|
31
|
+
const baseTx = mesh.userData.baseTransform?.x ?? 0;
|
|
32
|
+
const scrollOffsetX = mesh.userData.isFixed ? 0 : window.scrollX;
|
|
33
|
+
const currentPageX = rect.left + scrollOffsetX - tx + baseTx;
|
|
34
|
+
const deltaX = currentPageX - mesh.userData.baseDOM.x;
|
|
35
|
+
|
|
36
|
+
let ratioX = -deltaX / widthDiff;
|
|
37
|
+
if (Math.abs(ratioX) < 0.05) ratioX = 0.0;
|
|
38
|
+
else if (Math.abs(ratioX - 1.0) < 0.05) ratioX = 1.0;
|
|
39
|
+
else if (Math.abs(ratioX - 0.5) < 0.05) ratioX = 0.5;
|
|
40
|
+
|
|
41
|
+
mesh.userData.originRatioX = ratioX;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
styleData.height !== undefined &&
|
|
46
|
+
mesh.userData.originRatioY === undefined &&
|
|
47
|
+
Math.abs(heightDiff) > 0.1
|
|
48
|
+
) {
|
|
49
|
+
const rect = element.getBoundingClientRect();
|
|
50
|
+
const ty = styleData.y ?? 0;
|
|
51
|
+
const baseTy = mesh.userData.baseTransform?.y ?? 0;
|
|
52
|
+
const scrollOffsetY = mesh.userData.isFixed ? 0 : window.scrollY;
|
|
53
|
+
const currentPageY = rect.top + scrollOffsetY - ty + baseTy;
|
|
54
|
+
const deltaY = currentPageY - mesh.userData.baseDOM.y;
|
|
55
|
+
|
|
56
|
+
let ratioY = -deltaY / heightDiff;
|
|
57
|
+
if (Math.abs(ratioY) < 0.05) ratioY = 0.0;
|
|
58
|
+
else if (Math.abs(ratioY - 1.0) < 0.05) ratioY = 1.0;
|
|
59
|
+
else if (Math.abs(ratioY - 0.5) < 0.05) ratioY = 0.5;
|
|
60
|
+
|
|
61
|
+
mesh.userData.originRatioY = ratioY;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const ratioX = mesh.userData.originRatioX ?? 0.5;
|
|
65
|
+
const ratioY = mesh.userData.originRatioY ?? 0.5;
|
|
66
|
+
|
|
67
|
+
const moveX = widthDiff * (0.5 - ratioX);
|
|
68
|
+
const moveY = heightDiff * (0.5 - ratioY);
|
|
69
|
+
|
|
70
|
+
const baseTx = mesh.userData.baseTransform?.x ?? 0;
|
|
71
|
+
const baseTy = mesh.userData.baseTransform?.y ?? 0;
|
|
72
|
+
|
|
73
|
+
const deltaTx = (styleData.x ?? baseTx) - baseTx;
|
|
74
|
+
const deltaTy = (styleData.y ?? baseTy) - baseTy;
|
|
75
|
+
|
|
76
|
+
mesh.position.setX(baseX + moveX + deltaTx);
|
|
77
|
+
mesh.position.setY(baseY - (moveY + deltaTy));
|
|
78
|
+
mesh.scale.set(currentW, currentH, 1);
|
|
79
|
+
|
|
80
|
+
Painter.forceUpdateUniforms(mesh.material as THREE.ShaderMaterial, {
|
|
81
|
+
backgroundColor: styleData.backgroundColor,
|
|
82
|
+
backgroundImage: styleData.backgroundImage,
|
|
83
|
+
opacity: styleData.opacity,
|
|
84
|
+
borderRadius: styleData.borderRadius ?? mesh.userData.baseStyles?.borderRadius,
|
|
85
|
+
width: currentW,
|
|
86
|
+
height: currentH,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function updateFixedMeshesScroll(
|
|
92
|
+
fixedMeshes: Set<THREE.Mesh>,
|
|
93
|
+
currentScrollX: number,
|
|
94
|
+
currentScrollY: number,
|
|
95
|
+
) {
|
|
96
|
+
fixedMeshes.forEach((mesh) => {
|
|
97
|
+
if (mesh.userData.isFixed && mesh.userData.initialScroll && mesh.userData.originalBasePosition) {
|
|
98
|
+
const offsetX = currentScrollX - mesh.userData.initialScroll.x;
|
|
99
|
+
const offsetY = currentScrollY - mesh.userData.initialScroll.y;
|
|
100
|
+
|
|
101
|
+
mesh.userData.basePosition.x = mesh.userData.originalBasePosition.x + offsetX;
|
|
102
|
+
mesh.userData.basePosition.y = mesh.userData.originalBasePosition.y - offsetY;
|
|
103
|
+
|
|
104
|
+
mesh.position.x = mesh.userData.basePosition.x;
|
|
105
|
+
mesh.position.y = mesh.userData.basePosition.y;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
package/src/core/Engine.ts
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import { CoreConfig } from "../types";
|
|
1
|
+
import { CoreConfig, ATTR_DOM } from "../types";
|
|
2
2
|
import { Renderer } from "../renderer/Renderer";
|
|
3
3
|
import { Syncer } from "./Syncer";
|
|
4
|
+
import { MeshRegistry } from "../store/MeshRegistry";
|
|
4
5
|
|
|
5
6
|
export class Engine {
|
|
6
7
|
private renderer: Renderer;
|
|
7
8
|
private syncer: Syncer;
|
|
8
9
|
private target: HTMLElement;
|
|
10
|
+
private registry: MeshRegistry;
|
|
9
11
|
|
|
10
12
|
constructor(target: HTMLElement, config: CoreConfig) {
|
|
11
13
|
this.target = target;
|
|
14
|
+
this.registry = new MeshRegistry();
|
|
15
|
+
|
|
16
|
+
if (!document.getElementById("mirage-engine-styles")) {
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.id = "mirage-engine-styles";
|
|
19
|
+
style.textContent = `
|
|
20
|
+
[${ATTR_DOM.NAME}="${ATTR_DOM.VALUES.HIDE}"] {
|
|
21
|
+
opacity: 0 !important;
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
document.head.appendChild(style);
|
|
25
|
+
}
|
|
12
26
|
|
|
13
27
|
let mountContainer: HTMLElement | undefined;
|
|
14
28
|
|
|
@@ -23,11 +37,14 @@ export class Engine {
|
|
|
23
37
|
throw new Error("[Mirage] Cannot find a container (parent or option).");
|
|
24
38
|
}
|
|
25
39
|
|
|
26
|
-
this.renderer = new Renderer(
|
|
27
|
-
|
|
40
|
+
this.renderer = new Renderer(
|
|
41
|
+
this.target,
|
|
42
|
+
config,
|
|
43
|
+
mountContainer,
|
|
44
|
+
this.registry,
|
|
45
|
+
);
|
|
28
46
|
this.renderer.mount();
|
|
29
|
-
|
|
30
|
-
this.syncer = new Syncer(this.target, this.renderer, config);
|
|
47
|
+
this.syncer = new Syncer(this.target, this.renderer, this.registry, config);
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
public start() {
|
|
@@ -41,4 +58,51 @@ export class Engine {
|
|
|
41
58
|
this.syncer.stop();
|
|
42
59
|
this.renderer.dispose();
|
|
43
60
|
}
|
|
61
|
+
|
|
62
|
+
public getTracker() {
|
|
63
|
+
return this.syncer.tracker;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public updateUniforms(element: HTMLElement, uniforms: Record<string, any>) {
|
|
67
|
+
this.renderer.updateUniforms(element, uniforms);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public getCanvas() {
|
|
71
|
+
return this.renderer.canvas;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public test() {
|
|
75
|
+
const boxMesh = this.registry.get(
|
|
76
|
+
document.querySelector("#box2") as HTMLElement,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!boxMesh) return;
|
|
80
|
+
|
|
81
|
+
const keys: { [key: string]: boolean } = {
|
|
82
|
+
ArrowRight: false,
|
|
83
|
+
ArrowLeft: false,
|
|
84
|
+
ArrowUp: false,
|
|
85
|
+
ArrowDown: false,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
window.addEventListener("keydown", (e) => {
|
|
89
|
+
if (keys[e.key] !== undefined) keys[e.key] = true;
|
|
90
|
+
});
|
|
91
|
+
window.addEventListener("keyup", (e) => {
|
|
92
|
+
if (keys[e.key] !== undefined) keys[e.key] = false;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const moveStep = 2;
|
|
96
|
+
|
|
97
|
+
const animate = () => {
|
|
98
|
+
requestAnimationFrame(animate);
|
|
99
|
+
|
|
100
|
+
if (keys.ArrowRight) boxMesh.position.setX(boxMesh.position.x + moveStep);
|
|
101
|
+
if (keys.ArrowLeft) boxMesh.position.setX(boxMesh.position.x - moveStep);
|
|
102
|
+
if (keys.ArrowUp) boxMesh.position.setY(boxMesh.position.y + moveStep);
|
|
103
|
+
if (keys.ArrowDown) boxMesh.position.setY(boxMesh.position.y - moveStep);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
animate();
|
|
107
|
+
}
|
|
44
108
|
}
|
package/src/core/Syncer.ts
CHANGED
|
@@ -1,216 +1,75 @@
|
|
|
1
1
|
import { CoreConfig } from "../types/config";
|
|
2
2
|
import { Renderer } from "../renderer/Renderer";
|
|
3
|
+
import { MeshRegistry } from "../store/MeshRegistry";
|
|
3
4
|
import { extractSceneGraph } from "../dom/Extractor";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
DIRTY_STRUCTURE,
|
|
8
|
-
DIRTY_STYLE,
|
|
9
|
-
USER_LAYER,
|
|
10
|
-
SYSTEM_LAYER,
|
|
11
|
-
Visibility,
|
|
12
|
-
} from "../types";
|
|
13
|
-
|
|
14
|
-
interface InternalResizeConfig {
|
|
15
|
-
enabled: boolean;
|
|
16
|
-
delay: number;
|
|
17
|
-
onStart?: () => void;
|
|
18
|
-
onEnd?: () => void;
|
|
19
|
-
}
|
|
5
|
+
import { Visibility, USER_LAYER, ATTR_TRAVEL } from "../types";
|
|
6
|
+
import { animateMeshByData, updateFixedMeshesScroll } from "../animation/Animator";
|
|
7
|
+
import { Tracker } from "@mirage-engine/dom-tracker";
|
|
20
8
|
|
|
21
9
|
export class Syncer {
|
|
22
10
|
private target: HTMLElement;
|
|
23
11
|
private renderer: Renderer;
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
private observer: MutationObserver;
|
|
27
|
-
|
|
28
|
-
private isDomDirty: boolean = false;
|
|
29
|
-
private isRunning: boolean = false;
|
|
12
|
+
private registry: MeshRegistry;
|
|
30
13
|
private isTravelEnabled: boolean = false;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
constructor(target: HTMLElement, renderer: Renderer, config: CoreConfig) {
|
|
14
|
+
|
|
15
|
+
public tracker: Tracker;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
target: HTMLElement,
|
|
19
|
+
renderer: Renderer,
|
|
20
|
+
registry: MeshRegistry,
|
|
21
|
+
config: CoreConfig,
|
|
22
|
+
) {
|
|
42
23
|
this.target = target;
|
|
43
24
|
this.renderer = renderer;
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
// Resize Debounce Configuration
|
|
47
|
-
const debounceOpt = config.resizeDebounce ?? true;
|
|
48
|
-
if (debounceOpt === false) {
|
|
49
|
-
this.resizeConfig = { enabled: false, delay: 0 };
|
|
50
|
-
} else if (debounceOpt === true) {
|
|
51
|
-
this.resizeConfig = { enabled: true, delay: 150 };
|
|
52
|
-
} else {
|
|
53
|
-
this.resizeConfig = {
|
|
54
|
-
enabled: true,
|
|
55
|
-
delay: debounceOpt.delay ?? 150,
|
|
56
|
-
onStart: debounceOpt.onStart,
|
|
57
|
-
onEnd: debounceOpt.onEnd,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
25
|
+
this.registry = registry;
|
|
60
26
|
|
|
61
|
-
|
|
62
|
-
|
|
27
|
+
// Use Tracker from dom-tracker
|
|
28
|
+
this.tracker = new Tracker(target, {
|
|
29
|
+
resizeDebounce: config.resizeDebounce,
|
|
30
|
+
});
|
|
63
31
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
) {
|
|
72
|
-
currentMask |= DIRTY_RECT | DIRTY_STYLE;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
32
|
+
// Wire up the hooks
|
|
33
|
+
this.tracker.onLayoutChange.add((pendingMask, pendingDeletions) => {
|
|
34
|
+
const discoveredTraveler =
|
|
35
|
+
document.querySelector(`[${ATTR_TRAVEL.NAME}~='${ATTR_TRAVEL.VALUES.TRAVELER}']`) !== null;
|
|
36
|
+
if (discoveredTraveler && !this.isTravelEnabled) {
|
|
37
|
+
this.isTravelEnabled = true;
|
|
38
|
+
this.renderer.createRenderTarget();
|
|
75
39
|
}
|
|
76
40
|
|
|
77
|
-
|
|
78
|
-
this.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
clearTimeout(this.mutationTimer);
|
|
89
|
-
}
|
|
90
|
-
this.mutationTimer = window.setTimeout(() => {
|
|
91
|
-
this.mutationTimer = null;
|
|
92
|
-
this.isDomDirty = true;
|
|
93
|
-
}, 200);
|
|
41
|
+
const sceneGraph = extractSceneGraph(
|
|
42
|
+
this.target,
|
|
43
|
+
pendingMask,
|
|
44
|
+
USER_LAYER as Visibility,
|
|
45
|
+
1,
|
|
46
|
+
0,
|
|
47
|
+
this.renderer.qualityFactor
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
if (sceneGraph) {
|
|
51
|
+
this.renderer.syncScene(sceneGraph, pendingDeletions);
|
|
94
52
|
}
|
|
95
53
|
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
public start() {
|
|
99
|
-
if (this.isRunning) return;
|
|
100
|
-
this.isRunning = true;
|
|
101
54
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
childList: true,
|
|
105
|
-
subtree: true,
|
|
106
|
-
attributes: true,
|
|
107
|
-
characterData: true,
|
|
55
|
+
this.tracker.onScrollChange.add((scrollX, scrollY) => {
|
|
56
|
+
updateFixedMeshesScroll(this.renderer.fixedMeshes, scrollX, scrollY);
|
|
108
57
|
});
|
|
109
58
|
|
|
110
|
-
this.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
window.addEventListener("resize", this.onWindowResize);
|
|
114
|
-
|
|
115
|
-
this.forceUpdateScene();
|
|
116
|
-
this.renderLoop();
|
|
117
|
-
// for debugging
|
|
118
|
-
// this.renderer.showScissoredRenderTarget();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public stop() {
|
|
122
|
-
this.isRunning = false;
|
|
123
|
-
this.observer.disconnect();
|
|
124
|
-
|
|
125
|
-
this.clearTimers();
|
|
59
|
+
this.tracker.onStyleChange.add((pendingStyles) => {
|
|
60
|
+
animateMeshByData(this.registry, pendingStyles);
|
|
61
|
+
});
|
|
126
62
|
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
63
|
+
this.tracker.onRender.add(() => {
|
|
64
|
+
this.renderer.render();
|
|
65
|
+
});
|
|
130
66
|
}
|
|
131
67
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
clearTimeout(this.mutationTimer);
|
|
135
|
-
this.mutationTimer = null;
|
|
136
|
-
}
|
|
137
|
-
if (this.cssTimer) {
|
|
138
|
-
clearTimeout(this.cssTimer);
|
|
139
|
-
this.cssTimer = null;
|
|
140
|
-
}
|
|
68
|
+
public start() {
|
|
69
|
+
this.tracker.start();
|
|
141
70
|
}
|
|
142
71
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (this.mutationTimer !== null) return;
|
|
147
|
-
|
|
148
|
-
if (this.cssTimer) clearTimeout(this.cssTimer);
|
|
149
|
-
|
|
150
|
-
this.pendingMask |= DIRTY_RECT | DIRTY_STYLE;
|
|
151
|
-
|
|
152
|
-
this.cssTimer = window.setTimeout(() => {
|
|
153
|
-
this.isDomDirty = true;
|
|
154
|
-
this.cssTimer = null;
|
|
155
|
-
}, 50);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
private onWindowResize = () => {
|
|
159
|
-
if (!this.resizeConfig.enabled) {
|
|
160
|
-
this.isDomDirty = true;
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (!this.isResizing) {
|
|
165
|
-
this.isResizing = true;
|
|
166
|
-
if (this.resizeConfig.onStart) this.resizeConfig.onStart();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (this.resizeTimer) clearTimeout(this.resizeTimer);
|
|
170
|
-
|
|
171
|
-
this.resizeTimer = window.setTimeout(() => {
|
|
172
|
-
this.isDomDirty = true;
|
|
173
|
-
|
|
174
|
-
if (this.resizeConfig.onEnd) this.resizeConfig.onEnd();
|
|
175
|
-
this.isResizing = false;
|
|
176
|
-
this.resizeTimer = null;
|
|
177
|
-
}, this.resizeConfig.delay);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
private forceUpdateScene() {
|
|
181
|
-
this.isDomDirty = false;
|
|
182
|
-
|
|
183
|
-
const discoveredTraveler =
|
|
184
|
-
document.querySelector("[data-mirage-travel='traveler']") !== null;
|
|
185
|
-
if (discoveredTraveler && !this.isTravelEnabled) {
|
|
186
|
-
this.isTravelEnabled = true;
|
|
187
|
-
this.renderer.createRenderTarget();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const sceneGraph = extractSceneGraph(
|
|
191
|
-
this.target,
|
|
192
|
-
this.pendingMask,
|
|
193
|
-
(discoveredTraveler
|
|
194
|
-
? USER_LAYER | SYSTEM_LAYER
|
|
195
|
-
: USER_LAYER) as Visibility,
|
|
196
|
-
this.filter,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
if (sceneGraph) {
|
|
200
|
-
this.renderer.syncScene(sceneGraph);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
this.pendingMask = DIRTY_NONE;
|
|
72
|
+
public stop() {
|
|
73
|
+
this.tracker.stop();
|
|
204
74
|
}
|
|
205
|
-
|
|
206
|
-
private renderLoop = () => {
|
|
207
|
-
if (!this.isRunning) return;
|
|
208
|
-
|
|
209
|
-
if (this.isDomDirty) {
|
|
210
|
-
this.forceUpdateScene();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
this.renderer.render();
|
|
214
|
-
requestAnimationFrame(this.renderLoop);
|
|
215
|
-
};
|
|
216
75
|
}
|