@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/dist/avs-go.min.js +1 -1
- package/package.json +1 -1
- package/src/avs-go-dataviz.js +288 -157
- package/src/constants.js +1 -1
- package/src/logo.js +4 -2
package/package.json
CHANGED
package/src/avs-go-dataviz.js
CHANGED
|
@@ -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,
|
|
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
|
-
#
|
|
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-
|
|
88
|
-
color:var(--avs-
|
|
89
|
-
font-family:var(--avs-
|
|
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
|
-
#
|
|
93
|
-
margin-bottom:
|
|
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:
|
|
100
|
-
background:var(--avs-
|
|
101
|
-
color:var(--avs-
|
|
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
|
-
#
|
|
116
|
-
|
|
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
|
-
#
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
background-color: darkgrey;
|
|
129
|
-
color: grey;
|
|
120
|
+
#motionCaptureSnapshotLabel, #motionCaptureDelayLabel {
|
|
121
|
+
margin-left: 4px;
|
|
122
|
+
height: 14px;
|
|
130
123
|
}
|
|
131
|
-
#
|
|
124
|
+
#motionCaptureDelayWheel {
|
|
125
|
+
display: flex;
|
|
126
|
+
flex-direction: column;
|
|
127
|
+
margin: 0 4px;
|
|
132
128
|
height: 24px;
|
|
129
|
+
gap: 2px;
|
|
133
130
|
}
|
|
134
|
-
#
|
|
135
|
-
|
|
136
|
-
|
|
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, #
|
|
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="
|
|
204
|
-
<div id="
|
|
205
|
-
<div
|
|
206
|
-
<
|
|
207
|
-
<a class="btn" id="
|
|
208
|
-
<div id="
|
|
209
|
-
<div id="
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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="
|
|
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
|
-
*
|
|
521
|
+
* Motion capture data or URL.
|
|
510
522
|
*/
|
|
511
|
-
|
|
523
|
+
motionCapture: {
|
|
512
524
|
type: String,
|
|
513
|
-
observer: "
|
|
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
|
|
592
|
+
* Enable motion capture controls. Only available when `renderer` is `THREEJS`
|
|
581
593
|
*/
|
|
582
|
-
|
|
594
|
+
motionCaptureControlsEnable: {
|
|
583
595
|
type: Boolean,
|
|
584
|
-
observer: "
|
|
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.$.
|
|
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.$.
|
|
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.$.
|
|
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.$.
|
|
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.$.
|
|
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.$.
|
|
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.$.
|
|
1554
|
-
this.$.
|
|
1555
|
-
this.$.
|
|
1556
|
-
this.$.
|
|
1557
|
-
this.$.
|
|
1558
|
-
|
|
1559
|
-
this.$.
|
|
1560
|
-
|
|
1561
|
-
this.$.
|
|
1562
|
-
this.$.
|
|
1563
|
-
this.$.
|
|
1564
|
-
this.$.
|
|
1565
|
-
|
|
1566
|
-
this.$.
|
|
1567
|
-
this.$.
|
|
1568
|
-
this.$.
|
|
1569
|
-
|
|
1570
|
-
this.$.
|
|
1571
|
-
this.$.
|
|
1572
|
-
|
|
1573
|
-
this.$.
|
|
1574
|
-
this.$.
|
|
1575
|
-
this.$.
|
|
1576
|
-
this.$.
|
|
1577
|
-
|
|
1578
|
-
this.$.
|
|
1579
|
-
|
|
1580
|
-
this.
|
|
1581
|
-
this.
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
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
|
-
|
|
1600
|
-
if (!this.
|
|
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.$.
|
|
1604
|
-
this.$.
|
|
1605
|
-
this.$.
|
|
1606
|
-
this.$.
|
|
1607
|
-
this.
|
|
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
|
-
|
|
1612
|
-
this.$.
|
|
1613
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
1635
|
-
|
|
1636
|
-
this.animationTime += delay;
|
|
1631
|
+
if (this.motionCaptureFrames.length > 0) {
|
|
1632
|
+
this.motionCaptureTime += this.motionCaptureDelay;
|
|
1637
1633
|
}
|
|
1638
1634
|
const frame = {
|
|
1639
|
-
time: this.
|
|
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.
|
|
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
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
this
|
|
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.$.
|
|
1664
|
+
this.$.motionCaptureDelayLabel.innerText = this.motionCaptureDelay;
|
|
1659
1665
|
}
|
|
1660
1666
|
|
|
1661
|
-
|
|
1662
|
-
this.
|
|
1663
|
-
this
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
this.$.
|
|
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
|
-
|
|
1673
|
-
|
|
1674
|
-
const
|
|
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
|
-
|
|
1678
|
-
|
|
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
|
-
|
|
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 '
|
|
1789
|
+
* Change in 'motion-capture-controls-enable' property.
|
|
1694
1790
|
*/
|
|
1695
|
-
|
|
1791
|
+
_motionCaptureControlsEnableChanged(newValue, oldValue) {
|
|
1696
1792
|
if (newValue) {
|
|
1697
|
-
this.$.
|
|
1793
|
+
this.$.motionCapture.style.display = "block";
|
|
1698
1794
|
}
|
|
1699
1795
|
else {
|
|
1700
|
-
this.$.
|
|
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.
|
|
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 '
|
|
2009
|
+
* Change in 'motion-capture' property.
|
|
1914
2010
|
*/
|
|
1915
|
-
|
|
2011
|
+
async _motionCaptureValueChanged(newValue, oldValue) {
|
|
1916
2012
|
if (newValue) {
|
|
1917
|
-
|
|
1918
|
-
|
|
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