@abi-software/scaffoldvuer 0.1.52-beta.2 → 0.1.52-beta.3

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": "@abi-software/scaffoldvuer",
3
- "version": "0.1.52-beta.2",
3
+ "version": "0.1.52-beta.3",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "vue": "^2.6.10",
34
34
  "vue-drag-resize": "^1.3.2",
35
35
  "vue-router": "^3.5.1",
36
- "zincjs": "^0.50.0-beta.1"
36
+ "zincjs": "^1.0.0-alpha-3"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@vue/cli-plugin-babel": "^4.0.0",
@@ -47,8 +47,9 @@
47
47
  "node-sass": "^4.14.1",
48
48
  "raw-loader": "^0.5.1",
49
49
  "sass-loader": "^8.0.2",
50
+ "simple-dropzone": "^0.8.1",
50
51
  "vue-cli-plugin-styleguidist": "^4.32.2",
51
- "vue-styleguidist": "^4.38.1",
52
+ "vue-styleguidist": "^4.44.22",
52
53
  "vue-template-compiler": "^2.6.10",
53
54
  "webpack-node-externals": "^2.5.2"
54
55
  },
package/src/App.vue CHANGED
@@ -4,23 +4,29 @@
4
4
  rel="stylesheet"
5
5
  href="https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap"
6
6
  >
7
- <ScaffoldVuer
8
- ref="scaffold"
9
- class="vuer"
10
- :display-u-i="displayUI"
11
- :url="url"
12
- :help-mode="helpMode"
13
- :display-minimap="displayMinimap"
14
- :display-markers="displayMarkers"
15
- :minimap-settings="minimapSettings"
16
- :show-colour-picker="showColourPicker"
17
- :render="render"
18
- :region="region"
19
- :view-u-r-l="viewURL"
20
- @scaffold-selected="onSelected"
21
- @scaffold-navigated="onNavigated"
22
- @timeChanged="updateCurrentTime"
23
- />
7
+ <drop-zone
8
+ ref="dropzone"
9
+ @files-drop="onFilesDrop"
10
+ >
11
+ <ScaffoldVuer
12
+ ref="scaffold"
13
+ class="vuer"
14
+ :display-u-i="displayUI"
15
+ :url="url"
16
+ :help-mode="helpMode"
17
+ :display-minimap="displayMinimap"
18
+ :display-markers="displayMarkers"
19
+ :minimap-settings="minimapSettings"
20
+ :show-colour-picker="showColourPicker"
21
+ :render="render"
22
+ :region="region"
23
+ :view-u-r-l="viewURL"
24
+ @on-ready="onReady"
25
+ @scaffold-selected="onSelected"
26
+ @scaffold-navigated="onNavigated"
27
+ @timeChanged="updateCurrentTime"
28
+ />
29
+ </drop-zone>
24
30
  <el-popover
25
31
  placement="bottom"
26
32
  trigger="click"
@@ -88,7 +94,7 @@
88
94
  Capture
89
95
  </el-button>
90
96
  </el-row>
91
- <el-row :gutter="20">
97
+ <el-row :gutter="10">
92
98
  <el-button
93
99
  size="mini"
94
100
  @click="saveSettings()"
@@ -104,6 +110,12 @@
104
110
  <el-button
105
111
  size="mini"
106
112
  @click="exportGLB()"
113
+ >
114
+ Export GLB
115
+ </el-button>
116
+ <el-button
117
+ size="mini"
118
+ @click="exportGLTF()"
107
119
  >
108
120
  Export GLTF
109
121
  </el-button>
@@ -225,6 +237,7 @@
225
237
  <script>
226
238
  /* eslint-disable no-alert, no-console */
227
239
  import { ScaffoldVuer } from "./components/index.js";
240
+ import DropZone from "./components/DropZone.vue";
228
241
  import ModelsTable from "./components/ModelsTable.vue";
229
242
  import Vue from "vue";
230
243
  import { Button, Col, Icon, Input, InputNumber, Popover, Row, Switch } from "element-ui";
@@ -241,32 +254,10 @@ Vue.use(Popover);
241
254
  Vue.use(Row);
242
255
  Vue.use(Switch);
243
256
 
244
- /*
245
- const alignToObject = function(cameracontrol, scene) {
246
- var object = scene.findGeometriesWithGroupName("Endocardium of left atrium")[0];
247
- const boundingBox = object.getBoundingBox();
248
- if (boundingBox) {
249
- const radius = boundingBox.min.distanceTo(boundingBox.max)/2.0;
250
- const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
251
- const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
252
- const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
253
- const clip_factor = 8.0;
254
- const endingViewport = cameracontrol.getViewportFromCentreAndRadius(centreX, centreY, centreZ, radius, 40, radius * clip_factor );
255
- const startingViewport = cameracontrol.getCurrentViewport();
256
- cameracontrol.cameraTransition(startingViewport, endingViewport, 1500);
257
- cameracontrol.enableCameraTransition();
258
- }
259
- setTimeout(function(){ tumble(cameracontrol) }, 2000);
260
- }
261
-
262
- const tumble = function(cameracontrol) {
263
- cameracontrol.enableAutoTumble();
264
- cameracontrol.autoTumble([1.0, 0.0], Math.PI / 2, true);
265
- }
266
- */
267
257
  export default {
268
258
  name: "App",
269
259
  components: {
260
+ DropZone,
270
261
  ScaffoldVuer,
271
262
  ModelsTable
272
263
  },
@@ -277,10 +268,10 @@ export default {
277
268
  displayUI: true,
278
269
  selectedCoordinates: undefined,
279
270
  helpMode: false,
280
- displayMarkers: true,
271
+ displayMarkers: false,
281
272
  syncMode: false,
282
273
  currentTime: 0,
283
- displayMinimap: true,
274
+ displayMinimap: false,
284
275
  tumbleOn: false,
285
276
  showColourPicker: true,
286
277
  minimapSettings: {
@@ -315,7 +306,6 @@ export default {
315
306
  this.$refs.scaffold.toggleSyncControl(val);
316
307
  }
317
308
  },
318
-
319
309
  mounted: function() {
320
310
  this._sceneSettings = [];
321
311
  this.selectedCoordinates = this.$refs.scaffold.getDynamicSelectedCoordinates();
@@ -371,6 +361,9 @@ export default {
371
361
  cameracontrol.stopAutoTumble();
372
362
  }
373
363
  },
364
+ onReady: function() {
365
+ this.$refs.dropzone.revokeURLs();
366
+ },
374
367
  onSelected: function(data) {
375
368
  if (data && data[0].data.group) {
376
369
  delete this.$route.query["viewURL"];
@@ -380,16 +373,22 @@ export default {
380
373
  }
381
374
  },
382
375
  onNavigated: function(data) {
383
- console.log(data)
384
376
  this.zoom = data.zoom;
385
377
  this.pos[0] = data.target[0];
386
378
  this.pos[1] = data.target[1];
387
379
  },
380
+ onFilesDrop: function(metaURL) {
381
+ this.input = metaURL;
382
+ },
388
383
  parseInput: function() {
389
- if (this.$route.query.url !== this.input)
384
+ if (this.$route.query.url !== this.input) {
385
+ const queries = {...this.$route.query};
386
+ if (this.input && this.input !== "")
387
+ queries.url = this.input;
390
388
  this.$router.replace({
391
389
  query: { ...this.$route.query, url: this.input }
392
390
  });
391
+ }
393
392
  },
394
393
  updateCurrentTime: function(val) {
395
394
  this.currentTime = val;
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <div
3
+ ref="dropEl"
4
+ class="dropzone"
5
+ >
6
+ <slot />
7
+ <input
8
+ ref="fileInput"
9
+ type="file"
10
+ >
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ /* eslint-disable no-alert, no-console */
16
+ import { SimpleDropzone } from "simple-dropzone";
17
+ import path from "path";
18
+
19
+ export default {
20
+ name: "DropZone",
21
+ data: function () {
22
+ return {
23
+ objectURLs: [],
24
+ };
25
+ },
26
+ mounted: function () {
27
+ const dropCtrl = new SimpleDropzone(
28
+ this.$refs.dropEl,
29
+ this.$refs.fileInput
30
+ );
31
+ dropCtrl.on("drop", ({ files }) => {
32
+ this.localDrop(files);
33
+ });
34
+ },
35
+ methods: {
36
+ createObjectURLs: function (text, list) {
37
+ let content = text;
38
+ for (const [key, file] of Object.entries(list)) {
39
+ if (content.includes(key)) {
40
+ const objectURL = URL.createObjectURL(file);
41
+ content = content.replace(key, objectURL);
42
+ this.objectURLs.push(objectURL);
43
+ }
44
+ }
45
+ let blob = new Blob([content], { type: "application/json" });
46
+ const metaURL = URL.createObjectURL(blob);
47
+ this.objectURLs.push(metaURL);
48
+ this.$emit("files-drop", metaURL);
49
+ },
50
+ revokeURLs: function () {
51
+ this.objectURLs.forEach(objectURL => URL.revokeObjectURL(objectURL));
52
+ this.objectURLs = [];
53
+ },
54
+ localDrop: function (fileMap) {
55
+ const dataMaps = {};
56
+ let list = {};
57
+ let metadata = undefined;
58
+ const flatarray = Array.from(fileMap);
59
+ let rootPath = "";
60
+ for (let i = 0; i < flatarray.length; i++) {
61
+ if (flatarray[i][1].name.includes("metadata.json")) {
62
+ rootPath = flatarray[i][0].replace(flatarray[i][1].name, "");
63
+ metadata = { rootPath, file: flatarray[i][1] };
64
+ break;
65
+ }
66
+ }
67
+ if (metadata) {
68
+ flatarray.forEach(([filePath, file]) => {
69
+ if (file.name.match(/\.(json)$/)) {
70
+ const relativePath = path.relative(rootPath, filePath);
71
+ list[relativePath] = file;
72
+ }
73
+ });
74
+ const metaFileURL = URL.createObjectURL(metadata.file);
75
+ fetch(metaFileURL)
76
+ .then((response) => response.text())
77
+ .then((text) => this.createObjectURLs(text, list));
78
+ URL.revokeObjectURL(metaFileURL);
79
+ }
80
+ },
81
+ },
82
+ };
83
+ </script>
84
+
85
+ <style scoped lang="scss">
86
+ .dropzone {
87
+ position: absolute;
88
+ width: 100%;
89
+ height: 100%;
90
+ }
91
+ </style>
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <div :style="position" class="tooltipContainer">
3
+ <el-popover
4
+ ref="tooltip"
5
+ v-model="display"
6
+ placement="top"
7
+ :append-to-body="false"
8
+ trigger="manual"
9
+ popper-class="tooltip-popper non-selectable"
10
+ >
11
+ <div>{{ label }}</div>
12
+ <i v-popover:tooltip />
13
+ </el-popover>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ /* eslint-disable no-alert, no-console */
19
+ import Vue from "vue";
20
+ import { Popover } from "element-ui";
21
+ import lang from "element-ui/lib/locale/lang/en";
22
+ import locale from "element-ui/lib/locale";
23
+
24
+ locale.use(lang);
25
+ Vue.use(Popover);
26
+
27
+ /**
28
+ * A component to control the opacity of the target object.
29
+ */
30
+ export default {
31
+ name: "ScaffoldTooltip",
32
+ props: {
33
+ label: {
34
+ type: String,
35
+ default: "",
36
+ },
37
+ visible: {
38
+ type: Boolean,
39
+ default: false,
40
+ },
41
+ x: {
42
+ type: Number,
43
+ default: 200,
44
+ },
45
+ y: {
46
+ type: Number,
47
+ default: 200,
48
+ },
49
+ },
50
+ data: function () {
51
+ return {
52
+ display: false,
53
+ };
54
+ },
55
+ computed: {
56
+ position: function () {
57
+ return { left: this.x + "px", top: this.y - 30 + "px" };
58
+ },
59
+ },
60
+ watch: {
61
+ label: {
62
+ handler: function () {
63
+ if (this.visible && this.label && this.label !== "")
64
+ this.display = true;
65
+ else this.display = false;
66
+ },
67
+ immediate: true,
68
+ },
69
+ visible: {
70
+ handler: function () {
71
+ if (this.visible && this.label && this.label !== "")
72
+ this.display = true;
73
+ else this.display = false;
74
+ },
75
+ immediate: true,
76
+ },
77
+ },
78
+ };
79
+ </script>
80
+
81
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
82
+ <style scoped lang="scss">
83
+ @import "~element-ui/packages/theme-chalk/src/popover";
84
+
85
+ ::v-deep .tooltip-popper {
86
+ padding: 2px 6px;
87
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
88
+ font-size: 16px;
89
+ color: $app-primary-color;
90
+ background-color: #fff;
91
+ border: 1px solid $app-primary-color;
92
+ border-radius: 4px;
93
+ white-space: nowrap;
94
+ min-width: unset;
95
+ pointer-events: none;
96
+
97
+ &.el-popper[x-placement^="top"] {
98
+ .popper__arrow {
99
+ border-top-color: $app-primary-color !important;
100
+ &:after {
101
+ border-top-color: #fff !important;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ .tooltipContainer {
108
+ position: absolute;
109
+ height: 50px;
110
+ z-index: 2;
111
+ }
112
+
113
+ ::v-deep .non-selectable {
114
+ user-select: none;
115
+ pointer-events: none;
116
+ }
117
+ </style>
@@ -8,6 +8,12 @@
8
8
  element-loading-background="rgba(0, 0, 0, 0.3)"
9
9
  >
10
10
  <map-svg-sprite-color />
11
+ <scaffold-tooltip
12
+ :label="tData.label"
13
+ :visible="tData.visible"
14
+ :x="tData.x"
15
+ :y="tData.y"
16
+ />
11
17
  <div
12
18
  id="organsDisplayArea"
13
19
  ref="display"
@@ -44,8 +50,8 @@
44
50
  trigger="manual"
45
51
  popper-class="scaffold-popper right-popper non-selectable"
46
52
  />
47
- <TraditionalControls
48
- ref="traditionalControl"
53
+ <tree-controls
54
+ ref="treeControl"
49
55
  v-popover:checkBoxPopover
50
56
  :help-mode="helpMode"
51
57
  :module="$module"
@@ -55,7 +61,7 @@
55
61
  @drawer-toggled="drawerToggled"
56
62
  />
57
63
  <div class="opacity-box">
58
- <OpacityControls ref="opacityControl" />
64
+ <opacity-controls ref="opacityControl" />
59
65
  </div>
60
66
  <el-popover
61
67
  v-if="sceneData.timeVarying"
@@ -240,7 +246,8 @@
240
246
  /* eslint-disable no-alert, no-console */
241
247
  import Vue from "vue";
242
248
  import OpacityControls from "./OpacityControls";
243
- import TraditionalControls from "./TraditionalControls";
249
+ import ScaffoldTooltip from "./ScaffoldTooltip";
250
+ import TreeControls from "./TreeControls";
244
251
  import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
245
252
 
246
253
  import {
@@ -275,15 +282,16 @@ const EventNotifier = require("../scripts/eventNotifier").EventNotifier;
275
282
  * A vue component of the scaffold viewer.
276
283
  *
277
284
  * @requires ./OpacityControls.vue
278
- * @requires ./TraditionalControls.vue
285
+ * @requires ./TreeControls.vue
279
286
  */
280
287
  export default {
281
288
  name: "ScaffoldVuer",
282
289
  components: {
283
- OpacityControls,
284
290
  MapSvgIcon,
285
291
  MapSvgSpriteColor,
286
- TraditionalControls
292
+ OpacityControls,
293
+ ScaffoldTooltip,
294
+ TreeControls,
287
295
  },
288
296
  props: {
289
297
  /**
@@ -458,7 +466,14 @@ export default {
458
466
  }
459
467
  ],
460
468
  currentSpeed: 1,
461
- timeStamps: {}
469
+ timeStamps: {},
470
+ defaultCheckedKeys: [],
471
+ tData: {
472
+ label: "",
473
+ visible: false,
474
+ x: 200,
475
+ y: 200
476
+ }
462
477
  };
463
478
  },
464
479
  watch: {
@@ -723,39 +738,47 @@ export default {
723
738
  */
724
739
  eventNotifierCallback: function(event) {
725
740
  if (event.eventType == 1) {
726
- if (this.$refs.traditionalControl) {
741
+ if (this.$refs.treeControl) {
727
742
  if (event.identifiers[0]) {
728
743
  let id = event.identifiers[0].data.id
729
744
  ? event.identifiers[0].data.id
730
745
  : event.identifiers[0].data.group;
731
- this.$refs.traditionalControl.changeActiveByName(id, true);
746
+ let region = event.identifiers[0].data.region;
747
+ this.$refs.treeControl.changeActiveByName(id, region, true);
732
748
  } else {
733
- this.$refs.traditionalControl.removeActive(true);
749
+ this.$refs.treeControl.removeActive(true);
734
750
  }
735
751
  }
736
- /**
737
- * Triggers when an object has been selected
738
- *
739
- * @property {array} identifiers array of identifiers
740
- * of selected object.
741
- */
752
+ // Triggers when an object has been selected
742
753
  this.$emit("scaffold-selected", event.identifiers);
743
754
  } else if (event.eventType == 2) {
744
- if (this.$refs.traditionalControl) {
745
- if (event.identifiers[0]) {
746
- let id = event.identifiers[0].data.id
747
- ? event.identifiers[0].data.id
748
- : event.identifiers[0].data.group;
749
- this.$refs.traditionalControl.changeHoverByName(id, true);
750
- } else this.$refs.traditionalControl.removeHover(true);
755
+ this.tData.visible = false;
756
+ if (event.identifiers[0]) {
757
+ let id = event.identifiers[0].data.id
758
+ ? event.identifiers[0].data.id
759
+ : event.identifiers[0].data.group;
760
+ if (event.identifiers[0].coords) {
761
+ this.tData.visible = true;
762
+ this.tData.label = id;
763
+ this.tData.x = event.identifiers[0].coords.x;
764
+ this.tData.y =event.identifiers[0].coords.y;
765
+ }
766
+ if (this.$refs.treeControl) {
767
+ let region = event.identifiers[0].data.region;
768
+ this.$refs.treeControl.changeHoverByName(id, region, true);
769
+ } else {
770
+ this.$refs.treeControl.removeHover(true);
771
+ }
751
772
  }
752
- /**
753
- * Triggers when an object has been highlighted
754
- *
755
- * @property {array} identifiers array of identifiers
756
- * of highlighted object.
757
- */
773
+ // Triggers when an object has been highlighted
758
774
  this.$emit("scaffold-highlighted", event.identifiers);
775
+ } else if (event.eventType == 3) { //MOVE
776
+ if (event.identifiers[0]) {
777
+ if (event.identifiers[0].coords) {
778
+ this.tData.x = event.identifiers[0].coords.x;
779
+ this.tData.y = event.identifiers[0].coords.y;
780
+ }
781
+ }
759
782
  }
760
783
  },
761
784
  /**
@@ -796,8 +819,8 @@ export default {
796
819
  if (object !== this.selectedObject) {
797
820
  this.selectedObject = object;
798
821
  this.$refs.opacityControl.setObject(this.selectedObject);
799
- if (object) this.$module.setSelectedByZincObject(object, propagate);
800
- else this.$module.setSelectedByObjects([], propagate);
822
+ if (object) this.$module.setSelectedByZincObject(object, undefined, propagate);
823
+ else this.$module.setSelectedByObjects([], undefined, propagate);
801
824
  }
802
825
  },
803
826
  /**
@@ -808,31 +831,31 @@ export default {
808
831
  objectHovered: function(object, propagate) {
809
832
  if (object !== this.hoveredObject) {
810
833
  this.hoveredObject = object;
811
- if (object) this.$module.setHighlightedByZincObject(object, propagate);
812
- else this.$module.setHighlightedByObjects([], propagate);
834
+ if (object) this.$module.setHighlightedByZincObject(object, undefined, propagate);
835
+ else this.$module.setHighlightedByObjects([], undefined, propagate);
813
836
  }
814
837
  },
815
838
  /**
816
839
  * Set the selected by name.
817
840
  *
818
- * @param {name} name Name of the region
841
+ * @param {name} name Name of the group
819
842
  */
820
- changeActiveByName: function(name, propagate) {
843
+ changeActiveByName: function(name, region, propagate) {
821
844
  if (name === undefined)
822
- this.$refs.traditionalControl.removeActive(propagate);
845
+ this.$refs.treeControl.removeActive(propagate);
823
846
  else
824
- this.$refs.traditionalControl.changeActiveByName(name, propagate);
847
+ this.$refs.treeControl.changeActiveByName(name, region, propagate);
825
848
  },
826
849
  /**
827
850
  * Set the highlighted by name.
828
851
  *
829
- * @param {name} name Name of the region
852
+ * @param {name} name Name of the group
830
853
  */
831
- changeHighlightedByName: function(name, propagate) {
854
+ changeHighlightedByName: function(name, region, propagate) {
832
855
  if (name === undefined)
833
- this.$refs.traditionalControl.removeHover(propagate);
856
+ this.$refs.treeControl.removeHover(propagate);
834
857
  else
835
- this.$refs.traditionalControl.changeHoverByName(name, propagate);
858
+ this.$refs.treeControl.changeHoverByName(name, region, propagate);
836
859
  },
837
860
  /**
838
861
  * Start the animation.
@@ -919,7 +942,7 @@ export default {
919
942
  if (options.visibility) {
920
943
  // Some UIs may not be ready at this time.
921
944
  this.$nextTick(() => {
922
- this.$refs.traditionalControl.setState(options.visibility);
945
+ this.$refs.treeControl.setState(options.visibility);
923
946
  });
924
947
  }
925
948
  }
@@ -927,6 +950,7 @@ export default {
927
950
  this.$module.updateTime(0.01);
928
951
  this.$module.updateTime(0);
929
952
  this.$module.unsetFinishDownloadCallback();
953
+ this.$emit("on-ready");
930
954
  this.isReady = true;
931
955
  };
932
956
  },
@@ -942,8 +966,8 @@ export default {
942
966
  viewport: undefined,
943
967
  visibility: undefined
944
968
  };
945
- if (this.$refs.traditionalControl)
946
- state.visibility = this.$refs.traditionalControl.getState();
969
+ if (this.$refs.treeControl)
970
+ state.visibility = this.$refs.treeControl.getState();
947
971
  if (this.$module.scene) {
948
972
  let zincCameraControls = this.$module.scene.getZincCameraControls();
949
973
  state.viewport = zincCameraControls.getCurrentViewport();
@@ -971,7 +995,7 @@ export default {
971
995
  .getZincCameraControls()
972
996
  .setCurrentCameraSettings(state.viewport);
973
997
  if (state.visibility)
974
- this.$refs.traditionalControl.setState(state.visibility);
998
+ this.$refs.treeControl.setState(state.visibility);
975
999
  } else {
976
1000
  this.$module.setFinishDownloadCallback(
977
1001
  this.setURLFinishCallback({
@@ -1000,8 +1024,8 @@ export default {
1000
1024
  let visibility =
1001
1025
  state && state.visibility ? state.visibility : undefined;
1002
1026
  this._currentURL = newValue;
1003
- if (this.$refs.traditionalControl)
1004
- this.$refs.traditionalControl.clear();
1027
+ if (this.$refs.treeControl)
1028
+ this.$refs.treeControl.clear();
1005
1029
  this.loading = true;
1006
1030
  this.isReady = false;
1007
1031
  this.$module.setFinishDownloadCallback(