@abi-software/scaffoldvuer 0.1.4 → 0.1.5-1.beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +12 -0
- package/README.md +88 -2
- package/babel.config.js +9 -0
- package/dist/scaffoldvuer.common.js +3365 -74193
- package/dist/scaffoldvuer.common.js.map +1 -1
- package/dist/scaffoldvuer.css +1 -91
- package/dist/scaffoldvuer.umd.js +3371 -74199
- package/dist/scaffoldvuer.umd.js.map +1 -1
- package/dist/scaffoldvuer.umd.min.js +1 -195
- package/dist/scaffoldvuer.umd.min.js.map +1 -1
- package/package-lock.json +12550 -4183
- package/package.json +34 -10
- package/src/App.vue +366 -9
- package/src/assets/_variables.scss +43 -0
- package/src/assets/styles.scss +7 -0
- package/src/components/ModelsInformation.js +35 -0
- package/src/components/ModelsTable.vue +113 -0
- package/src/components/OpacityControls.vue +222 -0
- package/src/components/ScaffoldVuer.md +44 -0
- package/src/components/ScaffoldVuer.vue +1429 -54
- package/src/components/TraditionalControls.vue +556 -0
- package/src/components/index.js +3 -11
- package/src/credential.json +12 -0
- package/src/main.js +6 -0
- package/styleguide.config.js +22 -0
- package/vue.config.js +36 -9
|
@@ -1,94 +1,1469 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<div
|
|
3
|
+
ref="scaffoldContainer"
|
|
4
|
+
v-loading="loading"
|
|
5
|
+
class="scaffold-container"
|
|
6
|
+
element-loading-text="Loading..."
|
|
7
|
+
element-loading-spinner="el-icon-loading"
|
|
8
|
+
element-loading-background="rgba(0, 0, 0, 0.3)"
|
|
9
|
+
>
|
|
10
|
+
<SvgSpriteColor />
|
|
11
|
+
<div
|
|
12
|
+
id="organsDisplayArea"
|
|
13
|
+
ref="display"
|
|
14
|
+
tabindex="-1"
|
|
15
|
+
style="height:100%;width:100%;"
|
|
16
|
+
@keydown.66="backgroundChangeCallback"
|
|
17
|
+
/>
|
|
18
|
+
<div v-show="displayUI && !isTransitioning">
|
|
19
|
+
<el-popover
|
|
20
|
+
v-if="displayWarning"
|
|
21
|
+
ref="warningPopover"
|
|
22
|
+
v-model="hoverVisabilities[6].value"
|
|
23
|
+
:content="warningMessage"
|
|
24
|
+
placement="right"
|
|
25
|
+
:append-to-body="false"
|
|
26
|
+
trigger="manual"
|
|
27
|
+
popper-class="warning-popper right-popper non-selectable"
|
|
28
|
+
/>
|
|
29
|
+
<i
|
|
30
|
+
v-if="displayWarning"
|
|
31
|
+
v-popover:warningPopover
|
|
32
|
+
class="el-icon-warning warning-icon"
|
|
33
|
+
@mouseover="showToolitip(6)"
|
|
34
|
+
@mouseout="hideToolitip(6)"
|
|
35
|
+
>
|
|
36
|
+
<span class="warning-text">Beta</span>
|
|
37
|
+
</i>
|
|
38
|
+
<el-popover
|
|
39
|
+
ref="checkBoxPopover"
|
|
40
|
+
v-model="hoverVisabilities[5].value"
|
|
41
|
+
content="Change region visibility"
|
|
42
|
+
placement="right"
|
|
43
|
+
:append-to-body="false"
|
|
44
|
+
trigger="manual"
|
|
45
|
+
popper-class="scaffold-popper right-popper non-selectable"
|
|
46
|
+
/>
|
|
47
|
+
<TraditionalControls
|
|
48
|
+
ref="traditionalControl"
|
|
49
|
+
v-popover:checkBoxPopover
|
|
50
|
+
:help-mode="helpMode"
|
|
51
|
+
:module="$module"
|
|
52
|
+
:show-colour-picker="showColourPicker"
|
|
53
|
+
@object-selected="objectSelected"
|
|
54
|
+
@object-hovered="objectHovered"
|
|
55
|
+
@drawer-toggled="drawerToggled"
|
|
56
|
+
/>
|
|
57
|
+
<div class="opacity-box">
|
|
58
|
+
<OpacityControls ref="opacityControl" />
|
|
5
59
|
</div>
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
60
|
+
<el-popover
|
|
61
|
+
v-if="sceneData.timeVarying"
|
|
62
|
+
ref="sliderPopover"
|
|
63
|
+
v-model="hoverVisabilities[4].value"
|
|
64
|
+
content="Move the slider to animate the region"
|
|
65
|
+
placement="top"
|
|
66
|
+
:append-to-body="false"
|
|
67
|
+
trigger="manual"
|
|
68
|
+
popper-class="scaffold-popper top-popper non-selectable"
|
|
69
|
+
/>
|
|
70
|
+
<div
|
|
71
|
+
v-if="sceneData.timeVarying"
|
|
72
|
+
v-popover:sliderPopover
|
|
73
|
+
class="time-slider-container"
|
|
74
|
+
:class="[ minimisedSlider ? 'minimised' : '', sliderPosition]"
|
|
75
|
+
>
|
|
76
|
+
<el-tabs type="card">
|
|
77
|
+
<el-tab-pane label="Animate scaffold">
|
|
78
|
+
<el-row class="tab-content">
|
|
79
|
+
<SvgIcon
|
|
80
|
+
v-if="isPlaying"
|
|
81
|
+
icon="pause"
|
|
82
|
+
class="icon-button video-button"
|
|
83
|
+
@click.native="play(false)"
|
|
84
|
+
/>
|
|
85
|
+
<SvgIcon
|
|
86
|
+
v-else
|
|
87
|
+
icon="play"
|
|
88
|
+
class="video-button icon-button"
|
|
89
|
+
@click.native="play(true)"
|
|
90
|
+
/>
|
|
91
|
+
<el-slider
|
|
92
|
+
:min="0"
|
|
93
|
+
:max="timeMax"
|
|
94
|
+
:value="sceneData.currentTime / 100 * timeMax"
|
|
95
|
+
:step="0.1"
|
|
96
|
+
tooltip-class="time-slider-tooltip"
|
|
97
|
+
class="slider"
|
|
98
|
+
:format-tooltip="formatTooltip"
|
|
99
|
+
:marks="timeStamps"
|
|
100
|
+
@input="timeChange($event)"
|
|
101
|
+
/>
|
|
102
|
+
</el-row>
|
|
103
|
+
</el-tab-pane>
|
|
104
|
+
<el-tab-pane label="Animation data">
|
|
105
|
+
<el-row class="tab-content">
|
|
106
|
+
<div class="animation-data">
|
|
107
|
+
Original duration:
|
|
108
|
+
<div class="purple">
|
|
109
|
+
{{ orginalDuration }}
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="animation-data">
|
|
113
|
+
Animation duration:
|
|
114
|
+
<div class="purple">
|
|
115
|
+
{{ animateDuration }}
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
<div class="animation-data">
|
|
119
|
+
Playback speed
|
|
120
|
+
<el-select
|
|
121
|
+
:popper-append-to-body="true"
|
|
122
|
+
:value="currentSpeed"
|
|
123
|
+
placeholder="Select"
|
|
124
|
+
class="select-box"
|
|
125
|
+
popper-class="scaffold_viewer_dropdown"
|
|
126
|
+
@change="speedChanged($event)"
|
|
127
|
+
>
|
|
128
|
+
<el-option
|
|
129
|
+
v-for="item in playSpeed"
|
|
130
|
+
:key="item.value"
|
|
131
|
+
:label="item.label"
|
|
132
|
+
:value="item.value"
|
|
133
|
+
/>
|
|
134
|
+
</el-select>
|
|
135
|
+
</div>
|
|
136
|
+
</el-row>
|
|
137
|
+
</el-tab-pane>
|
|
138
|
+
</el-tabs>
|
|
14
139
|
</div>
|
|
15
|
-
<
|
|
140
|
+
<div class="bottom-right-control">
|
|
141
|
+
<el-popover
|
|
142
|
+
v-model="hoverVisabilities[0].value"
|
|
143
|
+
content="Zoom in"
|
|
144
|
+
placement="left"
|
|
145
|
+
:append-to-body="false"
|
|
146
|
+
trigger="manual"
|
|
147
|
+
popper-class="scaffold-popper left-popper non-selectable"
|
|
148
|
+
>
|
|
149
|
+
<SvgIcon
|
|
150
|
+
slot="reference"
|
|
151
|
+
icon="zoomIn"
|
|
152
|
+
class="icon-button zoomIn"
|
|
153
|
+
@click.native="zoomIn()"
|
|
154
|
+
@mouseover.native="showToolitip(0)"
|
|
155
|
+
@mouseout.native="hideToolitip(0)"
|
|
156
|
+
/>
|
|
157
|
+
</el-popover>
|
|
158
|
+
<el-popover
|
|
159
|
+
v-model="hoverVisabilities[1].value"
|
|
160
|
+
content="Zoom out"
|
|
161
|
+
placement="top-end"
|
|
162
|
+
:append-to-body="false"
|
|
163
|
+
trigger="manual"
|
|
164
|
+
popper-class="scaffold-popper popper-zoomout non-selectable"
|
|
165
|
+
>
|
|
166
|
+
<SvgIcon
|
|
167
|
+
slot="reference"
|
|
168
|
+
icon="zoomOut"
|
|
169
|
+
class="icon-button zoomOut"
|
|
170
|
+
@click.native="zoomOut()"
|
|
171
|
+
@mouseover.native="showToolitip(1)"
|
|
172
|
+
@mouseout.native="hideToolitip(1)"
|
|
173
|
+
/>
|
|
174
|
+
</el-popover>
|
|
175
|
+
<el-popover
|
|
176
|
+
v-model="hoverVisabilities[2].value"
|
|
177
|
+
placement="top"
|
|
178
|
+
:append-to-body="false"
|
|
179
|
+
trigger="manual"
|
|
180
|
+
popper-class="scaffold-popper non-selectable"
|
|
181
|
+
>
|
|
182
|
+
<div>
|
|
183
|
+
Fit to
|
|
184
|
+
<br>
|
|
185
|
+
window
|
|
186
|
+
</div>
|
|
187
|
+
<SvgIcon
|
|
188
|
+
slot="reference"
|
|
189
|
+
icon="fitWindow"
|
|
190
|
+
class="icon-button fitWindow"
|
|
191
|
+
@click.native="fitWindow()"
|
|
192
|
+
@mouseover.native="showToolitip(2)"
|
|
193
|
+
@mouseout.native="hideToolitip(2)"
|
|
194
|
+
/>
|
|
195
|
+
</el-popover>
|
|
196
|
+
</div>
|
|
197
|
+
<el-popover
|
|
198
|
+
ref="backgroundPopover"
|
|
199
|
+
placement="top-start"
|
|
200
|
+
width="128"
|
|
201
|
+
:append-to-body="false"
|
|
202
|
+
trigger="click"
|
|
203
|
+
popper-class="background-popper non-selectable"
|
|
204
|
+
>
|
|
205
|
+
<el-row class="backgroundText">
|
|
206
|
+
Change background
|
|
207
|
+
</el-row>
|
|
208
|
+
<el-row class="backgroundChooser">
|
|
209
|
+
<div
|
|
210
|
+
v-for="item in availableBackground"
|
|
211
|
+
:key="item"
|
|
212
|
+
:class="['backgroundChoice', item, item == currentBackground ? 'active' :'']"
|
|
213
|
+
@click="backgroundChangeCallback(item)"
|
|
214
|
+
/>
|
|
215
|
+
</el-row>
|
|
216
|
+
</el-popover>
|
|
217
|
+
<el-popover
|
|
218
|
+
v-model="hoverVisabilities[3].value"
|
|
219
|
+
content="Change background color"
|
|
220
|
+
placement="right"
|
|
221
|
+
:append-to-body="false"
|
|
222
|
+
trigger="manual"
|
|
223
|
+
popper-class="scaffold-popper right-popper non-selectable"
|
|
224
|
+
>
|
|
225
|
+
<SvgIcon
|
|
226
|
+
slot="reference"
|
|
227
|
+
v-popover:backgroundPopover
|
|
228
|
+
icon="changeBckgd"
|
|
229
|
+
class="icon-button background-colour"
|
|
230
|
+
:class="{ open: drawerOpen, close: !drawerOpen }"
|
|
231
|
+
@mouseover.native="showToolitip(3)"
|
|
232
|
+
@mouseout.native="hideToolitip(3)"
|
|
233
|
+
/>
|
|
234
|
+
</el-popover>
|
|
16
235
|
</div>
|
|
17
236
|
</div>
|
|
18
237
|
</template>
|
|
19
238
|
|
|
20
239
|
<script>
|
|
21
240
|
/* eslint-disable no-alert, no-console */
|
|
22
|
-
|
|
23
|
-
|
|
241
|
+
import Vue from "vue";
|
|
242
|
+
import OpacityControls from "./OpacityControls";
|
|
243
|
+
import TraditionalControls from "./TraditionalControls";
|
|
244
|
+
import { SvgIcon, SvgSpriteColor } from "@abi-software/svg-sprite";
|
|
24
245
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
246
|
+
import {
|
|
247
|
+
Col,
|
|
248
|
+
Loading,
|
|
249
|
+
Option,
|
|
250
|
+
Popover,
|
|
251
|
+
Row,
|
|
252
|
+
Select,
|
|
253
|
+
Slider,
|
|
254
|
+
TabPane,
|
|
255
|
+
Tabs
|
|
256
|
+
} from "element-ui";
|
|
257
|
+
import lang from "element-ui/lib/locale/lang/en";
|
|
258
|
+
import locale from "element-ui/lib/locale";
|
|
259
|
+
|
|
260
|
+
locale.use(lang);
|
|
261
|
+
Vue.use(Col);
|
|
262
|
+
Vue.use(Loading.directive);
|
|
263
|
+
Vue.use(Option);
|
|
264
|
+
Vue.use(Popover);
|
|
265
|
+
Vue.use(Row);
|
|
266
|
+
Vue.use(Select);
|
|
267
|
+
Vue.use(Slider);
|
|
268
|
+
Vue.use(TabPane);
|
|
269
|
+
Vue.use(Tabs);
|
|
33
270
|
|
|
271
|
+
const OrgansViewer = require("physiomeportal/src/modules/organsRenderer")
|
|
272
|
+
.OrgansViewer;
|
|
273
|
+
const EventNotifier = require("physiomeportal/src/utilities/eventNotifier")
|
|
274
|
+
.EventNotifier;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* A vue component of the scaffold viewer.
|
|
278
|
+
*
|
|
279
|
+
* @requires ./OpacityControls.vue
|
|
280
|
+
* @requires ./TraditionalControls.vue
|
|
281
|
+
*/
|
|
34
282
|
export default {
|
|
35
|
-
name:
|
|
283
|
+
name: "ScaffoldVuer",
|
|
284
|
+
components: {
|
|
285
|
+
OpacityControls,
|
|
286
|
+
SvgIcon,
|
|
287
|
+
SvgSpriteColor,
|
|
288
|
+
TraditionalControls
|
|
289
|
+
},
|
|
290
|
+
props: {
|
|
291
|
+
/**
|
|
292
|
+
* URL of the zincjs metadata. This value will be ignored if a valid
|
|
293
|
+
* state prop is also provided.
|
|
294
|
+
* If the url needs to be updated with state present, please use
|
|
295
|
+
* the setURL method.
|
|
296
|
+
*/
|
|
297
|
+
url: {
|
|
298
|
+
type: String,
|
|
299
|
+
default: ""
|
|
300
|
+
},
|
|
301
|
+
/**
|
|
302
|
+
* Show the colour control of set to true.
|
|
303
|
+
*/
|
|
304
|
+
showColourPicker: {
|
|
305
|
+
type: Boolean,
|
|
306
|
+
default: false
|
|
307
|
+
},
|
|
308
|
+
/**
|
|
309
|
+
* Flag to show/hide the UI.
|
|
310
|
+
*/
|
|
311
|
+
displayUI: {
|
|
312
|
+
type: Boolean,
|
|
313
|
+
default: true
|
|
314
|
+
},
|
|
315
|
+
/**
|
|
316
|
+
* Display all graphics at start.
|
|
317
|
+
*
|
|
318
|
+
* This setting only works when traditional is set to false.
|
|
319
|
+
*/
|
|
320
|
+
displayAtStartUp: {
|
|
321
|
+
type: Boolean,
|
|
322
|
+
default: true
|
|
323
|
+
},
|
|
324
|
+
/**
|
|
325
|
+
* Use for toggling the help tooltips.
|
|
326
|
+
*/
|
|
327
|
+
helpMode: {
|
|
328
|
+
type: Boolean,
|
|
329
|
+
default: false
|
|
330
|
+
},
|
|
331
|
+
/**
|
|
332
|
+
* Use for show/display beta warning icon.
|
|
333
|
+
*/
|
|
334
|
+
displayWarning: {
|
|
335
|
+
type: Boolean,
|
|
336
|
+
default: true
|
|
337
|
+
},
|
|
338
|
+
/**
|
|
339
|
+
* Warning message for the hovered over text
|
|
340
|
+
* on the warning icon.
|
|
341
|
+
*/
|
|
342
|
+
warningMessage: {
|
|
343
|
+
type: String,
|
|
344
|
+
default: "Beta feature - under active development"
|
|
345
|
+
},
|
|
346
|
+
/**
|
|
347
|
+
* Show/hide pickable markers for regions.
|
|
348
|
+
*/
|
|
349
|
+
displayMarkers: {
|
|
350
|
+
type: Boolean,
|
|
351
|
+
default: true
|
|
352
|
+
},
|
|
353
|
+
/**
|
|
354
|
+
* Show/hide minimap.
|
|
355
|
+
*/
|
|
356
|
+
displayMinimap: {
|
|
357
|
+
type: Boolean,
|
|
358
|
+
default: false
|
|
359
|
+
},
|
|
360
|
+
/**
|
|
361
|
+
* Settings for minimap position, size and alignment.
|
|
362
|
+
*/
|
|
363
|
+
minimapSettings: {
|
|
364
|
+
type: Object,
|
|
365
|
+
default: function() {
|
|
366
|
+
return {
|
|
367
|
+
x_offset: 16,
|
|
368
|
+
y_offset: 16,
|
|
369
|
+
width: 128,
|
|
370
|
+
height: 128,
|
|
371
|
+
align: "top-right"
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
/**
|
|
376
|
+
* State containing state of the scaffold.
|
|
377
|
+
*/
|
|
378
|
+
state: {
|
|
379
|
+
type: Object,
|
|
380
|
+
default: undefined
|
|
381
|
+
},
|
|
382
|
+
/**
|
|
383
|
+
* Optional prop for the name of the region to focus on,
|
|
384
|
+
* this option is ignored if state or viewURL is also provided.
|
|
385
|
+
*/
|
|
386
|
+
region: {
|
|
387
|
+
type: String,
|
|
388
|
+
default: ""
|
|
389
|
+
},
|
|
390
|
+
/**
|
|
391
|
+
* Optional prop for an URL of containing information of a viewport.
|
|
392
|
+
* This option is ignored if state is also provided.
|
|
393
|
+
* It will use the provided URL as base if a relative parth is provided.
|
|
394
|
+
*/
|
|
395
|
+
viewURL: {
|
|
396
|
+
type: String,
|
|
397
|
+
default: ""
|
|
398
|
+
},
|
|
399
|
+
/**
|
|
400
|
+
* Settings for turning on/off rendering
|
|
401
|
+
*/
|
|
402
|
+
render: {
|
|
403
|
+
type: Boolean,
|
|
404
|
+
default: true
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
data: function() {
|
|
408
|
+
return {
|
|
409
|
+
sceneData: this.$module.sceneData,
|
|
410
|
+
isPlaying: false,
|
|
411
|
+
/**
|
|
412
|
+
* This is set when scene is transitioning.
|
|
413
|
+
*/
|
|
414
|
+
isTransitioning: false,
|
|
415
|
+
tooltipAppendToBody: false,
|
|
416
|
+
hoverVisabilities: [
|
|
417
|
+
{ value: false },
|
|
418
|
+
{ value: false },
|
|
419
|
+
{ value: false },
|
|
420
|
+
{ value: false },
|
|
421
|
+
{ value: false },
|
|
422
|
+
{ value: false },
|
|
423
|
+
{ value: false }
|
|
424
|
+
],
|
|
425
|
+
inHelp: false,
|
|
426
|
+
loading: false,
|
|
427
|
+
duration: 3000,
|
|
428
|
+
drawerOpen: true,
|
|
429
|
+
currentBackground: "white",
|
|
430
|
+
availableBackground: ["white", "lightskyblue", "black"],
|
|
431
|
+
minimisedSlider: false,
|
|
432
|
+
sliderPosition: "",
|
|
433
|
+
timeMax: 100,
|
|
434
|
+
orginalDuration: "",
|
|
435
|
+
animateDuration: "6secs",
|
|
436
|
+
playSpeed: [
|
|
437
|
+
{
|
|
438
|
+
value: 0.1,
|
|
439
|
+
label: "0.1x"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
value: 0.5,
|
|
443
|
+
label: "0.5x"
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
value: 1,
|
|
447
|
+
label: "1x"
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
value: 2,
|
|
451
|
+
label: "2x"
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
value: 5,
|
|
455
|
+
label: "5x"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
value: 10,
|
|
459
|
+
label: "10x"
|
|
460
|
+
}
|
|
461
|
+
],
|
|
462
|
+
currentSpeed: 1,
|
|
463
|
+
timeStamps: {}
|
|
464
|
+
};
|
|
465
|
+
},
|
|
466
|
+
watch: {
|
|
467
|
+
url: {
|
|
468
|
+
handler: function(newValue) {
|
|
469
|
+
if (this.state === undefined || this.state.url === undefined)
|
|
470
|
+
this.setURL(newValue);
|
|
471
|
+
},
|
|
472
|
+
immediate: true
|
|
473
|
+
},
|
|
474
|
+
region: {
|
|
475
|
+
handler: function(region) {
|
|
476
|
+
if (!(this.state || this.viewURL)) this.setFocusedRegion(region);
|
|
477
|
+
},
|
|
478
|
+
immediate: true
|
|
479
|
+
},
|
|
480
|
+
state: {
|
|
481
|
+
handler: function(state) {
|
|
482
|
+
this.setState(state);
|
|
483
|
+
},
|
|
484
|
+
immediate: true,
|
|
485
|
+
deep: true
|
|
486
|
+
},
|
|
487
|
+
viewURL: {
|
|
488
|
+
handler: function(viewURL) {
|
|
489
|
+
this.updateViewURL(viewURL);
|
|
490
|
+
},
|
|
491
|
+
immediate: true
|
|
492
|
+
},
|
|
493
|
+
helpMode: function(val) {
|
|
494
|
+
this.setHelpMode(val);
|
|
495
|
+
},
|
|
496
|
+
displayMarkers: function(val) {
|
|
497
|
+
this.$module.scene.displayMarkers = val;
|
|
498
|
+
},
|
|
499
|
+
displayMinimap: function(val) {
|
|
500
|
+
this.$module.scene.displayMinimap = val;
|
|
501
|
+
},
|
|
502
|
+
"sceneData.currentTime": function() {
|
|
503
|
+
/**
|
|
504
|
+
* Triggers when scene time changes.
|
|
505
|
+
*
|
|
506
|
+
* @property {number} time Current build-in time of scene.
|
|
507
|
+
* of selected object.
|
|
508
|
+
*/
|
|
509
|
+
this.$emit("timeChanged", this.sceneData.currentTime);
|
|
510
|
+
},
|
|
511
|
+
duration: function() {
|
|
512
|
+
this.$module.scene.setDuration(this.duration);
|
|
513
|
+
},
|
|
514
|
+
minimapSettings: {
|
|
515
|
+
deep: true,
|
|
516
|
+
handler: "updateMinimapScissor"
|
|
517
|
+
},
|
|
518
|
+
render: function(val) {
|
|
519
|
+
this.toggleRendering(val);
|
|
520
|
+
}
|
|
521
|
+
},
|
|
36
522
|
beforeCreate: function() {
|
|
37
|
-
let eventNotifier = new EventNotifier();
|
|
38
|
-
eventNotifier.subscribe(this, eventNotifierCallback(this));
|
|
39
523
|
this.$module = new OrgansViewer();
|
|
524
|
+
this.isReady = false;
|
|
525
|
+
this.selectedObject = undefined;
|
|
526
|
+
this.hoveredObject = undefined;
|
|
527
|
+
this.currentBackground = "white";
|
|
528
|
+
this._currentURL = undefined;
|
|
529
|
+
this.availableBackground = ["white", "black", "lightskyblue"];
|
|
530
|
+
},
|
|
531
|
+
mounted: function() {
|
|
532
|
+
let eventNotifier = new EventNotifier();
|
|
533
|
+
eventNotifier.subscribe(this, this.eventNotifierCallback);
|
|
40
534
|
this.$module.addNotifier(eventNotifier);
|
|
535
|
+
this.$module.addOrganPartAddedCallback(this.organsAdded);
|
|
536
|
+
this.$module.initialiseRenderer(this.$refs.display);
|
|
537
|
+
this.toggleRendering(this.render);
|
|
538
|
+
this.$module.toolTip = undefined;
|
|
539
|
+
this.ro = new ResizeObserver(this.adjustLayout).observe(
|
|
540
|
+
this.$refs.scaffoldContainer
|
|
541
|
+
);
|
|
542
|
+
this.defaultRate = this.$module.getPlayRate();
|
|
543
|
+
},
|
|
544
|
+
beforeDestroy: function() {
|
|
545
|
+
if (this.ro) this.ro.disconnect();
|
|
546
|
+
this.$module.destroy();
|
|
547
|
+
this.$module = undefined;
|
|
41
548
|
},
|
|
42
549
|
methods: {
|
|
43
|
-
|
|
44
|
-
|
|
550
|
+
/**
|
|
551
|
+
* This is called when a new organ is read into the scene.
|
|
552
|
+
*/
|
|
553
|
+
organsAdded: function() {
|
|
554
|
+
this.loading = false;
|
|
555
|
+
},
|
|
556
|
+
/**
|
|
557
|
+
* This is called when Change backgspeedround colour button
|
|
558
|
+
* is pressed an causes the backgrouColornd colour to be changed
|
|
559
|
+
* to one of the three preset colour: white, black and
|
|
560
|
+
* lightskyblue.
|
|
561
|
+
*/
|
|
562
|
+
backgroundChangeCallback: function(colour) {
|
|
563
|
+
this.currentBackground = colour;
|
|
564
|
+
this.$module.zincRenderer
|
|
565
|
+
.getThreeJSRenderer()
|
|
566
|
+
.setClearColor(this.currentBackground, 1);
|
|
567
|
+
},
|
|
568
|
+
/**
|
|
569
|
+
* This is called by captueeScreenshot and after the last render
|
|
570
|
+
* loop, it download a screenshot of the current scene with no UI.
|
|
571
|
+
*/
|
|
572
|
+
captureScreenshotCallback: function() {
|
|
573
|
+
//Remove the callback, only needs to happen once
|
|
574
|
+
this.$module.zincRenderer.removePostRenderCallbackFunction(
|
|
575
|
+
this.captureID
|
|
576
|
+
);
|
|
577
|
+
let screenshot = this.$module.zincRenderer
|
|
578
|
+
.getThreeJSRenderer()
|
|
579
|
+
.domElement.toDataURL("image/png");
|
|
580
|
+
let hrefElement = document.createElement("a");
|
|
581
|
+
document.body.append(hrefElement);
|
|
582
|
+
if (!this.captureFilename) hrefElement.download = `screenshot.png`;
|
|
583
|
+
else hrefElement.download = this.captureFilename;
|
|
584
|
+
hrefElement.href = screenshot;
|
|
585
|
+
hrefElement.click();
|
|
586
|
+
hrefElement.remove();
|
|
587
|
+
},
|
|
588
|
+
/**
|
|
589
|
+
* Function for capturing a screenshot of the current rendering.
|
|
590
|
+
*
|
|
591
|
+
* @param {String} filename filename given to the screenshot.
|
|
592
|
+
*
|
|
593
|
+
* @public
|
|
594
|
+
*/
|
|
595
|
+
captureScreenshot: function(filename) {
|
|
596
|
+
this.captureFilename = filename;
|
|
597
|
+
this.captureID = this.$module.zincRenderer.addPostRenderCallbackFunction(
|
|
598
|
+
this.captureScreenshotCallback
|
|
599
|
+
);
|
|
600
|
+
},
|
|
601
|
+
formatTooltip(val) {
|
|
602
|
+
if (this.timeMax >= 1000) {
|
|
603
|
+
if (val) {
|
|
604
|
+
let sec = ((val % 60000) / 1000).toFixed(2) + "s";
|
|
605
|
+
let min = val > 60000 ? (val / 60000).toFixed(0) + "m " : "";
|
|
606
|
+
return min + sec;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return val ? val.toFixed(2) + " ms" : "0 ms";
|
|
610
|
+
},
|
|
611
|
+
/**
|
|
612
|
+
* Function to reset the view to default.
|
|
613
|
+
* Also called when the associated button is pressed.
|
|
614
|
+
*
|
|
615
|
+
* @public
|
|
616
|
+
*/
|
|
617
|
+
fitWindow: function() {
|
|
618
|
+
if (this.$module.scene) {
|
|
619
|
+
this.$module.scene.viewAll();
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
/**
|
|
623
|
+
* Function to zoom in.
|
|
624
|
+
* Also called when the associated button is pressed.
|
|
625
|
+
*
|
|
626
|
+
* @public
|
|
627
|
+
*/
|
|
628
|
+
zoomIn: function() {
|
|
629
|
+
if (this.$module.scene) {
|
|
630
|
+
this.$module.scene.changeZoomByScrollRateUnit(-1);
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
/**
|
|
634
|
+
* Function to zoom out.
|
|
635
|
+
* Also called when the associated button is pressed.
|
|
636
|
+
*
|
|
637
|
+
* @public
|
|
638
|
+
*/
|
|
639
|
+
zoomOut: function() {
|
|
640
|
+
if (this.$module.scene) {
|
|
641
|
+
this.$module.scene.changeZoomByScrollRateUnit(1);
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
/**
|
|
645
|
+
* Function to change the current play speed.
|
|
646
|
+
*
|
|
647
|
+
* @public
|
|
648
|
+
*/
|
|
649
|
+
speedChanged: function(speed) {
|
|
650
|
+
this.currentSpeed = speed;
|
|
651
|
+
this.$module.setPlayRate(this.defaultRate * this.currentSpeed);
|
|
652
|
+
},
|
|
653
|
+
/**
|
|
654
|
+
* Function used to stop the free spin
|
|
655
|
+
*
|
|
656
|
+
* @public
|
|
657
|
+
*/
|
|
658
|
+
stopFreeSpin: function() {
|
|
659
|
+
let cameracontrol = this.$module.scene.getZincCameraControls();
|
|
660
|
+
cameracontrol.stopAutoTumble();
|
|
661
|
+
this.isTransitioning = false;
|
|
662
|
+
},
|
|
663
|
+
/**
|
|
664
|
+
* Focus on named region
|
|
665
|
+
*/
|
|
666
|
+
viewRegion: function(name) {
|
|
667
|
+
if (name && name != "" && this.$module.scene) {
|
|
668
|
+
let objects = this.$module.scene.findObjectsWithGroupName(name);
|
|
669
|
+
let box = this.$module.scene.getBoundingBoxOfZincObjects(objects);
|
|
670
|
+
if (box) {
|
|
671
|
+
this.$module.scene.viewAllWithBoundingBox(box);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
},
|
|
675
|
+
setFocusedRegion: function(name) {
|
|
676
|
+
if (name) {
|
|
677
|
+
if (this.isReady) {
|
|
678
|
+
this.viewRegion(name);
|
|
679
|
+
} else {
|
|
680
|
+
this.$module.setFinishDownloadCallback(
|
|
681
|
+
this.setURLFinishCallback({ region: name })
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
45
685
|
},
|
|
46
|
-
|
|
47
|
-
|
|
686
|
+
updateViewURL: function(viewURL) {
|
|
687
|
+
if (viewURL) {
|
|
688
|
+
if (this.isReady) {
|
|
689
|
+
const url = new URL(viewURL, this.url);
|
|
690
|
+
this.$module.scene.loadViewURL(url);
|
|
691
|
+
} else {
|
|
692
|
+
this.$module.setFinishDownloadCallback(
|
|
693
|
+
this.setURLFinishCallback({ viewURL: viewURL })
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
48
697
|
},
|
|
698
|
+
/**
|
|
699
|
+
* Function used to rotate the scene.
|
|
700
|
+
* Also called when the associated button is pressed.
|
|
701
|
+
*
|
|
702
|
+
* @public
|
|
703
|
+
*/
|
|
704
|
+
freeSpin: function() {
|
|
705
|
+
if (this.$module.scene) {
|
|
706
|
+
let cameracontrol = this.$module.scene.getZincCameraControls();
|
|
707
|
+
this.isTransitioning = true;
|
|
708
|
+
cameracontrol.enableAutoTumble();
|
|
709
|
+
cameracontrol.autoTumble([1.0, 0.0], Math.PI, true);
|
|
710
|
+
setTimeout(this.stopFreeSpin, 4000);
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
/**
|
|
714
|
+
* Callback when a region is selected/highlighted.
|
|
715
|
+
* It will also update other controls.
|
|
716
|
+
*/
|
|
717
|
+
eventNotifierCallback: function(event) {
|
|
718
|
+
if (event.eventType == 1) {
|
|
719
|
+
if (this.$refs.traditionalControl) {
|
|
720
|
+
if (event.identifiers[0]) {
|
|
721
|
+
let id = event.identifiers[0].data.id
|
|
722
|
+
? event.identifiers[0].data.id
|
|
723
|
+
: event.identifiers[0].data.group;
|
|
724
|
+
this.$refs.traditionalControl.changeActiveByName(id);
|
|
725
|
+
} else {
|
|
726
|
+
this.$refs.traditionalControl.removeActive();
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Triggers when an object has been selected
|
|
731
|
+
*
|
|
732
|
+
* @property {array} identifiers array of identifiers
|
|
733
|
+
* of selected object.
|
|
734
|
+
*/
|
|
735
|
+
this.$emit("scaffold-selected", event.identifiers);
|
|
736
|
+
} else if (event.eventType == 2) {
|
|
737
|
+
if (this.$refs.traditionalControl) {
|
|
738
|
+
if (event.identifiers[0]) {
|
|
739
|
+
let id = event.identifiers[0].data.id
|
|
740
|
+
? event.identifiers[0].data.id
|
|
741
|
+
: event.identifiers[0].data.group;
|
|
742
|
+
this.$refs.traditionalControl.changeHoverByName(id);
|
|
743
|
+
} else this.$refs.traditionalControl.removeHover();
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Triggers when an object has been highlighted
|
|
747
|
+
*
|
|
748
|
+
* @property {array} identifiers array of identifiers
|
|
749
|
+
* of highlighted object.
|
|
750
|
+
*/
|
|
751
|
+
this.$emit("scaffold-highlighted", event.identifiers);
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
/**
|
|
755
|
+
* Get the coordinates of the current selected region.
|
|
756
|
+
*
|
|
757
|
+
* @public
|
|
758
|
+
*/
|
|
759
|
+
getCoordinatesOfSelected: function() {
|
|
760
|
+
if (this.selectedObject) {
|
|
761
|
+
return this.$module.scene.getObjectsScreenXY([this.selectedObject]);
|
|
762
|
+
}
|
|
763
|
+
return undefined;
|
|
764
|
+
},
|
|
765
|
+
/**
|
|
766
|
+
* Return an object containing the window coordinates of the
|
|
767
|
+
* current selected region which will be updated after each render
|
|
768
|
+
* loop.
|
|
769
|
+
*
|
|
770
|
+
* @public
|
|
771
|
+
*/
|
|
772
|
+
getDynamicSelectedCoordinates: function() {
|
|
773
|
+
return this.$module.selectedScreenCoordinates;
|
|
774
|
+
},
|
|
775
|
+
/**
|
|
776
|
+
* Callback when time is changed through the UI.
|
|
777
|
+
*/
|
|
49
778
|
timeChange: function(event) {
|
|
50
|
-
|
|
779
|
+
let normalizedTime = (event / this.timeMax) * 100;
|
|
780
|
+
if (normalizedTime != this.sceneData.currentTime)
|
|
781
|
+
this.$module.updateTime(normalizedTime);
|
|
782
|
+
},
|
|
783
|
+
/**
|
|
784
|
+
* A callback used by children components. Set the selected zinc object
|
|
785
|
+
*
|
|
786
|
+
* @param {object} object Zinc object
|
|
787
|
+
*/
|
|
788
|
+
objectSelected: function(object) {
|
|
789
|
+
if (object !== this.selectedObject) {
|
|
790
|
+
this.selectedObject = object;
|
|
791
|
+
this.$refs.opacityControl.setObject(this.selectedObject);
|
|
792
|
+
if (object) this.$module.setSelectedByZincObject(object, true);
|
|
793
|
+
else this.$module.setSelectedByObjects([], true);
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
/**
|
|
797
|
+
* A callback used by children components. Set the highlighted zinc object
|
|
798
|
+
*
|
|
799
|
+
* @param {object} object Zinc object
|
|
800
|
+
*/
|
|
801
|
+
objectHovered: function(object) {
|
|
802
|
+
if (object !== this.hoveredObject) {
|
|
803
|
+
this.hoveredObject = object;
|
|
804
|
+
if (object) this.$module.setHighlightedByZincObject(object, true);
|
|
805
|
+
else this.$module.setHighlightedByObjects([], true);
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
/**
|
|
809
|
+
* Set the selected by name.
|
|
810
|
+
*
|
|
811
|
+
* @param {name} name Name of the region
|
|
812
|
+
*/
|
|
813
|
+
changeActiveByName: function(name) {
|
|
814
|
+
this.$refs.traditionalControl.changeActiveByName(name);
|
|
815
|
+
if (name === undefined)
|
|
816
|
+
this.$refs.traditionalControl.removeActive();
|
|
51
817
|
},
|
|
818
|
+
/**
|
|
819
|
+
* Set the highlighted by name.
|
|
820
|
+
*
|
|
821
|
+
* @param {name} name Name of the region
|
|
822
|
+
*/
|
|
823
|
+
changeHighlightedByName: function(name) {
|
|
824
|
+
this.$refs.traditionalControl.changeHoverByName(name);
|
|
825
|
+
if (name === undefined)
|
|
826
|
+
this.$refs.traditionalControl.removeHover();
|
|
827
|
+
},
|
|
828
|
+
/**
|
|
829
|
+
* Start the animation.
|
|
830
|
+
*
|
|
831
|
+
* @param {object} object Zinc object
|
|
832
|
+
*/
|
|
52
833
|
play: function(flag) {
|
|
53
834
|
this.$module.playAnimation(flag);
|
|
54
835
|
this.isPlaying = flag;
|
|
836
|
+
},
|
|
837
|
+
/**
|
|
838
|
+
* Function to toggle on/off overlay help.
|
|
839
|
+
*/
|
|
840
|
+
setHelpMode: function(helpMode) {
|
|
841
|
+
if (helpMode) {
|
|
842
|
+
this.inHelp = true;
|
|
843
|
+
this.hoverVisabilities.forEach(item => {
|
|
844
|
+
item.value = true;
|
|
845
|
+
});
|
|
846
|
+
} else {
|
|
847
|
+
this.inHelp = false;
|
|
848
|
+
this.hoverVisabilities.forEach(item => {
|
|
849
|
+
item.value = false;
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
},
|
|
853
|
+
/**
|
|
854
|
+
* This is called when mouse cursor enters supported elements
|
|
855
|
+
* with help tootltips.
|
|
856
|
+
*/
|
|
857
|
+
showToolitip: function(tooltipNumber) {
|
|
858
|
+
if (!this.inHelp) {
|
|
859
|
+
this.tooltipWait = setTimeout(() => {
|
|
860
|
+
this.hoverVisabilities[tooltipNumber].value = true;
|
|
861
|
+
}, 500);
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
/**
|
|
865
|
+
* This is called when mouse cursor exits supported element..
|
|
866
|
+
*/
|
|
867
|
+
hideToolitip: function(tooltipNumber) {
|
|
868
|
+
if (!this.inHelp) {
|
|
869
|
+
this.hoverVisabilities[tooltipNumber].value = false;
|
|
870
|
+
clearTimeout(this.tooltipWait);
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
/**
|
|
874
|
+
* Called when minimap settings has changed. Pass the
|
|
875
|
+
* parameters to ZincJS and marked it for update.
|
|
876
|
+
*/
|
|
877
|
+
updateMinimapScissor: function() {
|
|
878
|
+
Object.keys(this.minimapSettings).forEach(key => {
|
|
879
|
+
this.$module.scene.minimapScissor[key] = this.minimapSettings[key];
|
|
880
|
+
});
|
|
881
|
+
this.$module.scene.minimapScissor.updateRequired = true;
|
|
882
|
+
},
|
|
883
|
+
updateSettingsfromScene: function() {
|
|
884
|
+
this.currentSpeed = 1;
|
|
885
|
+
this.$module.setPlayRate(this.defaultRate);
|
|
886
|
+
this.orginalDuration = this.$module.scene.getMetadataTag(
|
|
887
|
+
"OriginalDuration"
|
|
888
|
+
);
|
|
889
|
+
this.animateDuration = this.$module.scene.getMetadataTag("Duration");
|
|
890
|
+
let timeStamps = this.$module.scene.getMetadataTag("TimeStamps");
|
|
891
|
+
this.timeStamps = {};
|
|
892
|
+
for (const key in timeStamps) {
|
|
893
|
+
this.timeStamps[timeStamps[key]] = key;
|
|
894
|
+
}
|
|
895
|
+
this.timeMax = this.$module.scene.getDuration();
|
|
896
|
+
},
|
|
897
|
+
setURLFinishCallback: function(options) {
|
|
898
|
+
return () => {
|
|
899
|
+
if (options) {
|
|
900
|
+
if (options.viewport) {
|
|
901
|
+
this.$module.scene
|
|
902
|
+
.getZincCameraControls()
|
|
903
|
+
.setCurrentCameraSettings(options.viewport);
|
|
904
|
+
} else if (options.viewURL && options.viewURL !== "") {
|
|
905
|
+
const url = new URL(options.viewURL, this.url);
|
|
906
|
+
this.$module.scene.loadViewURL(url);
|
|
907
|
+
} else if (options.region && options.region !== "") {
|
|
908
|
+
this.viewRegion(options.region);
|
|
909
|
+
}
|
|
910
|
+
if (options.visibility) {
|
|
911
|
+
// Some UIs may not be ready at this time.
|
|
912
|
+
this.$nextTick(() => {
|
|
913
|
+
this.$refs.traditionalControl.setState(options.visibility);
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
this.updateSettingsfromScene();
|
|
918
|
+
this.$module.updateTime(0.01);
|
|
919
|
+
this.$module.updateTime(0);
|
|
920
|
+
this.$module.unsetFinishDownloadCallback();
|
|
921
|
+
this.isReady = true;
|
|
922
|
+
};
|
|
923
|
+
},
|
|
924
|
+
/**
|
|
925
|
+
* Function used for getting the current states of the scene. This exported states
|
|
926
|
+
* can be imported using the importStates method.
|
|
927
|
+
*
|
|
928
|
+
* @public
|
|
929
|
+
*/
|
|
930
|
+
getState: function() {
|
|
931
|
+
let state = {
|
|
932
|
+
url: this._currentURL,
|
|
933
|
+
viewport: undefined,
|
|
934
|
+
visibility: undefined
|
|
935
|
+
};
|
|
936
|
+
if (this.$refs.traditionalControl)
|
|
937
|
+
state.visibility = this.$refs.traditionalControl.getState();
|
|
938
|
+
if (this.$module.scene) {
|
|
939
|
+
let zincCameraControls = this.$module.scene.getZincCameraControls();
|
|
940
|
+
state.viewport = zincCameraControls.getCurrentViewport();
|
|
941
|
+
}
|
|
942
|
+
return state;
|
|
943
|
+
},
|
|
944
|
+
/**
|
|
945
|
+
* Function used for importing the states of the scene. This exported states
|
|
946
|
+
* can be imported using the read states method.
|
|
947
|
+
*
|
|
948
|
+
* @public
|
|
949
|
+
*/
|
|
950
|
+
setState: function(state) {
|
|
951
|
+
if (state) {
|
|
952
|
+
if (state.url && state.url !== this._currentURL) {
|
|
953
|
+
this.setURLAndState(state.url, {
|
|
954
|
+
viewport: state.viewport,
|
|
955
|
+
visibility: state.visibility
|
|
956
|
+
});
|
|
957
|
+
} else {
|
|
958
|
+
if (state.viewport || state.visibility) {
|
|
959
|
+
if (this.isReady && this.$module.scene) {
|
|
960
|
+
if (state.viewport)
|
|
961
|
+
this.$module.scene
|
|
962
|
+
.getZincCameraControls()
|
|
963
|
+
.setCurrentCameraSettings(state.viewport);
|
|
964
|
+
if (state.visibility)
|
|
965
|
+
this.$refs.traditionalControl.setState(state.visibility);
|
|
966
|
+
} else {
|
|
967
|
+
this.$module.setFinishDownloadCallback(
|
|
968
|
+
this.setURLFinishCallback({
|
|
969
|
+
viewport: state.viewport,
|
|
970
|
+
visibility: state.visibility
|
|
971
|
+
})
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
},
|
|
978
|
+
exportGLTF: function(binary) {
|
|
979
|
+
return this.$module.scene.exportGLTF(binary);
|
|
980
|
+
},
|
|
981
|
+
/**
|
|
982
|
+
* Function used for reading in new scaffold metadata and a custom
|
|
983
|
+
* viewport. This function will ignore the state prop and
|
|
984
|
+
* read in the new url.
|
|
985
|
+
*
|
|
986
|
+
* @public
|
|
987
|
+
*/
|
|
988
|
+
setURLAndState: function(newValue, state) {
|
|
989
|
+
if (newValue != this._currentURL) {
|
|
990
|
+
let viewport = state && state.viewport ? state.viewport : undefined;
|
|
991
|
+
let visibility =
|
|
992
|
+
state && state.visibility ? state.visibility : undefined;
|
|
993
|
+
this._currentURL = newValue;
|
|
994
|
+
if (this.$refs.traditionalControl)
|
|
995
|
+
this.$refs.traditionalControl.clear();
|
|
996
|
+
this.loading = true;
|
|
997
|
+
this.isReady = false;
|
|
998
|
+
this.$module.setFinishDownloadCallback(
|
|
999
|
+
this.setURLFinishCallback({
|
|
1000
|
+
viewport: viewport,
|
|
1001
|
+
region: this.region,
|
|
1002
|
+
viewURL: this.viewURL,
|
|
1003
|
+
visibility: visibility
|
|
1004
|
+
})
|
|
1005
|
+
);
|
|
1006
|
+
this.$module.loadOrgansFromURL(
|
|
1007
|
+
newValue,
|
|
1008
|
+
undefined,
|
|
1009
|
+
undefined,
|
|
1010
|
+
"scene",
|
|
1011
|
+
undefined
|
|
1012
|
+
);
|
|
1013
|
+
this.$module.scene.displayMarkers = this.displayMarkers;
|
|
1014
|
+
this.$module.scene.displayMinimap = this.displayMinimap;
|
|
1015
|
+
this.updateMinimapScissor();
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
/**
|
|
1019
|
+
* Function used for reading in new scaffold metadata. This function will ignore
|
|
1020
|
+
* the state prop and read in the new url.
|
|
1021
|
+
*
|
|
1022
|
+
* @public
|
|
1023
|
+
*/
|
|
1024
|
+
setURL: function(newValue) {
|
|
1025
|
+
this.setURLAndState(newValue, undefined);
|
|
1026
|
+
},
|
|
1027
|
+
/**
|
|
1028
|
+
* Callback when drawer is toggled.
|
|
1029
|
+
*
|
|
1030
|
+
*/
|
|
1031
|
+
drawerToggled: function(flag) {
|
|
1032
|
+
this.drawerOpen = flag;
|
|
1033
|
+
this.adjustLayout();
|
|
1034
|
+
},
|
|
1035
|
+
/**
|
|
1036
|
+
* Callback using ResizeObserver.
|
|
1037
|
+
|
|
1038
|
+
*/
|
|
1039
|
+
adjustLayout: function() {
|
|
1040
|
+
let width = this.$refs.scaffoldContainer.clientWidth;
|
|
1041
|
+
this.minimisedSlider = width < 812;
|
|
1042
|
+
if (this.minimisedSlider) {
|
|
1043
|
+
this.sliderPosition = this.drawerOpen ? "right" : "left";
|
|
1044
|
+
} else {
|
|
1045
|
+
this.sliderPosition = "";
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
toggleRendering: function(flag) {
|
|
1049
|
+
if (this.$module.zincRenderer) {
|
|
1050
|
+
if (flag) {
|
|
1051
|
+
this.$module.zincRenderer.animate();
|
|
1052
|
+
} else {
|
|
1053
|
+
this.$module.zincRenderer.stopAnimate();
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
},
|
|
1057
|
+
forceResize: function() {
|
|
1058
|
+
if (this.$module.zincRenderer) {
|
|
1059
|
+
this.$module.zincRenderer.onWindowResize();
|
|
1060
|
+
}
|
|
55
1061
|
}
|
|
56
|
-
},
|
|
57
|
-
props: ['url'],
|
|
58
|
-
data: function() {
|
|
59
|
-
return {
|
|
60
|
-
sceneData: this.$module.sceneData,
|
|
61
|
-
isPlaying: false
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
mounted: function () {
|
|
65
|
-
this.$module.loadOrgansFromURL(this.url, undefined, undefined, "Overlay", undefined);
|
|
66
|
-
this.$module.initialiseRenderer(this.$refs.display);
|
|
67
1062
|
}
|
|
68
|
-
}
|
|
1063
|
+
};
|
|
69
1064
|
</script>
|
|
70
1065
|
|
|
71
1066
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
72
|
-
<style scoped>
|
|
1067
|
+
<style scoped lang="scss">
|
|
1068
|
+
@import "~element-ui/packages/theme-chalk/src/col";
|
|
1069
|
+
@import "~element-ui/packages/theme-chalk/src/loading";
|
|
1070
|
+
@import "~element-ui/packages/theme-chalk/src/option";
|
|
1071
|
+
@import "~element-ui/packages/theme-chalk/src/popover";
|
|
1072
|
+
@import "~element-ui/packages/theme-chalk/src/row";
|
|
1073
|
+
@import "~element-ui/packages/theme-chalk/src/select";
|
|
1074
|
+
@import "~element-ui/packages/theme-chalk/src/slider";
|
|
1075
|
+
@import "~element-ui/packages/theme-chalk/src/tabs";
|
|
1076
|
+
@import "~element-ui/packages/theme-chalk/src/tab-pane";
|
|
1077
|
+
|
|
1078
|
+
.warning-icon {
|
|
1079
|
+
position: absolute;
|
|
1080
|
+
top: 15px;
|
|
1081
|
+
left: 37px;
|
|
1082
|
+
text-align: left;
|
|
1083
|
+
font-size: 25px;
|
|
1084
|
+
color: $warning;
|
|
1085
|
+
|
|
1086
|
+
&:hover {
|
|
1087
|
+
cursor: pointer;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
.warning-text {
|
|
1092
|
+
font-size: 15px;
|
|
1093
|
+
vertical-align: 5px;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
::v-deep .warning-popper {
|
|
1097
|
+
padding: 9px 10px;
|
|
1098
|
+
min-width: 150px;
|
|
1099
|
+
font-size: 12px;
|
|
1100
|
+
color: #fff;
|
|
1101
|
+
background-color: $warning;
|
|
1102
|
+
|
|
1103
|
+
&.right-popper {
|
|
1104
|
+
.popper__arrow {
|
|
1105
|
+
&::after {
|
|
1106
|
+
border-right-color: $warning !important;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
#organsDisplayArea {
|
|
1113
|
+
&:focus {
|
|
1114
|
+
outline: none !important;
|
|
1115
|
+
border: 0px;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
73
1118
|
|
|
74
1119
|
.scaffold-container {
|
|
75
|
-
height:100%;
|
|
76
|
-
width:100%;
|
|
1120
|
+
height: 100%;
|
|
1121
|
+
width: 100%;
|
|
1122
|
+
position: relative;
|
|
77
1123
|
}
|
|
78
1124
|
|
|
79
|
-
|
|
1125
|
+
.time-slider-container {
|
|
1126
|
+
text-align: left;
|
|
80
1127
|
position: absolute;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
1128
|
+
right: 155px;
|
|
1129
|
+
width: calc(100% - 530px);
|
|
1130
|
+
bottom: 16px;
|
|
1131
|
+
transition: all 1s ease;
|
|
1132
|
+
outline: none;
|
|
1133
|
+
|
|
1134
|
+
&.minimised {
|
|
1135
|
+
width: calc(40%);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
&.left {
|
|
1139
|
+
right: 155px;
|
|
1140
|
+
width: calc(100% - 250px);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
&.right {
|
|
1144
|
+
right: 8px;
|
|
1145
|
+
bottom: 54px;
|
|
1146
|
+
}
|
|
84
1147
|
}
|
|
85
1148
|
|
|
86
|
-
|
|
1149
|
+
.slider-display-text {
|
|
1150
|
+
height: 20px;
|
|
1151
|
+
color: rgb(48, 49, 51);
|
|
1152
|
+
font-size: 14px;
|
|
1153
|
+
font-weight: normal;
|
|
1154
|
+
line-height: 20px;
|
|
1155
|
+
padding-left: 8px;
|
|
1156
|
+
text-shadow: -1px -1px #fff, 1px -1px #fff, -1px 1px #fff, 1px -1px #fff;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.tab-content {
|
|
1160
|
+
display: flex;
|
|
1161
|
+
height: 34px;
|
|
1162
|
+
padding-top: 8px;
|
|
1163
|
+
font-size: 14px;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.tab-content ::v-deep .el-slider__marks-text {
|
|
1167
|
+
margin-top: 12px;
|
|
1168
|
+
margin-left: 8px;
|
|
1169
|
+
font-size: 10px;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.tab-content ::v-deep .el-slider__stop {
|
|
1173
|
+
width: 10px;
|
|
1174
|
+
height: 10px;
|
|
1175
|
+
top: -1px;
|
|
1176
|
+
border: solid 1px $app-primary-color;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
.animation-data {
|
|
1180
|
+
margin-left: 8px;
|
|
1181
|
+
line-height: 26px;
|
|
1182
|
+
display: flex;
|
|
1183
|
+
|
|
1184
|
+
:not(:first-child) {
|
|
1185
|
+
margin-left: 8px;
|
|
1186
|
+
}
|
|
1187
|
+
.purple {
|
|
1188
|
+
padding-left: 2px;
|
|
1189
|
+
color: $app-primary-color;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
.slider {
|
|
1193
|
+
margin-left: 30px;
|
|
1194
|
+
width: calc(100% - 88px);
|
|
1195
|
+
margin-top: -7px;
|
|
1196
|
+
|
|
1197
|
+
::v-deep .el-slider__runway {
|
|
1198
|
+
height: 10px;
|
|
1199
|
+
margin: 14px 0;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
::v-deep .el-slider__button-wrapper {
|
|
1203
|
+
top: -13px;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
.zoomOut {
|
|
1208
|
+
padding-left: 8px;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
.fitWindow {
|
|
1212
|
+
padding-left: 8px;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
::v-deep .non-selectable {
|
|
1216
|
+
user-select: none;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
::v-deep .background-popper {
|
|
1220
|
+
padding: 5px 12px;
|
|
1221
|
+
background-color: #ffffff;
|
|
1222
|
+
border: 1px solid $app-primary-color;
|
|
1223
|
+
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.06);
|
|
1224
|
+
height: 72px;
|
|
1225
|
+
width: 128px;
|
|
1226
|
+
min-width: 128px;
|
|
1227
|
+
|
|
1228
|
+
&.el-popper[x-placement^="top"] {
|
|
1229
|
+
.popper__arrow {
|
|
1230
|
+
border-top-color: $app-primary-color !important;
|
|
1231
|
+
&:after {
|
|
1232
|
+
border-top-color: #fff !important;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
.background-colour {
|
|
1239
|
+
bottom: 16px;
|
|
1240
|
+
position: absolute;
|
|
1241
|
+
transition: all 1s ease;
|
|
1242
|
+
|
|
1243
|
+
&.open {
|
|
1244
|
+
left: 322px;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
&.close {
|
|
1248
|
+
left: 24px;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.backgroundText {
|
|
1253
|
+
color: rgb(48, 49, 51);
|
|
1254
|
+
font-size: 14px;
|
|
1255
|
+
font-weight: normal;
|
|
1256
|
+
line-height: 20px;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
.backgroundChooser {
|
|
1260
|
+
display: flex;
|
|
1261
|
+
margin-top: 16px;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
.backgroundChoice {
|
|
1265
|
+
width: 20px;
|
|
1266
|
+
height: 20px;
|
|
1267
|
+
border: 1px solid rgb(144, 147, 153);
|
|
1268
|
+
margin-left: 20px;
|
|
1269
|
+
|
|
1270
|
+
&.active {
|
|
1271
|
+
border: 2px solid $app-primary-color;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
&:hover {
|
|
1275
|
+
cursor: pointer;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
&.white {
|
|
1279
|
+
background-color: white;
|
|
1280
|
+
margin-left: 10px;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
&.black {
|
|
1284
|
+
background-color: black;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
&.lightskyblue {
|
|
1288
|
+
background-color: lightskyblue;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
.icon-button {
|
|
1293
|
+
height: 24px !important;
|
|
1294
|
+
width: 24px !important;
|
|
1295
|
+
|
|
1296
|
+
&:hover {
|
|
1297
|
+
cursor: pointer;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
.bottom-right-control {
|
|
87
1302
|
position: absolute;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
1303
|
+
right: 16px;
|
|
1304
|
+
bottom: 16px;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.video-button {
|
|
1308
|
+
margin-left: 8px;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
.time-slider-container {
|
|
1312
|
+
::v-deep .el-tabs__header {
|
|
1313
|
+
margin: 0px;
|
|
1314
|
+
border-bottom: 1px solid rgb(144, 147, 153);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
.el-row {
|
|
1318
|
+
margin-bottom: 5px;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
::v-deep .el-tabs__content {
|
|
1322
|
+
border-left: 1px solid rgb(144, 147, 153);
|
|
1323
|
+
border-bottom: 1px solid rgb(144, 147, 153);
|
|
1324
|
+
border-right: 1px solid rgb(144, 147, 153);
|
|
1325
|
+
border-radius: 0px 0px 4px 4px;
|
|
1326
|
+
background-color: white;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
::v-deep .el-tabs--card {
|
|
1330
|
+
> .el-tabs__header {
|
|
1331
|
+
.el-tabs__nav {
|
|
1332
|
+
border: 1px solid rgb(144, 147, 153);
|
|
1333
|
+
border-bottom: none;
|
|
1334
|
+
border-radius: 4px 4px 0px 0px;
|
|
1335
|
+
background-color: white;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
.el-tabs__item {
|
|
1339
|
+
height: 24px;
|
|
1340
|
+
line-height: 24px;
|
|
1341
|
+
padding: 0 8px !important;
|
|
1342
|
+
border-bottom: 1px solid;
|
|
1343
|
+
border-left: 1px solid rgb(144, 147, 153);
|
|
1344
|
+
&:first-child {
|
|
1345
|
+
border-left: none;
|
|
1346
|
+
}
|
|
1347
|
+
&.is-active {
|
|
1348
|
+
border-bottom: 1px solid white;
|
|
1349
|
+
color: rgb(48, 49, 51);
|
|
1350
|
+
}
|
|
1351
|
+
&:hover {
|
|
1352
|
+
color: $app-primary-color;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
92
1357
|
}
|
|
93
1358
|
|
|
1359
|
+
::v-deep .scaffold-popper {
|
|
1360
|
+
padding: 6px 4px;
|
|
1361
|
+
font-size: 12px;
|
|
1362
|
+
color: rgb(48, 49, 51);
|
|
1363
|
+
background-color: #f3ecf6;
|
|
1364
|
+
border: 1px solid $app-primary-color;
|
|
1365
|
+
white-space: nowrap;
|
|
1366
|
+
min-width: unset;
|
|
1367
|
+
pointer-events: none;
|
|
1368
|
+
|
|
1369
|
+
&.left-popper {
|
|
1370
|
+
.popper__arrow {
|
|
1371
|
+
border-left-color: $app-primary-color !important;
|
|
1372
|
+
&:after {
|
|
1373
|
+
border-left-color: #f3ecf6 !important;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
&.right-popper {
|
|
1379
|
+
.popper__arrow {
|
|
1380
|
+
border-right-color: $app-primary-color !important;
|
|
1381
|
+
&:after {
|
|
1382
|
+
border-right-color: #f3ecf6 !important;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
&.el-popper[x-placement^="top"] {
|
|
1388
|
+
.popper__arrow {
|
|
1389
|
+
border-top-color: $app-primary-color !important;
|
|
1390
|
+
&:after {
|
|
1391
|
+
border-top-color: #f3ecf6 !important;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
::v-deep .el-slider__button {
|
|
1398
|
+
border: 2px solid $app-primary-color;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
::v-deep .el-slider__bar {
|
|
1402
|
+
background-color: $app-primary-color;
|
|
1403
|
+
height: 10px;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
::v-deep .el-loading-spinner {
|
|
1407
|
+
i, .el-loading-text {
|
|
1408
|
+
color: $app-primary-color;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
::v-deep .popper-zoomout {
|
|
1413
|
+
padding-right: 11px;
|
|
1414
|
+
left: -21px !important;
|
|
1415
|
+
.popper__arrow {
|
|
1416
|
+
left: 53px !important;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
.select-box {
|
|
1421
|
+
width: 57px;
|
|
1422
|
+
border-radius: 4px;
|
|
1423
|
+
border: 1px solid rgb(144, 147, 153);
|
|
1424
|
+
background-color: var(--white);
|
|
1425
|
+
font-weight: 500;
|
|
1426
|
+
color: rgb(48, 49, 51);
|
|
1427
|
+
margin-left: 8px;
|
|
1428
|
+
|
|
1429
|
+
::v-deep .el-input__inner {
|
|
1430
|
+
color: $app-primary-color;
|
|
1431
|
+
height: 22px;
|
|
1432
|
+
padding-left: 8px;
|
|
1433
|
+
padding-right: 8px;
|
|
1434
|
+
border: none;
|
|
1435
|
+
font-family: "Asap", sans-serif;
|
|
1436
|
+
line-height: 22px;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
::v-deep .el-input,
|
|
1440
|
+
::v-deep .el-input__icon {
|
|
1441
|
+
line-height: 22px;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
</style>
|
|
1445
|
+
|
|
1446
|
+
<style lang="scss">
|
|
1447
|
+
.time-slider-tooltip {
|
|
1448
|
+
padding: 6px 4px !important;
|
|
1449
|
+
font-family: "Asap", sans-serif;
|
|
1450
|
+
font-size: 12px !important;
|
|
1451
|
+
color: rgb(48, 49, 51) !important;
|
|
1452
|
+
background-color: #f3ecf6 !important;
|
|
1453
|
+
border: 1px solid $app-primary-color !important;
|
|
1454
|
+
white-space: nowrap !important;
|
|
1455
|
+
min-width: unset !important;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.scaffold_viewer_dropdown .el-select-dropdown__item {
|
|
1459
|
+
white-space: nowrap;
|
|
1460
|
+
text-align: left;
|
|
1461
|
+
font-family: "Asap", sans-serif;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.opacity-box {
|
|
1465
|
+
right: 0px;
|
|
1466
|
+
bottom:200px;
|
|
1467
|
+
position:absolute;
|
|
1468
|
+
}
|
|
94
1469
|
</style>
|