@needle-tools/engine 4.10.0-next.f0ec242 → 4.10.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 +7 -3
- package/README.md +2 -1
- package/components.needle.json +1 -1
- package/dist/needle-engine.bundle-BSq-d_16.min.js +1652 -0
- package/dist/{needle-engine.bundle-dgNq9Vsa.umd.cjs → needle-engine.bundle-C2kVfQq6.umd.cjs} +153 -140
- package/dist/{needle-engine.bundle-BC-0Ex9m.js → needle-engine.bundle-CIuhf7-t.js} +7388 -7113
- package/dist/needle-engine.d.ts +15 -15
- package/dist/needle-engine.js +259 -257
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/vendor-CPuBPspY.umd.cjs +1121 -0
- package/dist/vendor-DPCU8cUF.min.js +1121 -0
- package/dist/vendor-MBoqSyFm.js +16240 -0
- package/lib/engine/codegen/register_types.js +2 -0
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_camera.d.ts +7 -1
- package/lib/engine/engine_camera.js +46 -6
- package/lib/engine/engine_camera.js.map +1 -1
- package/lib/engine/engine_context.d.ts +6 -0
- package/lib/engine/engine_context.js +48 -9
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_gizmos.d.ts +11 -10
- package/lib/engine/engine_gizmos.js +24 -10
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_license.js +1 -1
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lightdata.d.ts +3 -3
- package/lib/engine/engine_lightdata.js +10 -10
- package/lib/engine/engine_lightdata.js.map +1 -1
- package/lib/engine/engine_physics_rapier.js +4 -0
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_scenelighting.d.ts +1 -1
- package/lib/engine/engine_scenelighting.js +4 -5
- package/lib/engine/engine_scenelighting.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +3 -1
- package/lib/engine/engine_utils.js +11 -0
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
- package/lib/engine/extensions/extension_utils.js +1 -1
- package/lib/engine/extensions/extension_utils.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +1 -1
- package/lib/engine/webcomponents/logo-element.js +29 -5
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +4 -3
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.js +22 -0
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +0 -1
- package/lib/engine/webcomponents/needle-engine.loading.js +3 -36
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine/xr/NeedleXRController.d.ts +3 -3
- package/lib/engine/xr/NeedleXRController.js +28 -0
- package/lib/engine/xr/NeedleXRController.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +2 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/Renderer.js +6 -1
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/Skybox.js +22 -4
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/debug/LogStats.d.ts +1 -0
- package/lib/engine-components/debug/LogStats.js +1 -0
- package/lib/engine-components/debug/LogStats.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +7 -0
- package/lib/engine-components/timeline/PlayableDirector.js +8 -1
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineModels.d.ts +11 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineTracks.js +30 -25
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/utils/LookAt.js +5 -1
- package/lib/engine-components/utils/LookAt.js.map +1 -1
- package/lib/engine-components/web/Clickthrough.js +10 -2
- package/lib/engine-components/web/Clickthrough.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.d.ts +24 -0
- package/lib/engine-components/web/ScrollFollow.js +169 -42
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/engine-components/web/ViewBox.d.ts +43 -0
- package/lib/engine-components/web/ViewBox.js +258 -0
- package/lib/engine-components/web/ViewBox.js.map +1 -0
- package/lib/engine-components/web/index.d.ts +1 -0
- package/lib/engine-components/web/index.js +1 -0
- package/lib/engine-components/web/index.js.map +1 -1
- package/lib/engine-components-experimental/Presentation.d.ts +1 -0
- package/lib/engine-components-experimental/Presentation.js +1 -0
- package/lib/engine-components-experimental/Presentation.js.map +1 -1
- package/package.json +3 -2
- package/src/engine/codegen/register_types.ts +2 -0
- package/src/engine/engine_camera.ts +61 -9
- package/src/engine/engine_context.ts +50 -10
- package/src/engine/engine_gizmos.ts +37 -23
- package/src/engine/engine_license.ts +1 -1
- package/src/engine/engine_lightdata.ts +11 -11
- package/src/engine/engine_physics_rapier.ts +3 -0
- package/src/engine/engine_scenelighting.ts +5 -6
- package/src/engine/engine_utils.ts +12 -0
- package/src/engine/extensions/NEEDLE_lightmaps.ts +1 -1
- package/src/engine/extensions/extension_utils.ts +1 -1
- package/src/engine/webcomponents/logo-element.ts +29 -4
- package/src/engine/webcomponents/needle menu/needle-menu.ts +4 -3
- package/src/engine/webcomponents/needle-engine.loading.ts +32 -32
- package/src/engine/webcomponents/needle-engine.ts +33 -6
- package/src/engine/xr/NeedleXRController.ts +36 -4
- package/src/engine-components/CameraUtils.ts +1 -1
- package/src/engine-components/Renderer.ts +6 -1
- package/src/engine-components/Skybox.ts +26 -7
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/debug/LogStats.ts +1 -0
- package/src/engine-components/timeline/PlayableDirector.ts +10 -1
- package/src/engine-components/timeline/TimelineModels.ts +11 -1
- package/src/engine-components/timeline/TimelineTracks.ts +30 -25
- package/src/engine-components/utils/LookAt.ts +5 -1
- package/src/engine-components/web/Clickthrough.ts +11 -2
- package/src/engine-components/web/ScrollFollow.ts +205 -51
- package/src/engine-components/web/ViewBox.ts +278 -0
- package/src/engine-components/web/index.ts +2 -1
- package/src/engine-components-experimental/Presentation.ts +1 -0
- package/dist/needle-engine.bundle-BSh7dSEx.min.js +0 -1639
- package/dist/vendor-D0Yvltn9.umd.cjs +0 -1121
- package/dist/vendor-DU8tJyl_.js +0 -14366
- package/dist/vendor-JyrX4DVM.min.js +0 -1121
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { Camera, PerspectiveCamera, Quaternion, Scene, Vector2, Vector3 } from "three";
|
|
2
|
+
|
|
3
|
+
import { isDevEnvironment } from "../../engine/debug/debug.js";
|
|
4
|
+
import { Gizmos } from "../../engine/engine_gizmos.js";
|
|
5
|
+
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
|
6
|
+
import { getTempVector } from "../../engine/engine_three_utils.js";
|
|
7
|
+
import { registerType } from "../../engine/engine_typestore.js";
|
|
8
|
+
import { getParam } from "../../engine/engine_utils.js";
|
|
9
|
+
import { RGBAColor } from "../../engine/js-extensions/RGBAColor.js";
|
|
10
|
+
import { Behaviour } from "../Component.js";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const debugParam = getParam("debugviewbox");
|
|
14
|
+
const disabledGizmoColor = new RGBAColor(.5, .5, .5, .5);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* This component can be used to automatically fit a certain box area into the camera view - no matter your screen size or aspect ratio.
|
|
18
|
+
*
|
|
19
|
+
* Add the ViewBox to an object into your scene
|
|
20
|
+
*
|
|
21
|
+
* @link [Example on needle.run](https://viewbox-demo-z23hmxbz2gkayo-z1nyzm6.needle.run/)
|
|
22
|
+
* @link [Scrollytelling Demo using animated Viewbox](https://scrollytelling-bike-z23hmxb2gnu5a.needle.run/)
|
|
23
|
+
* @link [Example on Stackblitz](https://stackblitz.com/edit/needle-engine-view-box-example)
|
|
24
|
+
*
|
|
25
|
+
* @example Add a Viewbox component to an object in your scene
|
|
26
|
+
* ```ts
|
|
27
|
+
const viewBox = new Object3D();
|
|
28
|
+
viewBox.scale.set(0, 0, 0);
|
|
29
|
+
viewBox.addComponent(ViewBox, { debug: true });
|
|
30
|
+
scene.add(viewBox);
|
|
31
|
+
|
|
32
|
+
* @category Web
|
|
33
|
+
* @group Components
|
|
34
|
+
* @component
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
@registerType
|
|
38
|
+
export class ViewBox extends Behaviour {
|
|
39
|
+
|
|
40
|
+
static readonly instances: ViewBox[] = [];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The reference field of view is used to calculate the box size. This should usually be the same as your camera's fov.
|
|
44
|
+
* @default undefined (meaning it will use the camera fov on the first frame)
|
|
45
|
+
*/
|
|
46
|
+
@serializable()
|
|
47
|
+
referenceFieldOfView: number | undefined = undefined;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Enable debug logs and rendering for this component instance
|
|
51
|
+
*/
|
|
52
|
+
@serializable()
|
|
53
|
+
debug: boolean = false;
|
|
54
|
+
|
|
55
|
+
onEnable(): void {
|
|
56
|
+
if (debugParam || this.debug || isDevEnvironment()) console.debug("[ViewBox] Using camera fov:", this.referenceFieldOfView);
|
|
57
|
+
// register instance
|
|
58
|
+
ViewBox.instances.push(this);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
onDisable(): void {
|
|
62
|
+
if (debugParam || this.debug) console.debug("[ViewBox] Disabled");
|
|
63
|
+
// unregister instance
|
|
64
|
+
const idx = ViewBox.instances.indexOf(this);
|
|
65
|
+
if (idx !== -1) ViewBox.instances.splice(idx, 1);
|
|
66
|
+
this._projectedBoxElement?.remove();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
onBeforeRender(): void {
|
|
70
|
+
if (this.context.isInXR) return;
|
|
71
|
+
if (this.destroyed) return;
|
|
72
|
+
const isActive = ViewBox.instances[ViewBox.instances.length - 1] === this;
|
|
73
|
+
if (!isActive) {
|
|
74
|
+
if (debugParam || this.debug) {
|
|
75
|
+
Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, disabledGizmoColor);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (debugParam || this.debug) Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0xdddd00, 0, true, this.gameObject.worldQuaternion);
|
|
80
|
+
|
|
81
|
+
// calculate box size to fit the camera frustrum size at the current position (just scale)
|
|
82
|
+
const camera = this.context.mainCamera;
|
|
83
|
+
if (!camera) return;
|
|
84
|
+
if (!(camera instanceof PerspectiveCamera)) {
|
|
85
|
+
// TODO: support orthographic camera
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (this.referenceFieldOfView === undefined) {
|
|
90
|
+
this.referenceFieldOfView = camera.fov;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (this.referenceFieldOfView === undefined || this.referenceFieldOfView <= 0) {
|
|
94
|
+
if (debugParam || this.debug) console.warn("[ViewBox] No valid referenceFieldOfView set, cannot adjust box size:", this.referenceFieldOfView);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const domWidth = this.context.domWidth;
|
|
99
|
+
const domHeight = this.context.domHeight;
|
|
100
|
+
|
|
101
|
+
let rectPosX = 0;
|
|
102
|
+
let rectPosY = 0;
|
|
103
|
+
let rectWidth = domWidth;
|
|
104
|
+
let rectHeight = domHeight;
|
|
105
|
+
let diffWidth = 1;
|
|
106
|
+
let diffHeight = 1;
|
|
107
|
+
// use focus rect if available
|
|
108
|
+
const focusRectSize = this.context.focusRectSize;
|
|
109
|
+
if (focusRectSize) {
|
|
110
|
+
// console.log(focusRectSize)
|
|
111
|
+
rectPosX = focusRectSize.x;
|
|
112
|
+
rectPosY = focusRectSize.y;
|
|
113
|
+
rectWidth = focusRectSize.width;
|
|
114
|
+
rectHeight = focusRectSize.height;
|
|
115
|
+
diffWidth = domWidth / rectWidth;
|
|
116
|
+
diffHeight = domHeight / rectHeight;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
const view = camera.view;
|
|
121
|
+
const zoom = camera.zoom;
|
|
122
|
+
const aspect = camera.aspect;
|
|
123
|
+
const fov = camera.fov;
|
|
124
|
+
camera.view = null;
|
|
125
|
+
camera.zoom = 1;
|
|
126
|
+
camera.fov = this.referenceFieldOfView;
|
|
127
|
+
camera.updateProjectionMatrix();
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
const boxPosition = this.gameObject.worldPosition;
|
|
131
|
+
const boxScale = this.gameObject.worldScale;
|
|
132
|
+
|
|
133
|
+
const cameraPosition = camera.worldPosition;
|
|
134
|
+
const distance = cameraPosition.distanceTo(boxPosition);
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
// #region camera fixes
|
|
138
|
+
// If the camera is inside the box, move it out
|
|
139
|
+
const boxSizeMax = Math.max(boxScale.x, boxScale.y, boxScale.z);
|
|
140
|
+
const direction = getTempVector(cameraPosition).sub(boxPosition);
|
|
141
|
+
if (distance < boxSizeMax) {
|
|
142
|
+
// move camera out of bounds
|
|
143
|
+
if (this.debug || debugParam) console.warn("[ViewBox] Moving camera out of bounds", distance, "<", boxSizeMax);
|
|
144
|
+
const positionDirection = getTempVector(direction);
|
|
145
|
+
positionDirection.y *= .00000001; // stay on horizontal plane mostly
|
|
146
|
+
positionDirection.normalize();
|
|
147
|
+
const lengthToMove = (boxSizeMax - distance);
|
|
148
|
+
const newPosition = cameraPosition.add(positionDirection.multiplyScalar(lengthToMove));
|
|
149
|
+
camera.worldPosition = newPosition.lerp(cameraPosition, 1 - this.context.time.deltaTime);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Ensure the camera looks at the ViewBox
|
|
153
|
+
// TOOD: smooth lookat over multiple frames if we have multiple viewboxes
|
|
154
|
+
// const dot = direction.normalize().dot(camera.worldForward);
|
|
155
|
+
// if (dot < .9) {
|
|
156
|
+
// console.log(dot);
|
|
157
|
+
// const targetRotation = direction;
|
|
158
|
+
// const rotation = getTempQuaternion();
|
|
159
|
+
// rotation.setFromUnitVectors(camera.worldForward.multiplyScalar(-1), targetRotation);
|
|
160
|
+
// camera.worldQuaternion = rotation;
|
|
161
|
+
// camera.updateMatrixWorld();
|
|
162
|
+
// }
|
|
163
|
+
const boxPositionInCameraSpace = getTempVector(boxPosition);
|
|
164
|
+
camera.worldToLocal(boxPositionInCameraSpace);
|
|
165
|
+
camera.lookAt(boxPosition);
|
|
166
|
+
camera.updateMatrixWorld();
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
// #region calculate fit
|
|
170
|
+
const vFOV = this.referenceFieldOfView * Math.PI / 180; // convert vertical fov to radians
|
|
171
|
+
const height = 2 * Math.tan(vFOV / 2) * distance; // visible height
|
|
172
|
+
const width = height * camera.aspect; // visible width
|
|
173
|
+
|
|
174
|
+
const projectedBox = this.projectBoxIntoCamera(camera, 1);
|
|
175
|
+
// return
|
|
176
|
+
const boxWidth = (projectedBox.maxX - projectedBox.minX);
|
|
177
|
+
const boxHeight = (projectedBox.maxY - projectedBox.minY);
|
|
178
|
+
|
|
179
|
+
const scale = this.fit(
|
|
180
|
+
boxWidth * camera.aspect,
|
|
181
|
+
boxHeight,
|
|
182
|
+
width / diffWidth,
|
|
183
|
+
height / diffHeight
|
|
184
|
+
);
|
|
185
|
+
// console.log({ scale, width, height, boxWidth: boxWidth * camera.aspect, boxHeight, diffWidth, diffHeight, aspect: camera.aspect, distance })
|
|
186
|
+
// this.context.focusRectSettings.zoom = 1.39;
|
|
187
|
+
// if (!this.context.focusRect) this.context.setCameraFocusRect(this.context.domElement);
|
|
188
|
+
// return
|
|
189
|
+
const vec = getTempVector(boxPosition);
|
|
190
|
+
vec.project(camera);
|
|
191
|
+
this.context.focusRectSettings.offsetX = vec.x;
|
|
192
|
+
this.context.focusRectSettings.offsetY = vec.y;
|
|
193
|
+
this.context.focusRectSettings.zoom = scale / (height * .5);
|
|
194
|
+
// if we don't have a focus rect yet, set it to the dom element
|
|
195
|
+
if (!this.context.focusRect) this.context.setCameraFocusRect(this.context.domElement);
|
|
196
|
+
|
|
197
|
+
// Reset values
|
|
198
|
+
camera.view = view;
|
|
199
|
+
camera.zoom = zoom;
|
|
200
|
+
camera.aspect = aspect;
|
|
201
|
+
camera.fov = fov;
|
|
202
|
+
// camera.updateProjectionMatrix();
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
// BACKLOG: some code for box scale of an object (different component)
|
|
206
|
+
// this.gameObject.worldScale = getTempVector(width, height, worldscale.z);
|
|
207
|
+
// this.gameObject.scale.multiplyScalar(.98)
|
|
208
|
+
// const minscale = Math.min(width, height);
|
|
209
|
+
// console.log(width, height);
|
|
210
|
+
// this.gameObject.worldScale = getTempVector(scale, scale, scale);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Cover fit
|
|
216
|
+
*/
|
|
217
|
+
private fit(width1: number, height1: number, width2: number, height2: number) {
|
|
218
|
+
const scaleX = width2 / width1;
|
|
219
|
+
const scaleY = height2 / height1;
|
|
220
|
+
return Math.min(scaleX, scaleY);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
private projectBoxIntoCamera(camera: Camera, _factor: number) {
|
|
226
|
+
const factor = .5 * _factor;
|
|
227
|
+
|
|
228
|
+
const corners = [
|
|
229
|
+
getTempVector(-factor, -factor, -factor),
|
|
230
|
+
getTempVector(factor, -factor, -factor),
|
|
231
|
+
getTempVector(-factor, factor, -factor),
|
|
232
|
+
getTempVector(factor, factor, -factor),
|
|
233
|
+
getTempVector(-factor, -factor, factor),
|
|
234
|
+
getTempVector(factor, -factor, factor),
|
|
235
|
+
getTempVector(-factor, factor, factor),
|
|
236
|
+
getTempVector(factor, factor, factor),
|
|
237
|
+
];
|
|
238
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
239
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
240
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
241
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
242
|
+
for (let i = 0; i < corners.length; i++) {
|
|
243
|
+
const c = corners[i];
|
|
244
|
+
c.applyMatrix4(this.gameObject.matrixWorld);
|
|
245
|
+
c.project(camera);
|
|
246
|
+
if (c.x < minX) minX = c.x;
|
|
247
|
+
if (c.x > maxX) maxX = c.x;
|
|
248
|
+
if (c.y < minY) minY = c.y;
|
|
249
|
+
if (c.y > maxY) maxY = c.y;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (debugParam) {
|
|
253
|
+
if (!this._projectedBoxElement) {
|
|
254
|
+
this._projectedBoxElement = document.createElement("div");
|
|
255
|
+
}
|
|
256
|
+
if (this._projectedBoxElement.parentElement !== this.context.domElement)
|
|
257
|
+
this.context.domElement.appendChild(this._projectedBoxElement);
|
|
258
|
+
this._projectedBoxElement.style.position = "fixed";
|
|
259
|
+
// dotted but with larger gaps
|
|
260
|
+
this._projectedBoxElement.style.outline = "2px dashed rgba(255,0,0,.5)";
|
|
261
|
+
this._projectedBoxElement.style.left = ((minX * .5 + .5) * this.context.domWidth) + "px";
|
|
262
|
+
this._projectedBoxElement.style.top = ((-maxY * .5 + .5) * this.context.domHeight) + "px";
|
|
263
|
+
this._projectedBoxElement.style.width = ((maxX - minX) * .5 * this.context.domWidth) + "px";
|
|
264
|
+
this._projectedBoxElement.style.height = ((maxY - minY) * .5 * this.context.domHeight) + "px";
|
|
265
|
+
this._projectedBoxElement.style.pointerEvents = "none";
|
|
266
|
+
this._projectedBoxElement.style.zIndex = "1000";
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
return { minX, maxX, minY, maxY };
|
|
271
|
+
|
|
272
|
+
}
|
|
273
|
+
private _projectedBoxElement: HTMLElement | null = null;
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
}
|