@needle-tools/engine 4.14.0 → 4.15.0-next.cecd8e7
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 +8 -0
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-NolzHLqO.min.js → needle-engine.bundle-CuAiLb-d.min.js} +137 -129
- package/dist/{needle-engine.bundle-COL2Bar3.umd.cjs → needle-engine.bundle-JQGIFVRm.umd.cjs} +128 -120
- package/dist/{needle-engine.bundle-Z_gAD7Kg.js → needle-engine.bundle-VZVrVbc3.js} +5497 -5252
- package/dist/needle-engine.d.ts +318 -42
- package/dist/needle-engine.js +570 -569
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/engine_accessibility.d.ts +77 -0
- package/lib/engine/engine_accessibility.js +162 -0
- package/lib/engine/engine_accessibility.js.map +1 -0
- package/lib/engine/engine_context.d.ts +2 -0
- package/lib/engine/engine_context.js +7 -0
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_materialpropertyblock.d.ts +90 -4
- package/lib/engine/engine_materialpropertyblock.js +97 -7
- package/lib/engine/engine_materialpropertyblock.js.map +1 -1
- package/lib/engine/engine_math.d.ts +34 -1
- package/lib/engine/engine_math.js +34 -1
- package/lib/engine/engine_math.js.map +1 -1
- package/lib/engine/engine_networking.js +1 -1
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -0
- package/lib/engine/engine_types.js +2 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/webcomponents/icons.js +3 -0
- package/lib/engine/webcomponents/icons.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +1 -0
- package/lib/engine/webcomponents/logo-element.js +3 -1
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle-button.d.ts +37 -11
- package/lib/engine/webcomponents/needle-button.js +42 -11
- package/lib/engine/webcomponents/needle-button.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +10 -2
- package/lib/engine/webcomponents/needle-engine.js +13 -3
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -2
- package/lib/engine-components/Component.js +1 -2
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/DragControls.d.ts +1 -0
- package/lib/engine-components/DragControls.js +21 -0
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/NeedleMenu.d.ts +2 -0
- package/lib/engine-components/NeedleMenu.js +2 -0
- package/lib/engine-components/NeedleMenu.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +28 -3
- package/lib/engine-components/Networking.js +28 -3
- package/lib/engine-components/Networking.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +1 -0
- package/lib/engine-components/ReflectionProbe.js +20 -2
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +15 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +77 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/ui/Button.d.ts +1 -0
- package/lib/engine-components/ui/Button.js +11 -0
- package/lib/engine-components/ui/Button.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -0
- package/lib/engine-components/ui/Text.js +11 -0
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/package.json +2 -2
- package/src/engine/engine_accessibility.ts +198 -0
- package/src/engine/engine_context.ts +9 -0
- package/src/engine/engine_materialpropertyblock.ts +102 -11
- package/src/engine/engine_math.ts +34 -1
- package/src/engine/engine_networking.ts +1 -1
- package/src/engine/engine_types.ts +5 -0
- package/src/engine/webcomponents/icons.ts +3 -0
- package/src/engine/webcomponents/logo-element.ts +4 -1
- package/src/engine/webcomponents/needle-button.ts +44 -13
- package/src/engine/webcomponents/needle-engine.ts +18 -7
- package/src/engine-components/Component.ts +1 -3
- package/src/engine-components/DragControls.ts +29 -4
- package/src/engine-components/NeedleMenu.ts +5 -3
- package/src/engine-components/Networking.ts +29 -4
- package/src/engine-components/ReflectionProbe.ts +21 -2
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +108 -32
- package/src/engine-components/ui/Button.ts +12 -0
- package/src/engine-components/ui/Text.ts +13 -0
|
@@ -13,12 +13,11 @@ import { AudioSource } from "../../../../AudioSource.js";
|
|
|
13
13
|
import { Behaviour, GameObject } from "../../../../Component.js";
|
|
14
14
|
import { Rigidbody } from "../../../../RigidBody.js";
|
|
15
15
|
import type { IPointerClickHandler, PointerEventData } from "../../../../ui/PointerEvents.js";
|
|
16
|
-
|
|
17
|
-
import { makeNameSafeForUSD,USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
|
16
|
+
import { makeNameSafeForUSD, USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
|
18
17
|
import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
|
|
19
18
|
import { AudioExtension } from "./AudioExtension.js";
|
|
20
19
|
import type { BehaviorExtension, UsdzBehaviour } from "./Behaviour.js";
|
|
21
|
-
import { ActionBuilder, ActionModel, BehaviorModel, EmphasizeActionMotionType,GroupActionModel,type IBehaviorElement, Target, TriggerBuilder } from "./BehavioursBuilder.js";
|
|
20
|
+
import { ActionBuilder, ActionModel, BehaviorModel, EmphasizeActionMotionType, GroupActionModel, type IBehaviorElement, Target, TriggerBuilder } from "./BehavioursBuilder.js";
|
|
22
21
|
|
|
23
22
|
const debug = getParam("debugusdzbehaviours");
|
|
24
23
|
|
|
@@ -57,6 +56,22 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
|
|
|
57
56
|
private targetRot = new Quaternion();
|
|
58
57
|
private targetScale = new Vector3();
|
|
59
58
|
|
|
59
|
+
onEnable(): void {
|
|
60
|
+
this.context.accessibility.updateElement(this, {
|
|
61
|
+
role: "button",
|
|
62
|
+
label: "Move " + (this.object?.name || "object") + " to " + (this.target?.name || "target") + " on click",
|
|
63
|
+
hidden: false,
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
onDisable(): void {
|
|
67
|
+
this.context.accessibility.updateElement(this, {
|
|
68
|
+
hidden: true,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
onDestroy(): void {
|
|
72
|
+
this.context.accessibility.removeElement(this);
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
onPointerEnter() {
|
|
61
76
|
this.context.input.setCursor("pointer");
|
|
62
77
|
}
|
|
@@ -68,8 +83,8 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
|
|
|
68
83
|
|
|
69
84
|
const rbs = this.object?.getComponentsInChildren(Rigidbody);
|
|
70
85
|
|
|
71
|
-
if (rbs){
|
|
72
|
-
for (const rb of rbs) {
|
|
86
|
+
if (rbs) {
|
|
87
|
+
for (const rb of rbs) {
|
|
73
88
|
rb.resetVelocities();
|
|
74
89
|
rb.resetForcesAndTorques();
|
|
75
90
|
}
|
|
@@ -227,6 +242,22 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
|
|
|
227
242
|
}
|
|
228
243
|
}
|
|
229
244
|
|
|
245
|
+
onEnable(): void {
|
|
246
|
+
this.context.accessibility.updateElement(this, {
|
|
247
|
+
role: "button",
|
|
248
|
+
label: "Change material to " + (this.variantMaterial?.name || "unknown material"),
|
|
249
|
+
hidden: false,
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
onDisable(): void {
|
|
253
|
+
this.context.accessibility.updateElement(this, {
|
|
254
|
+
hidden: true,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
onDestroy(): void {
|
|
258
|
+
this.context.accessibility.removeElement(this);
|
|
259
|
+
}
|
|
260
|
+
|
|
230
261
|
onPointerEnter(_args: PointerEventData) {
|
|
231
262
|
this.context.input.setCursor("pointer");
|
|
232
263
|
}
|
|
@@ -427,7 +458,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
427
458
|
|
|
428
459
|
if (!this.toggleOnClick && this.hideSelf)
|
|
429
460
|
this.gameObject.visible = false;
|
|
430
|
-
|
|
461
|
+
|
|
431
462
|
if (this.target)
|
|
432
463
|
this.target.visible = this.toggleOnClick ? !this.target.visible : this.targetState;
|
|
433
464
|
}
|
|
@@ -453,7 +484,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
453
484
|
|
|
454
485
|
beforeCreateDocument() {
|
|
455
486
|
if (!this.target) return;
|
|
456
|
-
|
|
487
|
+
|
|
457
488
|
// need to cache on the object itself, because otherwise different actions would override each other's visibility state
|
|
458
489
|
// TODO would probably be better to have this somewhere on the exporter, not on this component
|
|
459
490
|
if (this.gameObject[SetActiveOnClick.wasVisible] === undefined)
|
|
@@ -514,7 +545,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
514
545
|
// It's much easier to reason about nested actions when we're not duplicating tons of hierarchy...
|
|
515
546
|
// We can probably only do a shallow clone when the tapped object has geometry of its own, otherwise
|
|
516
547
|
// we end up with nothing to tap on.
|
|
517
|
-
|
|
548
|
+
|
|
518
549
|
// Option A: we deep clone ourselves. This makes hierarchical cases and nested behaviours really complex.
|
|
519
550
|
// We do this currently when the object doesn't have any geometry.
|
|
520
551
|
if (!this.selfModelClone.geometry) {
|
|
@@ -533,11 +564,11 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
533
564
|
clone.name += "_toggle" + (SetActiveOnClick.clonedToggleIndex++);
|
|
534
565
|
originalModel.add(clone);
|
|
535
566
|
this.gameObject[SetActiveOnClick.toggleClone] = clone;
|
|
536
|
-
|
|
567
|
+
|
|
537
568
|
console.warn("USDZExport: Toggle " + this.gameObject.name + " doesn't have geometry. It will be deep cloned and nested behaviours will likely not work.");
|
|
538
569
|
}
|
|
539
570
|
const clonedSelfModel = this.gameObject[SetActiveOnClick.toggleClone];
|
|
540
|
-
|
|
571
|
+
|
|
541
572
|
if (!this.gameObject[SetActiveOnClick.reverseToggleClone]) {
|
|
542
573
|
const clone = this.selfModelClone.clone();
|
|
543
574
|
clone.setMatrix(new Matrix4());
|
|
@@ -589,7 +620,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
589
620
|
TriggerBuilder.tapTrigger(selfModel),
|
|
590
621
|
ActionBuilder.parallel(...toggleSequence)
|
|
591
622
|
));
|
|
592
|
-
|
|
623
|
+
|
|
593
624
|
const reverseSequence: ActionModel[] = [];
|
|
594
625
|
reverseSequence.push(ActionBuilder.fadeAction(this.toggleModel, 0, false));
|
|
595
626
|
reverseSequence.push(ActionBuilder.fadeAction(selfModel, 0, true));
|
|
@@ -680,7 +711,7 @@ export class HideOnStart extends Behaviour implements UsdzBehaviour {
|
|
|
680
711
|
}
|
|
681
712
|
|
|
682
713
|
private wasVisible: boolean = false;
|
|
683
|
-
|
|
714
|
+
|
|
684
715
|
beforeCreateDocument() {
|
|
685
716
|
this.wasVisible = GameObject.isActiveSelf(this.gameObject);
|
|
686
717
|
}
|
|
@@ -713,6 +744,22 @@ export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
|
|
|
713
744
|
@serializable()
|
|
714
745
|
motionType: EmphasizeActionMotionType = "bounce";
|
|
715
746
|
|
|
747
|
+
onEnable(): void {
|
|
748
|
+
this.context.accessibility.updateElement(this, {
|
|
749
|
+
role: "button",
|
|
750
|
+
label: "Emphasize " + this.target?.name + " on click",
|
|
751
|
+
hidden: false,
|
|
752
|
+
})
|
|
753
|
+
}
|
|
754
|
+
onDisable(): void {
|
|
755
|
+
this.context.accessibility.updateElement(this, {
|
|
756
|
+
hidden: true,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
onDestroy(): void {
|
|
760
|
+
this.context.accessibility.removeElement(this);
|
|
761
|
+
}
|
|
762
|
+
|
|
716
763
|
beforeCreateDocument() { }
|
|
717
764
|
|
|
718
765
|
createBehaviours(ext, model, _context) {
|
|
@@ -775,6 +822,21 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
775
822
|
}
|
|
776
823
|
}
|
|
777
824
|
|
|
825
|
+
onEnable(): void {
|
|
826
|
+
this.context.accessibility.updateElement(this, {
|
|
827
|
+
role: "button",
|
|
828
|
+
label: "Play audio: " + (this.clip || this.target?.clip || "unknown clip"),
|
|
829
|
+
hidden: false,
|
|
830
|
+
})
|
|
831
|
+
}
|
|
832
|
+
onDisable(): void {
|
|
833
|
+
this.context.accessibility.updateElement(this, {
|
|
834
|
+
hidden: true,
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
onDestroy(): void {
|
|
838
|
+
this.context.accessibility.removeElement(this);
|
|
839
|
+
}
|
|
778
840
|
|
|
779
841
|
onPointerEnter() {
|
|
780
842
|
this.context.input.setCursor("pointer");
|
|
@@ -816,7 +878,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
816
878
|
const clipName = AudioExtension.getName(clipUrl);
|
|
817
879
|
const volume = this.target ? this.target.volume : 1;
|
|
818
880
|
const auralMode = this.target && this.target.spatialBlend == 0 ? "nonSpatial" : "spatial";
|
|
819
|
-
|
|
881
|
+
|
|
820
882
|
// This checks if any child is clickable – if yes, the tap trigger is added; if not, we omit it.
|
|
821
883
|
let anyChildHasGeometry = false;
|
|
822
884
|
this.gameObject.traverse(c => {
|
|
@@ -825,7 +887,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
825
887
|
// Workaround: seems iOS often simply doesn't play audio on scene start when this is NOT present.
|
|
826
888
|
// unclear why, but having a useless tap action (nothing to tap on) "fixes" it.
|
|
827
889
|
anyChildHasGeometry = true;
|
|
828
|
-
|
|
890
|
+
|
|
829
891
|
const audioClip = ext.addAudioClip(clipUrl);
|
|
830
892
|
// const stopAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "stop", volume, auralMode);
|
|
831
893
|
let playAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "play", volume, auralMode);
|
|
@@ -834,8 +896,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
834
896
|
|
|
835
897
|
const behaviorName = (this.name ? "_" + this.name : "");
|
|
836
898
|
|
|
837
|
-
if (anyChildHasGeometry && this.trigger === "tap")
|
|
838
|
-
{
|
|
899
|
+
if (anyChildHasGeometry && this.trigger === "tap") {
|
|
839
900
|
// does not seem to work in iOS / QuickLook...
|
|
840
901
|
// TODO use play "type" which can be start/stop/pause
|
|
841
902
|
if (this.toggleOnClick) (playAction as ActionModel).multiplePerformOperation = "stop";
|
|
@@ -901,9 +962,25 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
901
962
|
|
|
902
963
|
private get target() { return this.animator?.gameObject || this.animation?.gameObject }
|
|
903
964
|
|
|
965
|
+
onEnable(): void {
|
|
966
|
+
this.context.accessibility.updateElement(this, {
|
|
967
|
+
role: "button",
|
|
968
|
+
label: "Plays animation " + (this.stateName || "") + " on " + (this.target ? this.target.name : ""),
|
|
969
|
+
hidden: false
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
onDisable(): void {
|
|
973
|
+
this.context.accessibility.updateElement(this, {
|
|
974
|
+
hidden: true,
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
onDestroy(): void {
|
|
978
|
+
this.context.accessibility.removeElement(this);
|
|
979
|
+
}
|
|
904
980
|
|
|
905
981
|
onPointerEnter() {
|
|
906
982
|
this.context.input.setCursor("pointer");
|
|
983
|
+
this.context.accessibility.hover(this, "Click to play animation " + (this.stateName || "") + " on " + (this.target ? this.target.name : ""));
|
|
907
984
|
}
|
|
908
985
|
onPointerExit() {
|
|
909
986
|
this.context.input.unsetCursor("pointer");
|
|
@@ -912,6 +989,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
912
989
|
args.use();
|
|
913
990
|
if (!this.target) return;
|
|
914
991
|
if (this.stateName) {
|
|
992
|
+
this.context.accessibility.focus(this);
|
|
915
993
|
// TODO this is currently quite annoying to use,
|
|
916
994
|
// as for the web we use the Animator component and its states directly,
|
|
917
995
|
// while in QuickLook we use explicit animations / states.
|
|
@@ -923,8 +1001,8 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
923
1001
|
|
|
924
1002
|
private stateAnimationModel: any;
|
|
925
1003
|
|
|
926
|
-
private animationSequence
|
|
927
|
-
private animationLoopAfterSequence
|
|
1004
|
+
private animationSequence?= new Array<RegisteredAnimationInfo>();
|
|
1005
|
+
private animationLoopAfterSequence?= new Array<RegisteredAnimationInfo>();
|
|
928
1006
|
private randomOffsetNormalized: number = 0;
|
|
929
1007
|
|
|
930
1008
|
createBehaviours(_ext: BehaviorExtension, model: USDObject, _context: USDZExporterContext) {
|
|
@@ -950,9 +1028,9 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
950
1028
|
afterCreateDocument(ext: BehaviorExtension, context: USDZExporterContext) {
|
|
951
1029
|
if ((this.animationSequence === undefined && this.animationLoopAfterSequence === undefined) || !this.stateAnimationModel) return;
|
|
952
1030
|
if (!this.target) return;
|
|
953
|
-
|
|
1031
|
+
|
|
954
1032
|
const document = context.document;
|
|
955
|
-
|
|
1033
|
+
|
|
956
1034
|
// check if the AnimationExtension has been attached and what data it has for the current object
|
|
957
1035
|
const animationExt = context.extensions.find(ext => ext instanceof AnimationExtension) as AnimationExtension;
|
|
958
1036
|
if (!animationExt) return;
|
|
@@ -966,7 +1044,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
966
1044
|
if (requiresExclusivePlayback) {
|
|
967
1045
|
if (isDevEnvironment())
|
|
968
1046
|
console.warn("Setting exclusive playback for " + this.target.name + "@" + this.stateName + " because it has " + animationExt.getClipCount(this.target) + " animations. This works around QuickLook bug FB13410767.");
|
|
969
|
-
|
|
1047
|
+
|
|
970
1048
|
PlayAnimationOnClick.rootsWithExclusivePlayback.add(this.target);
|
|
971
1049
|
}
|
|
972
1050
|
|
|
@@ -986,7 +1064,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
986
1064
|
this.trigger == "tap" ? TriggerBuilder.tapTrigger(this.selfModel) : TriggerBuilder.sceneStartTrigger(),
|
|
987
1065
|
sequence
|
|
988
1066
|
);
|
|
989
|
-
|
|
1067
|
+
|
|
990
1068
|
// See comment above for why exclusive playback is currently required when playing multiple animations on the same root.
|
|
991
1069
|
if (requiresExclusivePlayback)
|
|
992
1070
|
playAnimationOnTap.makeExclusive(true);
|
|
@@ -1008,8 +1086,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1008
1086
|
|
|
1009
1087
|
const sequence = ActionBuilder.sequence();
|
|
1010
1088
|
|
|
1011
|
-
if (animationSequence && animationSequence.length > 0)
|
|
1012
|
-
{
|
|
1089
|
+
if (animationSequence && animationSequence.length > 0) {
|
|
1013
1090
|
for (const anim of animationSequence) {
|
|
1014
1091
|
sequence.addAction(getOrCacheAction(model, anim));
|
|
1015
1092
|
}
|
|
@@ -1033,11 +1110,10 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1033
1110
|
return sequence;
|
|
1034
1111
|
}
|
|
1035
1112
|
|
|
1036
|
-
static getAndRegisterAnimationSequences(ext: AnimationExtension, target: GameObject, stateName?: string):
|
|
1037
|
-
|
|
1038
|
-
animationSequence: Array<RegisteredAnimationInfo>,
|
|
1113
|
+
static getAndRegisterAnimationSequences(ext: AnimationExtension, target: GameObject, stateName?: string): {
|
|
1114
|
+
animationSequence: Array<RegisteredAnimationInfo>,
|
|
1039
1115
|
animationLoopAfterSequence: Array<RegisteredAnimationInfo>,
|
|
1040
|
-
randomTimeOffset: number,
|
|
1116
|
+
randomTimeOffset: number,
|
|
1041
1117
|
} | undefined {
|
|
1042
1118
|
|
|
1043
1119
|
if (!target) return undefined;
|
|
@@ -1055,14 +1131,14 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1055
1131
|
let animationLoopAfterSequence: Array<RegisteredAnimationInfo> = [];
|
|
1056
1132
|
|
|
1057
1133
|
if (animation) {
|
|
1058
|
-
const anim = ext.registerAnimation(target, animation.clip);
|
|
1059
|
-
if (anim) {
|
|
1134
|
+
const anim = ext.registerAnimation(target, animation.clip);
|
|
1135
|
+
if (anim) {
|
|
1060
1136
|
if (animation.loop)
|
|
1061
1137
|
animationLoopAfterSequence.push(anim);
|
|
1062
1138
|
else
|
|
1063
1139
|
animationSequence.push(anim);
|
|
1064
1140
|
}
|
|
1065
|
-
|
|
1141
|
+
|
|
1066
1142
|
let randomTimeOffset = 0;
|
|
1067
1143
|
if (animation.minMaxOffsetNormalized) {
|
|
1068
1144
|
const from = animation.minMaxOffsetNormalized.x;
|
|
@@ -1156,7 +1232,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1156
1232
|
if (lastClip) {
|
|
1157
1233
|
let clipCopy: AnimationClip | undefined;
|
|
1158
1234
|
if (ext.holdClipMap.has(lastClip)) {
|
|
1159
|
-
clipCopy = ext.holdClipMap.get(lastClip);
|
|
1235
|
+
clipCopy = ext.holdClipMap.get(lastClip);
|
|
1160
1236
|
}
|
|
1161
1237
|
else {
|
|
1162
1238
|
// We're creating a "hold" clip here; exactly 1 second long, and inteprolates exactly on the duration of the clip
|
|
@@ -180,6 +180,8 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
180
180
|
this.onClick.invoke();
|
|
181
181
|
args.use();
|
|
182
182
|
|
|
183
|
+
this.context.accessibility.focus(this);
|
|
184
|
+
|
|
183
185
|
// debug clicks for WebXR
|
|
184
186
|
if (debug) {
|
|
185
187
|
const pos = this.gameObject.worldPosition;
|
|
@@ -238,9 +240,19 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
238
240
|
|
|
239
241
|
onEnable() {
|
|
240
242
|
super.onEnable();
|
|
243
|
+
this.context.accessibility.updateElement(this, {
|
|
244
|
+
role: "button",
|
|
245
|
+
label: this.gameObject.name + " button",
|
|
246
|
+
hidden: false
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
onDisable() {
|
|
250
|
+
super.onDisable();
|
|
251
|
+
this.context.accessibility.updateElement(this, { hidden: true })
|
|
241
252
|
}
|
|
242
253
|
|
|
243
254
|
onDestroy(): void {
|
|
255
|
+
this.context.accessibility.removeElement(this);
|
|
244
256
|
if (this._isHovered) this.context.input.unsetCursor("pointer");
|
|
245
257
|
}
|
|
246
258
|
|
|
@@ -102,6 +102,7 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
|
|
|
102
102
|
this._text = val;
|
|
103
103
|
this.feedText(this.text, this.supportRichText);
|
|
104
104
|
this.markDirty();
|
|
105
|
+
this.context.accessibility.updateElement(this, { label: this.text });
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
|
|
@@ -238,6 +239,13 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
|
|
|
238
239
|
|
|
239
240
|
onEnable(): void {
|
|
240
241
|
super.onEnable();
|
|
242
|
+
|
|
243
|
+
this.context.accessibility.updateElement(this, {
|
|
244
|
+
role: "text",
|
|
245
|
+
label: this.text,
|
|
246
|
+
hidden: false
|
|
247
|
+
});
|
|
248
|
+
|
|
241
249
|
this._didHandleTextRenderOnTop = false;
|
|
242
250
|
if (this.uiObject) {
|
|
243
251
|
// @ts-ignore
|
|
@@ -261,6 +269,11 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
|
|
|
261
269
|
onDisable(): void {
|
|
262
270
|
super.onDisable();
|
|
263
271
|
this.canvas?.unregisterEventReceiver(this);
|
|
272
|
+
this.context.accessibility.updateElement(this, { hidden: true });
|
|
273
|
+
}
|
|
274
|
+
onDestroy(): void {
|
|
275
|
+
super.onDestroy();
|
|
276
|
+
this.context.accessibility.removeElement(this);
|
|
264
277
|
}
|
|
265
278
|
|
|
266
279
|
private getAlignment(opts: ThreeMeshUIEveryOptions): ThreeMeshUIEveryOptions {
|