@needle-tools/engine 4.12.4-next.46bee95 → 4.12.5-next.1be4457
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 +5 -0
- package/README.md +2 -1
- package/dist/{needle-engine.bundle-CvasmiEO.min.js → needle-engine.bundle-BNb-Ipns.min.js} +17 -16
- package/dist/{needle-engine.bundle-CojFvJHR.umd.cjs → needle-engine.bundle-Cf9xdXZc.umd.cjs} +45 -44
- package/dist/{needle-engine.bundle-DGjkYJDl.js → needle-engine.bundle-DMiFIvRW.js} +540 -519
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/debug/debug_overlay.js +1 -1
- package/lib/engine/debug/debug_overlay.js.map +1 -1
- package/lib/engine/engine_animation.js.map +1 -1
- package/lib/engine/webcomponents/WebXRButtons.js +1 -1
- package/lib/engine/webcomponents/WebXRButtons.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +5 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +84 -50
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +1 -0
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -1
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/utils/OpenURL.js +1 -3
- package/lib/engine-components/utils/OpenURL.js.map +1 -1
- package/lib/engine-components/webxr/WebXR.js +6 -8
- package/lib/engine-components/webxr/WebXR.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/debug/debug_overlay.ts +1 -1
- package/src/engine/engine_animation.ts +1 -1
- package/src/engine/webcomponents/WebXRButtons.ts +1 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +88 -50
- package/src/engine/webcomponents/needle-engine.ar-overlay.ts +1 -0
- package/src/engine-components/Animation.ts +1 -1
- package/src/engine-components/utils/OpenURL.ts +0 -2
- package/src/engine-components/webxr/WebXR.ts +6 -9
|
@@ -112,7 +112,7 @@ export function addLog(type: LogType, message: string | any[], _file?: string |
|
|
|
112
112
|
const context = ContextRegistry.Current;
|
|
113
113
|
let domElement = context?.domElement ?? document.querySelector("needle-engine");
|
|
114
114
|
// check if we're in webxr dom overlay
|
|
115
|
-
if (context
|
|
115
|
+
if (context?.isInAR) {
|
|
116
116
|
domElement = context.arOverlayElement;
|
|
117
117
|
}
|
|
118
118
|
if (!domElement) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnimationAction, AnimationClip, AnimationMixer, KeyframeTrack, Object3D, PropertyBinding, Vector3Like } from "three";
|
|
2
|
-
import { isDevEnvironment } from "./debug/index.js";
|
|
3
2
|
|
|
3
|
+
import { isDevEnvironment } from "./debug/index.js";
|
|
4
4
|
import type { Context } from "./engine_context.js";
|
|
5
5
|
import { GLTF, IAnimationComponent, Model } from "./engine_types.js";
|
|
6
6
|
import { TypeStore } from "./engine_typestore.js";
|
|
@@ -240,7 +240,7 @@ export class WebXRButtonFactory {
|
|
|
240
240
|
private hideElementDuringXRSession(element: HTMLElement) {
|
|
241
241
|
onXRSessionStart(_ => {
|
|
242
242
|
element["previous-display"] = element.style.display;
|
|
243
|
-
element.style.display
|
|
243
|
+
element.style.setProperty("display", "none", "important");
|
|
244
244
|
});
|
|
245
245
|
onXRSessionEnd(_ => {
|
|
246
246
|
if (element["previous-display"] != undefined)
|
|
@@ -269,7 +269,6 @@ export class NeedleMenu {
|
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
271
|
this._muteButton = ButtonsFactory.getOrCreate().createMuteButton(this._context);
|
|
272
|
-
this._muteButton.setAttribute("priority", "100");
|
|
273
272
|
this._menu.appendChild(this._muteButton);
|
|
274
273
|
}
|
|
275
274
|
private _muteButton?: HTMLButtonElement;
|
|
@@ -282,7 +281,6 @@ export class NeedleMenu {
|
|
|
282
281
|
}
|
|
283
282
|
this._fullscreenButton = ButtonsFactory.getOrCreate().createFullscreenButton(this._context);
|
|
284
283
|
if (this._fullscreenButton) {
|
|
285
|
-
this._fullscreenButton.setAttribute("priority", "150");
|
|
286
284
|
this._menu.appendChild(this._fullscreenButton);
|
|
287
285
|
}
|
|
288
286
|
}
|
|
@@ -527,9 +525,9 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
527
525
|
|
|
528
526
|
.logo {
|
|
529
527
|
cursor: pointer;
|
|
530
|
-
padding-left: 0.
|
|
531
|
-
padding-bottom: .
|
|
532
|
-
margin-right: 0.
|
|
528
|
+
padding-left: 0.5em;
|
|
529
|
+
padding-bottom: .02em;
|
|
530
|
+
margin-right: 0.6em;
|
|
533
531
|
}
|
|
534
532
|
.logo-hidden {
|
|
535
533
|
.logo {
|
|
@@ -538,8 +536,8 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
538
536
|
}
|
|
539
537
|
:host .has-options .logo {
|
|
540
538
|
border-left: 1px solid rgba(40,40,40,.4);
|
|
541
|
-
margin-left: 0.
|
|
542
|
-
margin-right: 0.
|
|
539
|
+
margin-left: 0.3em;
|
|
540
|
+
margin-right: 0.6em;
|
|
543
541
|
}
|
|
544
542
|
|
|
545
543
|
.logo > span {
|
|
@@ -671,22 +669,23 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
671
669
|
}
|
|
672
670
|
|
|
673
671
|
.compact .options > *, .compact .options > ::slotted(*) {
|
|
674
|
-
font-size: 1.
|
|
675
|
-
padding: .
|
|
672
|
+
font-size: 1.2em;
|
|
673
|
+
padding: .6em .5em;
|
|
676
674
|
width: 100%;
|
|
677
675
|
}
|
|
678
676
|
.compact.has-options {
|
|
679
|
-
padding-left:
|
|
677
|
+
padding-left: 1em;
|
|
680
678
|
}
|
|
681
679
|
.compact.has-options .logo {
|
|
682
680
|
border: none;
|
|
683
681
|
padding-left: 0;
|
|
684
|
-
margin-bottom: .
|
|
682
|
+
margin-bottom: .02em;
|
|
685
683
|
}
|
|
686
684
|
.compact .options.compact-only {
|
|
687
685
|
display: initial;
|
|
688
686
|
& > * {
|
|
689
687
|
min-height: 1em;
|
|
688
|
+
padding: .4em .4em;
|
|
690
689
|
}
|
|
691
690
|
}
|
|
692
691
|
.compact .options {
|
|
@@ -870,7 +869,7 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
870
869
|
connectedCallback() {
|
|
871
870
|
window.addEventListener("resize", this.handleSizeChange);
|
|
872
871
|
this.handleMenuVisible();
|
|
873
|
-
this._sizeChangeInterval = setInterval(() => this.handleSizeChange(undefined,
|
|
872
|
+
this._sizeChangeInterval = setInterval(() => this.handleSizeChange(undefined, false), 5000);
|
|
874
873
|
// the dom element is set after the constructor runs
|
|
875
874
|
setTimeout(() => {
|
|
876
875
|
this._domElement?.addEventListener("resize", this.handleSizeChange);
|
|
@@ -1073,6 +1072,8 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
1073
1072
|
}
|
|
1074
1073
|
|
|
1075
1074
|
private _isHandlingChange = false;
|
|
1075
|
+
/** During modification of options container (e.g. when moving items into the extra buttons container) the mutation observer should not trigger an update event immediately. This is a workaround for the total size required for all elements not being calculated reliably. */
|
|
1076
|
+
private _pauseMutationObserverOptionsContainer = false;
|
|
1076
1077
|
|
|
1077
1078
|
/** Called when any change in the web component is detected (including in children and child attributes) */
|
|
1078
1079
|
private onChangeDetected(_mut: MutationRecord[]) {
|
|
@@ -1083,7 +1084,8 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
1083
1084
|
this.handleMenuVisible();
|
|
1084
1085
|
for (const mut of _mut) {
|
|
1085
1086
|
if (mut.target == this.options) {
|
|
1086
|
-
this.
|
|
1087
|
+
if (!this._pauseMutationObserverOptionsContainer)
|
|
1088
|
+
this.onOptionsChildrenChanged(mut)
|
|
1087
1089
|
}
|
|
1088
1090
|
}
|
|
1089
1091
|
}
|
|
@@ -1168,29 +1170,34 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
1168
1170
|
|
|
1169
1171
|
|
|
1170
1172
|
private _lastAvailableWidthChange = 0;
|
|
1171
|
-
private
|
|
1173
|
+
private _timeoutHandleSize: number = 0;
|
|
1174
|
+
private _timeoutHandleCompactItems: number = 0;
|
|
1172
1175
|
|
|
1173
1176
|
private handleSizeChange = (_evt?: Event, forceOrEvent?: boolean) => {
|
|
1174
1177
|
if (!this._domElement) return;
|
|
1178
|
+
// if (this._isApplyingSizeUpdate) return;
|
|
1175
1179
|
|
|
1176
1180
|
const width = this._domElement.clientWidth;
|
|
1177
1181
|
if (width < 100) {
|
|
1178
|
-
clearTimeout(this.
|
|
1182
|
+
clearTimeout(this._timeoutHandleSize!);
|
|
1179
1183
|
this.root.classList.add("compact");
|
|
1180
1184
|
this.foldout.classList.add("floating-panel-style");
|
|
1181
1185
|
return;
|
|
1182
1186
|
}
|
|
1183
1187
|
|
|
1184
|
-
const padding =
|
|
1188
|
+
const padding = 10 * 2;
|
|
1185
1189
|
const availableWidth = width - padding;
|
|
1186
1190
|
|
|
1187
1191
|
// if the available width has not changed significantly then we can skip the rest
|
|
1188
1192
|
if (!forceOrEvent && Math.abs(availableWidth - this._lastAvailableWidthChange) < 1) return;
|
|
1189
1193
|
this._lastAvailableWidthChange = availableWidth;
|
|
1190
1194
|
|
|
1191
|
-
clearTimeout(this.
|
|
1195
|
+
clearTimeout(this._timeoutHandleSize!);
|
|
1196
|
+
|
|
1197
|
+
this._timeoutHandleSize = setTimeout(() => {
|
|
1198
|
+
|
|
1199
|
+
// console.warn("APPLY", this.root.classList.contains("compact") ? "COMPACT" : "FULL", "MODE (available width: " + availableWidth.toFixed(0) + "px)", getCurrentWidth());
|
|
1192
1200
|
|
|
1193
|
-
this._timeoutHandle = setTimeout(() => {
|
|
1194
1201
|
const spaceLeft = getSpaceLeft();
|
|
1195
1202
|
if (spaceLeft < 0) {
|
|
1196
1203
|
this.root.classList.add("compact")
|
|
@@ -1205,41 +1212,19 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
1205
1212
|
this.foldout.classList.add("floating-panel-style");
|
|
1206
1213
|
}
|
|
1207
1214
|
}
|
|
1215
|
+
this._pauseMutationObserverOptionsContainer = true;
|
|
1216
|
+
this.updateCompactFoldoutItem();
|
|
1217
|
+
window.requestAnimationFrame(() => this._pauseMutationObserverOptionsContainer = false);
|
|
1208
1218
|
|
|
1209
|
-
|
|
1210
|
-
this.optionsCompactMode.childNodes.forEach(element => {
|
|
1211
|
-
element.remove();
|
|
1212
|
-
});
|
|
1213
|
-
// Find items in the folding list with the highest priority
|
|
1214
|
-
// The one with the highest priority will be added to the visible container
|
|
1215
|
-
let priorityItem: HTMLElement | null = null;
|
|
1216
|
-
let priorityValue: number = -10000000;
|
|
1217
|
-
for (let i = 0; i < this.options.children.length; i++) {
|
|
1218
|
-
const element = this.options.children.item(i);
|
|
1219
|
-
if (element instanceof HTMLElement) {
|
|
1220
|
-
const priority = NeedleMenu.getElementPriority(element);
|
|
1221
|
-
if (priority !== undefined && priority > priorityValue) {
|
|
1222
|
-
// check if the element is hidden
|
|
1223
|
-
// @TODO: use computed styles
|
|
1224
|
-
const style = element.style;
|
|
1225
|
-
if (style.display === "none") continue;
|
|
1226
|
-
priorityItem = element;
|
|
1227
|
-
priorityValue = priority;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
if (priorityItem) {
|
|
1232
|
-
const item = priorityItem;
|
|
1233
|
-
const clone = item.cloneNode(true);
|
|
1234
|
-
clone.addEventListener("click", () => item.click())
|
|
1235
|
-
this.optionsCompactMode.appendChild(clone);
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
}, 5) as unknown as number;
|
|
1219
|
+
}, 150) as unknown as number;
|
|
1240
1220
|
|
|
1241
1221
|
const getCurrentWidth = () => {
|
|
1242
|
-
|
|
1222
|
+
let totalWidthRequired = 0;
|
|
1223
|
+
totalWidthRequired += this.options.getBoundingClientRect().width;
|
|
1224
|
+
totalWidthRequired += this.optionsCompactMode.getBoundingClientRect().width;
|
|
1225
|
+
totalWidthRequired += 10 * this.options.childElementCount; // padding
|
|
1226
|
+
totalWidthRequired += this.logoContainer.style.display != "none" ? this.logoContainer.getBoundingClientRect().width : 0;;
|
|
1227
|
+
return totalWidthRequired;
|
|
1243
1228
|
}
|
|
1244
1229
|
|
|
1245
1230
|
let lastSpaceLeft = -1;
|
|
@@ -1253,6 +1238,59 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
1253
1238
|
}
|
|
1254
1239
|
}
|
|
1255
1240
|
|
|
1241
|
+
private updateCompactFoldoutItem() {
|
|
1242
|
+
|
|
1243
|
+
if (this.root.classList.contains("compact")) {
|
|
1244
|
+
|
|
1245
|
+
// Find items in the folding list with the highest priority
|
|
1246
|
+
// The one with the highest priority will be added to the visible container
|
|
1247
|
+
let priorityItem: HTMLElement | null = null;
|
|
1248
|
+
let priorityValue: number = -10000000;
|
|
1249
|
+
const testItem = (element: ChildNode | null) => {
|
|
1250
|
+
if (element instanceof HTMLElement) {
|
|
1251
|
+
const priority = NeedleMenu.getElementPriority(element);
|
|
1252
|
+
if (priority !== undefined && priority >= priorityValue) {
|
|
1253
|
+
// check if the element is hidden
|
|
1254
|
+
// @TODO: use computed styles
|
|
1255
|
+
const style = window.getComputedStyle(element);
|
|
1256
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") {
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1259
|
+
priorityItem = element;
|
|
1260
|
+
priorityValue = priority;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
for (let i = 0; i < this.options.children.length; i++) {
|
|
1265
|
+
testItem(this.options.children.item(i));
|
|
1266
|
+
}
|
|
1267
|
+
for (let i = 0; i < this.optionsCompactMode.children.length; i++) {
|
|
1268
|
+
testItem(this.optionsCompactMode.children.item(i));
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
if (priorityItem && !this.optionsCompactMode.contains(priorityItem)) {
|
|
1272
|
+
this.optionsCompactMode.childNodes.forEach(element => {
|
|
1273
|
+
this.options.appendChild(element);
|
|
1274
|
+
});
|
|
1275
|
+
const item = priorityItem;
|
|
1276
|
+
this.optionsCompactMode.appendChild(item);
|
|
1277
|
+
// console.warn("In compact mode, moved item with priority " + priorityValue + " to compact foldout:", item);
|
|
1278
|
+
}
|
|
1279
|
+
else if (!priorityItem) {
|
|
1280
|
+
// console.warn("In compact mode but no item has priority, showing all items in foldout");
|
|
1281
|
+
this.optionsCompactMode.childNodes.forEach(element => {
|
|
1282
|
+
this.options.appendChild(element);
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
// console.warn("Not in compact mode but trying to update compact foldout item");
|
|
1288
|
+
this.optionsCompactMode.childNodes.forEach(element => {
|
|
1289
|
+
this.options.appendChild(element);
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
// private _foldoutItemVisibleInterval = 0;
|
|
1256
1294
|
|
|
1257
1295
|
|
|
1258
1296
|
private ___insertDebugOptions() {
|
|
@@ -121,6 +121,7 @@ export class AROverlayHandler {
|
|
|
121
121
|
|
|
122
122
|
const quitARSlot = document.createElement("slot");
|
|
123
123
|
quitARSlot.style.display = "contents";
|
|
124
|
+
quitARSlot.style.padding = "10px";
|
|
124
125
|
quitARSlot.setAttribute("name", "quit-ar");
|
|
125
126
|
this.appendElement(quitARSlot, element);
|
|
126
127
|
this._createdAROnlyElements.push(quitARSlot);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat } from "three";
|
|
2
|
-
import { AnimationUtils } from "../engine/engine_animation.js";
|
|
3
2
|
|
|
3
|
+
import { AnimationUtils } from "../engine/engine_animation.js";
|
|
4
4
|
import { Mathf } from "../engine/engine_math.js";
|
|
5
5
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
|
6
6
|
import { IAnimationComponent } from "../engine/engine_types.js";
|
|
@@ -57,8 +57,6 @@ export class OpenURL extends Behaviour implements IPointerClickHandler {
|
|
|
57
57
|
url = "mailto:" + url;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
if (isDevEnvironment()) showBalloonMessage("Open URL: " + url)
|
|
61
|
-
|
|
62
60
|
switch (this.mode) {
|
|
63
61
|
case OpenURLMode.NewTab:
|
|
64
62
|
if (DeviceUtilities.isSafari()) {
|
|
@@ -551,8 +551,6 @@ export class WebXR extends Behaviour {
|
|
|
551
551
|
* and device capabilities. Handles creating AR, VR, QuickLook buttons and utility buttons like QR codes.
|
|
552
552
|
*/
|
|
553
553
|
private handleCreatingHTML() {
|
|
554
|
-
const xrButtonsPriority = 50;
|
|
555
|
-
|
|
556
554
|
if (this.createARButton || this.createVRButton || this.useQuicklookExport) {
|
|
557
555
|
// Quicklook / iOS
|
|
558
556
|
if ((DeviceUtilities.isiOS() && DeviceUtilities.isSafari()) || debugQuicklook) {
|
|
@@ -560,18 +558,18 @@ export class WebXR extends Behaviour {
|
|
|
560
558
|
const usdzExporter = GameObject.findObjectOfType(USDZExporter);
|
|
561
559
|
if (!usdzExporter || (usdzExporter && usdzExporter.allowCreateQuicklookButton)) {
|
|
562
560
|
const button = this.getButtonsFactory().createQuicklookButton();
|
|
563
|
-
this.addButton(button
|
|
561
|
+
this.addButton(button);
|
|
564
562
|
}
|
|
565
563
|
}
|
|
566
564
|
}
|
|
567
565
|
// WebXR
|
|
568
566
|
if (this.createARButton) {
|
|
569
567
|
const arbutton = this.getButtonsFactory().createARButton();
|
|
570
|
-
this.addButton(arbutton
|
|
568
|
+
this.addButton(arbutton);
|
|
571
569
|
}
|
|
572
570
|
if (this.createVRButton) {
|
|
573
571
|
const vrbutton = this.getButtonsFactory().createVRButton();
|
|
574
|
-
this.addButton(vrbutton
|
|
572
|
+
this.addButton(vrbutton);
|
|
575
573
|
}
|
|
576
574
|
}
|
|
577
575
|
|
|
@@ -579,7 +577,7 @@ export class WebXR extends Behaviour {
|
|
|
579
577
|
NeedleXRSession.isVRSupported().then(supported => {
|
|
580
578
|
if (!supported) {
|
|
581
579
|
const button = this.getButtonsFactory().createSendToQuestButton();
|
|
582
|
-
this.addButton(button
|
|
580
|
+
this.addButton(button);
|
|
583
581
|
}
|
|
584
582
|
});
|
|
585
583
|
}
|
|
@@ -592,7 +590,7 @@ export class WebXR extends Behaviour {
|
|
|
592
590
|
}
|
|
593
591
|
else if (!DeviceUtilities.isMobileDevice()) {
|
|
594
592
|
const qrCode = ButtonsFactory.getOrCreate().createQRCode();
|
|
595
|
-
this.addButton(qrCode,
|
|
593
|
+
this.addButton(qrCode,);
|
|
596
594
|
}
|
|
597
595
|
}
|
|
598
596
|
}
|
|
@@ -607,9 +605,8 @@ export class WebXR extends Behaviour {
|
|
|
607
605
|
* @param button The HTML element to add
|
|
608
606
|
* @param priority The button's priority value (lower numbers appear first)
|
|
609
607
|
*/
|
|
610
|
-
private addButton(button: HTMLElement
|
|
608
|
+
private addButton(button: HTMLElement) {
|
|
611
609
|
this._buttons.push(button);
|
|
612
|
-
button.setAttribute("priority", priority.toString());
|
|
613
610
|
this.context.menu.appendChild(button);
|
|
614
611
|
}
|
|
615
612
|
|