@avs/go 0.13.71758 → 0.13.71762

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avs/go",
3
- "version": "0.13.71758",
3
+ "version": "0.13.71762",
4
4
  "description": "AVS Go",
5
5
  "keywords": [
6
6
  "polymer",
@@ -27,7 +27,7 @@ import {Viewer, TransformInteractor, PanInteractor, ZoomRectangleInteractor, Pic
27
27
  import {AvsHttpMixin} from './avs-http-mixin.js';
28
28
  import {AvsStreamMixin} from './avs-stream-mixin.js';
29
29
  import {AvsDataSourceMixin} from './avs-data-source-mixin.js';
30
- import {LOGO, CAMERA, PLAY, COPY, RESET, DELETE} from './logo.js';
30
+ import {LOGO, PLAY, CAMERA, TIMELAPSE, HOME, DELETE, COPY, LINK} from './logo.js';
31
31
  import {Euler, Vector3, Quaternion} from 'three';
32
32
 
33
33
  /**
@@ -75,7 +75,7 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
75
75
  width:100%;
76
76
  height:100%;
77
77
  }
78
- #animationControls {
78
+ #motionCapture {
79
79
  display: none;
80
80
  position:absolute;
81
81
  top: 8px;
@@ -84,26 +84,28 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
84
84
  background-color: rgba(128, 128, 128, 0.8);
85
85
  font-size: 10pt;
86
86
  border-radius: 8px;
87
- background:var(--avs-animation-controls-background, rgba(80,80,80,0.75));
88
- color:var(--avs-animation-controls-color, #ffffff);
89
- font-family:var(--avs-animation-controls-font-family);
87
+ background:var(--avs-motion-capture-background, rgba(80,80,80,0.75));
88
+ color:var(--avs-motion-capture-color, #ffffff);
89
+ font-family:var(--avs-motion-capture-font-family);
90
90
  box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
91
+ user-select: none;
91
92
  }
92
- #animationControlsTitle {
93
- margin-bottom: 8px;
93
+ #motionCaptureTitle {
94
+ margin-bottom: 4px;
94
95
  font-weight: 700;
95
96
  }
96
97
  .btn {
97
98
  padding: 4px;
98
99
  border-radius: 4px;
99
- margin: 4px;
100
- background:var(--avs-animation-controls-button-background, white);
101
- color:var(--avs-animation-controls-button-color, black);
100
+ margin: 2px;
101
+ background:var(--avs-motion-capture-control-background, white);
102
+ color:var(--avs-motion-capture-control-color, black);
102
103
  display: inline-flex;
103
104
  align-items: center;
104
105
  box-shadow: 0 2px 2px #00000024,0 3px 1px -2px #0000001f,0 1px 5px #0003;
106
+ }
107
+ a.btn {
105
108
  cursor: pointer;
106
- user-select: none;
107
109
  }
108
110
  .btn.disabled {
109
111
  cursor: default;
@@ -112,28 +114,28 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
112
114
  background-color: darkgrey;
113
115
  color: grey;
114
116
  }
115
- #animationDelay {
116
- width: 30px;
117
- height: 29px;
118
- background:var(--avs-animation-controls-button-background, white);
119
- color:var(--avs-animation-controls-button-color, black);
120
- border-width: 0;
121
- border-radius: 4px;
122
- box-shadow: 0 2px 2px #00000024,0 3px 1px -2px #0000001f,0 1px 5px #0003;
123
- margin: 4px;
117
+ #motionCaptureSnapshotIcon, #motionCaptureDelayIcon {
118
+ height: 24px;
124
119
  }
125
- #animationDelay:disabled {
126
- pointer-events: none;
127
- box-shadow: none;
128
- background-color: darkgrey;
129
- color: grey;
120
+ #motionCaptureSnapshotLabel, #motionCaptureDelayLabel {
121
+ margin-left: 4px;
122
+ height: 14px;
130
123
  }
131
- #animationSnapshotIcon {
124
+ #motionCaptureDelayWheel {
125
+ display: flex;
126
+ flex-direction: column;
127
+ margin: 0 4px;
132
128
  height: 24px;
129
+ gap: 2px;
133
130
  }
134
- #animationSnapshotLabel {
135
- margin-left: 4px;
136
- height: 16px;
131
+ #motionCaptureDelayIncrease, #motionCaptureDelayDecrease {
132
+ height: 8px;
133
+ text-align: center;
134
+ font-weight: 700;
135
+ cursor: pointer;
136
+ }
137
+ #motionCaptureReset, #motionCaptureCopyData {
138
+ margin-left: 12px;
137
139
  }
138
140
  #sceneImage {
139
141
  width:100%;
@@ -161,7 +163,7 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
161
163
  font-weight:var(--avs-zoom-overlay-font-weight, bold);
162
164
  font-style:var(--avs-zoom-overlay-font-style);
163
165
  }
164
- #tooltip, #animationTooltip {
166
+ #tooltip, #motionCaptureTooltip, #motionCaptureAlert {
165
167
  position:absolute;
166
168
  opacity:0;
167
169
  transition:opacity ease 0.3s;
@@ -176,6 +178,11 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
176
178
  font-weight:var(--avs-tooltip-font-weight);
177
179
  font-style:var(--avs-tooltip-font-style);
178
180
  }
181
+ #motionCaptureAlert {
182
+ left: 50%;
183
+ top: 50%;
184
+ transform: translate(-50%, -50%);
185
+ }
179
186
  #spinnerDiv {
180
187
  position:absolute;
181
188
  left:var(--avs-spinner-left, 50%);
@@ -200,25 +207,30 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
200
207
  </style>
201
208
  <div id="container">
202
209
  <div id="dataVizDiv"></div>
203
- <div id="animationControls">
204
- <div id="animationControlsTitle">Animation Controls</div>
205
- <div style="display: flex; justify-content: center">
206
- <input type="number" disabled min="1" max="10" value="0" step="1" id="animationDelay" data-tooltip="Frame delay (seconds)">
207
- <a class="btn" id="animationSnapshot" data-tooltip="Take snapshot">
208
- <div id="animationSnapshotIcon"></div>
209
- <div id="animationSnapshotLabel">0</div>
210
+ <div id="motionCapture">
211
+ <div style="display: flex; justify-content: center" id="motionCaptureTitle">Motion Capture</div>
212
+ <div>
213
+ <a class="btn disabled" id="motionCapturePlay" data-tooltip="Play motion capture"></a>
214
+ <a class="btn" id="motionCaptureSnapshot" data-tooltip="Take snapshot">
215
+ <div id="motionCaptureSnapshotIcon"></div>
216
+ <div id="motionCaptureSnapshotLabel">0</div>
210
217
  </a>
211
- </div>
212
- <div style="display: flex; justify-content: center">
213
- <a class="btn disabled" id="animationPlay" data-tooltip="Play animation"></a>
214
- <a class="btn disabled" id="animationCopy" data-tooltip="Copy animation URL to clipboard"></a>
215
- </div>
216
- <div style="display: flex; justify-content: center">
217
- <a class="btn" id="animationReset" data-tooltip="Reset transform"></a>
218
- <a class="btn disabled" id="animationClear" data-tooltip="Clear animation"></a>
218
+ <div class="btn disabled" id="motionCaptureDelay" data-tooltip="Frame delay (seconds)">
219
+ <div id="motionCaptureDelayIcon"></div>
220
+ <div id="motionCaptureDelayLabel">0</div>
221
+ <div id="motionCaptureDelayWheel">
222
+ <a id="motionCaptureDelayIncrease">+</a>
223
+ <a id="motionCaptureDelayDecrease">-</a>
224
+ </div>
225
+ </div>
226
+ <a class="btn" id="motionCaptureReset" data-tooltip="Reset transform"></a>
227
+ <a class="btn disabled" id="motionCaptureClear" data-tooltip="Clear motion capture frame"></a>
228
+ <a class="btn disabled" id="motionCaptureCopyData" data-tooltip="Copy motion capture data to clipboard"></a>
229
+ <a class="btn disabled" id="motionCaptureCopyUrl" data-tooltip="Copy motion capture URL to clipboard"></a>
219
230
  </div>
220
231
  </div>
221
- <div id="animationTooltip"></div>
232
+ <div id="motionCaptureTooltip"></div>
233
+ <div id="motionCaptureAlert"></div>
222
234
  <div id="zoomOverlay"></div>
223
235
  <div id="spinnerDiv">
224
236
  <div id="spinner"></div>
@@ -506,11 +518,11 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
506
518
  observer: "_transformValueChanged"
507
519
  },
508
520
  /**
509
- * Transform animation encoded string.
521
+ * Motion capture data or URL.
510
522
  */
511
- transformAnimation: {
523
+ motionCapture: {
512
524
  type: String,
513
- observer: "_transformAnimationValueChanged"
525
+ observer: "_motionCaptureValueChanged"
514
526
  },
515
527
  /**
516
528
  * Enable the zoom rectangle interactor. Only available when `renderer` is `THREEJS`
@@ -577,11 +589,11 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
577
589
  observer: "_animatedGlyphsEnableChanged"
578
590
  },
579
591
  /**
580
- * Enable animation controls overlay. Only available when `renderer` is `THREEJS`
592
+ * Enable motion capture controls. Only available when `renderer` is `THREEJS`
581
593
  */
582
- animationControlsEnable: {
594
+ motionCaptureControlsEnable: {
583
595
  type: Boolean,
584
- observer: "_animationControlsEnableChanged"
596
+ observer: "_motionCaptureControlsEnableChanged"
585
597
  }
586
598
  }
587
599
  }
@@ -992,23 +1004,23 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
992
1004
  blendedG += (bgCol[1] * (1 - col[3]));
993
1005
  blendedB += (bgCol[2] * (1 - col[3]));
994
1006
  }
995
- this.$.animationControls.style.color = "var(--avs-animation-controls-color, rgb(" + blendedR + ", " + blendedG + ", " + blendedB + "))";
1007
+ this.$.motionCapture.style.color = "var(--avs-motion-capture-color, rgb(" + blendedR + ", " + blendedG + ", " + blendedB + "))";
996
1008
  this.$.zoomOverlay.style.color = "var(--avs-zoom-overlay-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
997
1009
  this.$.tooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
998
- this.$.animationTooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
1010
+ this.$.motionCaptureTooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
999
1011
  }
1000
1012
  if (json.sceneInfo.color) {
1001
1013
  var col = json.sceneInfo.color.match(/[0-9.]+/gi);
1002
- this.$.animationControls.style.background = "var(--avs-animation-controls-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.75))";
1014
+ this.$.motionCapture.style.background = "var(--avs-motion-capture-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.75))";
1003
1015
  this.$.zoomOverlay.style.background = "var(--avs-zoom-overlay-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.75))";
1004
1016
  this.$.tooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
1005
- this.$.animationTooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
1017
+ this.$.motionCaptureTooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
1006
1018
  }
1007
1019
  if (json.sceneInfo.fontFamily) {
1008
- this.$.animationControls.style.fontFamily = "var(--avs-animation-controls-font-family, " + json.sceneInfo.fontFamily + ")";
1020
+ this.$.motionCapture.style.fontFamily = "var(--avs-motion-capture-font-family, " + json.sceneInfo.fontFamily + ")";
1009
1021
  this.$.zoomOverlay.style.fontFamily = "var(--avs-zoom-overlay-font-family, " + json.sceneInfo.fontFamily + ")";
1010
1022
  this.$.tooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + json.sceneInfo.fontFamily + ")";
1011
- this.$.animationTooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + json.sceneInfo.fontFamily + ")";
1023
+ this.$.motionCaptureTooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + json.sceneInfo.fontFamily + ")";
1012
1024
  }
1013
1025
  }
1014
1026
 
@@ -1550,44 +1562,41 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1550
1562
  }
1551
1563
  });
1552
1564
 
1553
- this.$.animationSnapshotIcon.innerHTML = CAMERA;
1554
- this.$.animationPlay.innerHTML = PLAY;
1555
- this.$.animationCopy.innerHTML = COPY;
1556
- this.$.animationReset.innerHTML = RESET;
1557
- this.$.animationClear.innerHTML = DELETE;
1558
-
1559
- this.$.animationDelay.addEventListener('change', this._handleAnimationDelayChange.bind(this));
1560
- this.$.animationSnapshot.addEventListener('click', this._handleAnimationSnapshot.bind(this));
1561
- this.$.animationPlay.addEventListener('click', this.runAnimation.bind(this));
1562
- this.$.animationCopy.addEventListener('click', this._handleAnimationCopy.bind(this));
1563
- this.$.animationReset.addEventListener('click', this.resetTransform.bind(this));
1564
- this.$.animationClear.addEventListener('click', this._handleAnimationClear.bind(this));
1565
-
1566
- this.$.animationDelay.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1567
- this.$.animationSnapshot.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1568
- this.$.animationPlay.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1569
- this.$.animationCopy.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1570
- this.$.animationReset.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1571
- this.$.animationClear.addEventListener('pointermove', this._handlePointerEnterAnimationControl.bind(this));
1572
-
1573
- this.$.animationDelay.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1574
- this.$.animationSnapshot.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1575
- this.$.animationPlay.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1576
- this.$.animationCopy.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1577
- this.$.animationReset.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1578
- this.$.animationClear.addEventListener('pointerout', this._handlePointerLeaveAnimationControl.bind(this));
1579
-
1580
- this.animationTime = 0;
1581
- this.transformAnimationFrames ??= [];
1582
- if (this.transformAnimationFrames.length > 0) {
1583
- this.$.animationDelay.value = 2;
1584
- this.$.animationDelay.disabled = false;
1585
- this.$.animationSnapshotLabel.innerHTML = this.transformAnimationFrames.length;
1586
- this.$.animationPlay.classList.remove("disabled");
1587
- this.$.animationCopy.classList.remove("disabled");
1588
- this.$.animationClear.classList.remove("disabled");
1589
- this.animationTime = this.transformAnimationFrames[this.transformAnimationFrames.length - 1].time / 1000;
1590
- }
1565
+ this.$.motionCapturePlay.innerHTML = PLAY;
1566
+ this.$.motionCaptureSnapshotIcon.innerHTML = CAMERA;
1567
+ this.$.motionCaptureDelayIcon.innerHTML = TIMELAPSE;
1568
+ this.$.motionCaptureReset.innerHTML = HOME;
1569
+ this.$.motionCaptureClear.innerHTML = DELETE;
1570
+ this.$.motionCaptureCopyData.innerHTML = COPY;
1571
+ this.$.motionCaptureCopyUrl.innerHTML = LINK;
1572
+
1573
+ this.$.motionCapturePlay.addEventListener('click', this.runAnimation.bind(this));
1574
+ this.$.motionCaptureSnapshot.addEventListener('click', this._handleMotionCaptureSnapshot.bind(this));
1575
+ this.$.motionCaptureDelayIncrease.addEventListener('click', this._handleMotionCaptureDelayIncrease.bind(this));
1576
+ this.$.motionCaptureDelayDecrease.addEventListener('click', this._handleMotionCaptureDelayDecrease.bind(this));
1577
+ this.$.motionCaptureReset.addEventListener('click', this.resetTransform.bind(this));
1578
+ this.$.motionCaptureClear.addEventListener('click', this._handleMotionCaptureClear.bind(this));
1579
+ this.$.motionCaptureCopyData.addEventListener('click', this._handleMotionCaptureCopyData.bind(this));
1580
+ this.$.motionCaptureCopyUrl.addEventListener('click', this._handleMotionCaptureCopyUrl.bind(this));
1581
+
1582
+ this.$.motionCapturePlay.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1583
+ this.$.motionCaptureSnapshot.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1584
+ this.$.motionCaptureDelay.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1585
+ this.$.motionCaptureReset.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1586
+ this.$.motionCaptureClear.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1587
+ this.$.motionCaptureCopyData.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1588
+ this.$.motionCaptureCopyUrl.addEventListener('pointermove', this._handlePointerEnterMotionCaptureControl.bind(this));
1589
+
1590
+ this.$.motionCapturePlay.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1591
+ this.$.motionCaptureSnapshot.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1592
+ this.$.motionCaptureDelay.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1593
+ this.$.motionCaptureReset.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1594
+ this.$.motionCaptureClear.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1595
+ this.$.motionCaptureCopyData.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1596
+ this.$.motionCaptureCopyUrl.addEventListener('pointerout', this._handlePointerLeaveMotionCaptureControl.bind(this));
1597
+
1598
+ this.motionCaptureTime = 0;
1599
+ this.motionCaptureFrames ??= [];
1591
1600
 
1592
1601
  this._resetTimer();
1593
1602
 
@@ -1596,47 +1605,34 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1596
1605
  });
1597
1606
  }
1598
1607
 
1599
- _handlePointerEnterAnimationControl(e) {
1600
- if (!this.showAnimationTooltip) {
1608
+ _handlePointerEnterMotionCaptureControl(e) {
1609
+ if (!this.showMotionCaptureTooltip) {
1601
1610
  var adjustedCoords = this._getAdjustedCoords(e.clientX, e.clientY);
1602
1611
  var pos = this._calcTooltipPosition(adjustedCoords.x, adjustedCoords.y);
1603
- this.$.animationTooltip.style.left = pos.x + "px";
1604
- this.$.animationTooltip.style.top = pos.y + "px";
1605
- this.$.animationTooltip.style.opacity = 1;
1606
- this.$.animationTooltip.innerHTML = e.currentTarget.dataset.tooltip ?? e.currentTarget.id;
1607
- this.showAnimationTooltip = true;
1612
+ this.$.motionCaptureTooltip.style.left = pos.x + "px";
1613
+ this.$.motionCaptureTooltip.style.top = pos.y + "px";
1614
+ this.$.motionCaptureTooltip.style.opacity = 1;
1615
+ this.$.motionCaptureTooltip.innerHTML = e.currentTarget.dataset.tooltip ?? e.currentTarget.id;
1616
+ this.showMotionCaptureTooltip = true;
1608
1617
  }
1609
1618
  }
1610
1619
 
1611
- _handlePointerLeaveAnimationControl() {
1612
- this.$.animationTooltip.style.opacity = 0;
1613
- this.showAnimationTooltip = false;
1620
+ _handlePointerLeaveMotionCaptureControl() {
1621
+ this.$.motionCaptureTooltip.style.opacity = 0;
1622
+ this.showMotionCaptureTooltip = false;
1614
1623
  }
1615
1624
 
1616
1625
  _round2dp(n) {
1617
1626
  return Math.round((n + Number.EPSILON) * 100) / 100;
1618
1627
  }
1619
1628
 
1620
- _handleAnimationDelayChange() {
1621
- let delay = Number(this.$.animationDelay.value);
1622
- if (delay < 1) {
1623
- delay = 1;
1624
- this.$.animationDelay.value = delay;
1625
- }
1626
- if (delay > 10) {
1627
- delay = 10;
1628
- this.$.animationDelay.value = delay;
1629
- }
1630
- }
1631
-
1632
- _handleAnimationSnapshot() {
1629
+ _handleMotionCaptureSnapshot() {
1633
1630
  const transform = this._getTransformComponents();
1634
- const delay = Number(this.$.animationDelay.value);
1635
- if (this.transformAnimationFrames.length > 0) {
1636
- this.animationTime += delay;
1631
+ if (this.motionCaptureFrames.length > 0) {
1632
+ this.motionCaptureTime += this.motionCaptureDelay;
1637
1633
  }
1638
1634
  const frame = {
1639
- time: this.animationTime * 1000,
1635
+ time: this.motionCaptureTime * 1000,
1640
1636
  scale: this._round2dp(transform.scale),
1641
1637
  position: [this._round2dp(transform.position[0]),
1642
1638
  this._round2dp(transform.position[1]),
@@ -1646,39 +1642,139 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1646
1642
  this._round2dp(transform.rotation[2]),
1647
1643
  transform.rotation[3]]
1648
1644
  };
1649
- this.transformAnimationFrames.push(frame);
1645
+ this.motionCaptureFrames.push(frame);
1646
+
1647
+ if (this.motionCaptureFrames.length == 1) {
1648
+ this.$.motionCapturePlay.classList.remove("disabled");
1649
+ this.$.motionCaptureDelay.classList.remove("disabled");
1650
+ this.$.motionCaptureDelayLabel.innerText = "2";
1651
+ this.$.motionCaptureClear.classList.remove("disabled");
1652
+ this.$.motionCaptureCopyData.classList.remove("disabled");
1653
+ this.$.motionCaptureCopyUrl.classList.remove("disabled");
1654
+ this.motionCaptureDelay = 2;
1655
+ }
1656
+ this.$.motionCaptureSnapshotLabel.innerText = this.motionCaptureFrames.length;
1657
+ }
1650
1658
 
1651
- if (this.transformAnimationFrames.length == 1) {
1652
- this.$.animationDelay.value = 2;
1653
- this.$.animationDelay.disabled = false;
1654
- this.$.animationPlay.classList.remove("disabled");
1655
- this.$.animationCopy.classList.remove("disabled");
1656
- this.$.animationClear.classList.remove("disabled");
1659
+ _handleMotionCaptureDelayIncrease() {
1660
+ this.motionCaptureDelay++;
1661
+ if (this.motionCaptureDelay > 9) {
1662
+ this.motionCaptureDelay = 9;
1657
1663
  }
1658
- this.$.animationSnapshotLabel.innerHTML = this.transformAnimationFrames.length;
1664
+ this.$.motionCaptureDelayLabel.innerText = this.motionCaptureDelay;
1659
1665
  }
1660
1666
 
1661
- _handleAnimationClear() {
1662
- this.transformAnimationFrames.length = 0;
1663
- this.$.animationDelay.value = 0;
1664
- this.$.animationDelay.disabled = true;
1665
- this.$.animationSnapshotLabel.innerHTML = "0";
1666
- this.$.animationPlay.classList.add("disabled");
1667
- this.$.animationCopy.classList.add("disabled");
1668
- this.$.animationClear.classList.add("disabled");
1669
- this.animationTime = 0;
1667
+ _handleMotionCaptureDelayDecrease() {
1668
+ this.motionCaptureDelay--;
1669
+ if (this.motionCaptureDelay < 1) {
1670
+ this.motionCaptureDelay = 1;
1671
+ }
1672
+ this.$.motionCaptureDelayLabel.innerText = this.motionCaptureDelay;
1670
1673
  }
1671
1674
 
1672
- _handleAnimationCopy() {
1673
- const json = JSON.stringify(this.transformAnimationFrames);
1674
- const encoded = btoa(json);
1675
+ _handleMotionCaptureCopyData() {
1676
+ // Convert to JSON and copy to clipboard
1677
+ const data = JSON.stringify(this.motionCaptureFrames);
1678
+ navigator.clipboard.writeText(data);
1675
1679
 
1676
- /**
1677
- * A transform animation share event occurred.
1678
- * @event avs-transform-animation-share
1679
- */
1680
+ // Show alert
1681
+ this.$.motionCaptureAlert.innerText = "Motion capture data copied to clipboard";
1682
+ this.$.motionCaptureAlert.style.opacity = 1;
1683
+ setTimeout(function () {
1684
+ this.$.motionCaptureAlert.style.opacity = 0;
1685
+ }.bind(this), 2000);
1686
+ }
1687
+
1688
+ async _handleMotionCaptureCopyUrl() {
1689
+ // Convert to JSON, compress and base64url encode
1690
+ const json = JSON.stringify(this.motionCaptureFrames);
1691
+ const compressed = await this._compress(json);
1692
+ const encoded = compressed.toBase64().replace('/', '_').replace('+', '-');
1693
+
1694
+ // Create URL and copy to clipboard
1695
+ const url = window.location.origin + window.location.pathname + "?motionCapture=" + encoded;
1696
+ navigator.clipboard.writeText(url);
1680
1697
 
1681
- this.dispatchEvent(new CustomEvent('avs-transform-animation-share', { detail: encoded }));
1698
+ // Show alert
1699
+ this.$.motionCaptureAlert.innerText = "Motion capture URL copied to clipboard";
1700
+ this.$.motionCaptureAlert.style.opacity = 1;
1701
+ setTimeout(function () {
1702
+ this.$.motionCaptureAlert.style.opacity = 0;
1703
+ }.bind(this), 2000);
1704
+ }
1705
+
1706
+ /**
1707
+ * Convert a string to its UTF-8 bytes and compress it.
1708
+ *
1709
+ * @param {string} str
1710
+ * @returns {Promise<Uint8Array>}
1711
+ */
1712
+ async _compress(str) {
1713
+ // Convert the string to a byte stream.
1714
+ const stream = new Blob([str]).stream();
1715
+
1716
+ // Create a compressed stream.
1717
+ const compressedStream = stream.pipeThrough(
1718
+ new CompressionStream("gzip")
1719
+ );
1720
+
1721
+ // Read all the bytes from this stream.
1722
+ const chunks = [];
1723
+ for await (const chunk of compressedStream) {
1724
+ chunks.push(chunk);
1725
+ }
1726
+ return this._concatUint8Arrays(chunks);
1727
+ }
1728
+
1729
+ /**
1730
+ * Decompress bytes into a UTF-8 string.
1731
+ *
1732
+ * @param {Uint8Array} compressedBytes
1733
+ * @returns {Promise<string>}
1734
+ */
1735
+ async _decompress(compressedBytes) {
1736
+ // Convert the bytes to a stream.
1737
+ const stream = new Blob([compressedBytes]).stream();
1738
+
1739
+ // Create a decompressed stream.
1740
+ const decompressedStream = stream.pipeThrough(
1741
+ new DecompressionStream("gzip")
1742
+ );
1743
+
1744
+ // Read all the bytes from this stream.
1745
+ const chunks = [];
1746
+ for await (const chunk of decompressedStream) {
1747
+ chunks.push(chunk);
1748
+ }
1749
+ const stringBytes = await this._concatUint8Arrays(chunks);
1750
+
1751
+ // Convert the bytes to a string.
1752
+ return new TextDecoder().decode(stringBytes);
1753
+ }
1754
+
1755
+ /**
1756
+ * Combine multiple Uint8Arrays into one.
1757
+ *
1758
+ * @param {ReadonlyArray<Uint8Array>} uint8arrays
1759
+ * @returns {Promise<Uint8Array>}
1760
+ */
1761
+ async _concatUint8Arrays(uint8arrays) {
1762
+ const blob = new Blob(uint8arrays);
1763
+ const buffer = await blob.arrayBuffer();
1764
+ return new Uint8Array(buffer);
1765
+ }
1766
+
1767
+ _handleMotionCaptureClear() {
1768
+ this.motionCaptureFrames.length = 0;
1769
+ this.$.motionCapturePlay.classList.add("disabled");
1770
+ this.$.motionCaptureSnapshotLabel.innerText = "0";
1771
+ this.$.motionCaptureDelay.classList.add("disabled");
1772
+ this.$.motionCaptureDelayLabel.innerText = "0";
1773
+ this.$.motionCaptureClear.classList.add("disabled");
1774
+ this.$.motionCaptureCopyData.classList.add("disabled");
1775
+ this.$.motionCaptureCopyUrl.classList.add("disabled");
1776
+ this.motionCaptureDelay = 0;
1777
+ this.motionCaptureTime = 0;
1682
1778
  }
1683
1779
 
1684
1780
  _updatePixelRatio(change) {
@@ -1690,14 +1786,14 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1690
1786
  }
1691
1787
 
1692
1788
  /**
1693
- * Change in 'animation-controls-enable' property.
1789
+ * Change in 'motion-capture-controls-enable' property.
1694
1790
  */
1695
- _animationControlsEnableChanged(newValue, oldValue) {
1791
+ _motionCaptureControlsEnableChanged(newValue, oldValue) {
1696
1792
  if (newValue) {
1697
- this.$.animationControls.style.display = "block";
1793
+ this.$.motionCapture.style.display = "block";
1698
1794
  }
1699
1795
  else {
1700
- this.$.animationControls.style.display = "none";
1796
+ this.$.motionCapture.style.display = "none";
1701
1797
  }
1702
1798
  }
1703
1799
 
@@ -1860,7 +1956,7 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1860
1956
  "legendTitle": "--avs-legend-title-animations",
1861
1957
  "glyph": "--avs-glyph-animations"
1862
1958
  });
1863
- styleMap.transform = this.transformAnimationFrames.length > 0 ? JSON.stringify(this.transformAnimationFrames) : null;
1959
+ styleMap.transform = this.motionCaptureFrames.length > 0 ? JSON.stringify(this.motionCaptureFrames) : null;
1864
1960
 
1865
1961
  this.animator.setStyleMap(styleMap);
1866
1962
  this.threeViewer.runAnimation();
@@ -1910,12 +2006,47 @@ export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin
1910
2006
  }
1911
2007
 
1912
2008
  /**
1913
- * Change in 'transform-animation' property.
2009
+ * Change in 'motion-capture' property.
1914
2010
  */
1915
- _transformAnimationValueChanged(newValue, oldValue) {
2011
+ async _motionCaptureValueChanged(newValue, oldValue) {
1916
2012
  if (newValue) {
1917
- const decoded = atob(newValue);
1918
- this.transformAnimationFrames = JSON.parse(decoded);
2013
+ // Try parsing JSON first
2014
+ try {
2015
+ this.motionCaptureFrames = JSON.parse(newValue);
2016
+ }
2017
+ catch {
2018
+ // Decode from base64url, decompress and parse JSON
2019
+ const decoded = Uint8Array.fromBase64(newValue.replaceAll('_', '/').replaceAll('-', '+'));
2020
+ const decompressed = await this._decompress(decoded);
2021
+ this.motionCaptureFrames = JSON.parse(decompressed);
2022
+ }
2023
+
2024
+ if (!this.motionCaptureFrames) {
2025
+ this.motionCaptureFrames = [];
2026
+ }
2027
+
2028
+ if (this.motionCaptureFrames.length > 0) {
2029
+ this.$.motionCapturePlay.classList.remove("disabled");
2030
+ this.$.motionCaptureSnapshotLabel.innerText = this.motionCaptureFrames.length;
2031
+ this.$.motionCaptureDelay.classList.remove("disabled");
2032
+ this.$.motionCaptureDelayLabel.innerText = "2";
2033
+ this.$.motionCaptureClear.classList.remove("disabled");
2034
+ this.$.motionCaptureCopyData.classList.remove("disabled");
2035
+ this.$.motionCaptureCopyUrl.classList.remove("disabled");
2036
+ this.motionCaptureDelay = 2;
2037
+ this.motionCaptureTime = this.motionCaptureFrames[this.motionCaptureFrames.length - 1].time / 1000;
2038
+ }
2039
+ else {
2040
+ this.$.motionCapturePlay.classList.add("disabled");
2041
+ this.$.motionCaptureSnapshotLabel.innerText = "0";
2042
+ this.$.motionCaptureDelay.classList.add("disabled");
2043
+ this.$.motionCaptureDelayLabel.innerText = "0";
2044
+ this.$.motionCaptureClear.classList.add("disabled");
2045
+ this.$.motionCaptureCopyData.classList.add("disabled");
2046
+ this.$.motionCaptureCopyUrl.classList.add("disabled");
2047
+ this.motionCaptureDelay = 0;
2048
+ this.motionCaptureTime = 0;
2049
+ }
1919
2050
  }
1920
2051
  }
1921
2052
 
package/src/constants.js CHANGED
@@ -18,4 +18,4 @@
18
18
  * Advanced Visual Systems Inc. (http://www.avs.com)
19
19
  */
20
20
 
21
- export var VERSION = '0.13.71758';
21
+ export var VERSION = '0.13.71762';