@abi-software/scaffoldvuer 1.21.1-beta.2 → 2.0.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/README.md +31 -12
- package/dist/index.html +9 -6
- package/dist/scaffoldvuer.js +14095 -13154
- package/dist/scaffoldvuer.umd.cjs +48 -48
- package/dist/style.css +1 -1
- package/eslint.config.js +37 -9
- package/package.json +10 -3
- package/public/index.html +9 -6
- package/src/App.vue +312 -279
- package/src/ScaffoldVuer-wc.js +4 -4
- package/src/app/DropZone.vue +11 -27
- package/src/app/ModelsInformation.js +22 -19
- package/src/app/ModelsTable.vue +42 -65
- package/src/app/TextureDemos.js +38 -64
- package/src/assets/_variables.scss +12 -10
- package/src/components/GlyphsControls.vue +3 -23
- package/src/components/LinesControls.vue +27 -66
- package/src/components/OpacityControls.vue +22 -26
- package/src/components/PointsControls.vue +20 -71
- package/src/components/PrimitiveControls.vue +35 -49
- package/src/components/ScaffoldOverlay.vue +63 -63
- package/src/components/ScaffoldTooltip.vue +36 -49
- package/src/components/ScaffoldTreeControls.vue +81 -129
- package/src/components/ScaffoldVuer.vue +509 -498
- package/src/components/TextureSlidesControls.vue +22 -64
- package/src/components/TransformationControls.vue +15 -42
- package/src/components/index.js +2 -2
- package/src/main.js +16 -18
- package/src/scripts/Annotation.js +3 -3
- package/src/scripts/BaseModule.js +26 -30
- package/src/scripts/EventNotifier.js +30 -36
- package/src/scripts/GraphicsHighlight.js +43 -50
- package/src/scripts/LocalFilesHelper.js +27 -26
- package/src/scripts/MappedNerves.js +2139 -697
- package/src/scripts/MappedOrgans.js +24 -25
- package/src/scripts/OrgansRenderer.js +445 -425
- package/src/scripts/RendererModule.js +133 -122
- package/src/scripts/Search.js +135 -151
- package/src/scripts/Utilities.js +129 -127
- package/src/scripts/WebGL.js +57 -91
- package/src/scripts/niftiHelper.js +3 -3
- package/src/store/index.js +7 -7
- package/vite.config.js +51 -50
- package/vite.static-build.js +7 -7
- package/vuese-generator.js +48 -56
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
ref="overlay"
|
|
4
|
-
>
|
|
2
|
+
<div ref="overlay">
|
|
5
3
|
<div
|
|
6
|
-
class="content-layer"
|
|
4
|
+
class="content-layer"
|
|
5
|
+
ref="contentLayer"
|
|
7
6
|
@mouseleave.capture="skipWhenInBound"
|
|
8
7
|
@mousedown.capture="(event) => contentMouseActive(event, true)"
|
|
9
8
|
@mouseup.capture="(event) => contentMouseActive(event, false)"
|
|
@@ -12,7 +11,9 @@
|
|
|
12
11
|
>
|
|
13
12
|
<slot />
|
|
14
13
|
</div>
|
|
15
|
-
<div
|
|
14
|
+
<div
|
|
15
|
+
v-if="positionalRotation"
|
|
16
|
+
ref="topLayer"
|
|
16
17
|
@mousemove.capture="forwardEvent"
|
|
17
18
|
@mouseover.capture="forwardEvent"
|
|
18
19
|
@touchmove.capture="forwardTouchEvent"
|
|
@@ -22,21 +23,28 @@
|
|
|
22
23
|
v-for="overlay in rotationOverlays"
|
|
23
24
|
:key="overlay.position"
|
|
24
25
|
:class="['rotation-overlay', overlay.position, touchActive ? 'touch-active' : '']"
|
|
25
|
-
@mousedown="
|
|
26
|
+
@mousedown="
|
|
27
|
+
(event) => {
|
|
28
|
+
setRotationMode(event, overlay.mode);
|
|
29
|
+
forwardEvent(event);
|
|
30
|
+
}
|
|
31
|
+
"
|
|
26
32
|
@mouseup="forwardEvent"
|
|
27
|
-
@touchstart="
|
|
33
|
+
@touchstart="
|
|
34
|
+
(event) => {
|
|
35
|
+
setRotationMode(event, overlay.mode);
|
|
36
|
+
forwardTouchEvent(event);
|
|
37
|
+
}
|
|
38
|
+
"
|
|
28
39
|
@touchend="forwardTouchEvent"
|
|
29
40
|
>
|
|
30
41
|
<span>{{ overlay.text }}</span>
|
|
31
42
|
</div>
|
|
32
43
|
</div>
|
|
33
|
-
|
|
34
44
|
</div>
|
|
35
45
|
</template>
|
|
36
46
|
|
|
37
47
|
<script>
|
|
38
|
-
/* eslint-disable no-alert, no-console */
|
|
39
|
-
|
|
40
48
|
const rotationOverlays = [
|
|
41
49
|
{ position: 'top', mode: 'vertical', text: 'Begin interaction here to rotate on the x-axis' },
|
|
42
50
|
{ position: 'bottom', mode: 'vertical', text: 'Begin interaction here to rotate on the x-axis' },
|
|
@@ -45,48 +53,47 @@ const rotationOverlays = [
|
|
|
45
53
|
];
|
|
46
54
|
|
|
47
55
|
export default {
|
|
48
|
-
name:
|
|
56
|
+
name: 'ScaffoldOverlay',
|
|
49
57
|
data: function () {
|
|
50
58
|
return {
|
|
51
59
|
lockRotationMode: false,
|
|
52
60
|
touchActive: false,
|
|
53
61
|
rotationOverlays: rotationOverlays,
|
|
54
|
-
}
|
|
62
|
+
};
|
|
55
63
|
},
|
|
56
64
|
props: {
|
|
57
65
|
/**
|
|
58
66
|
* Experimental feature to restrict rotation at
|
|
59
67
|
* one-axis based on position of the initial click
|
|
60
68
|
*/
|
|
61
|
-
|
|
69
|
+
positionalRotation: {
|
|
62
70
|
type: Boolean,
|
|
63
71
|
default: false,
|
|
64
72
|
},
|
|
65
73
|
},
|
|
66
74
|
methods: {
|
|
67
|
-
contentMouseActive: function(event, flag) {
|
|
75
|
+
contentMouseActive: function (event, flag) {
|
|
68
76
|
if (this.positionalRotation) {
|
|
69
77
|
const topLayer = this.$refs.topLayer;
|
|
70
78
|
if (topLayer) {
|
|
71
79
|
if (!flag) {
|
|
72
80
|
this.lockRotationMode = false;
|
|
73
|
-
this.setRotationMode(undefined,
|
|
81
|
+
this.setRotationMode(undefined, 'free');
|
|
74
82
|
topLayer.style.pointerEvents = 'auto';
|
|
75
|
-
if (event.type ===
|
|
83
|
+
if (event.type === 'touchend') {
|
|
76
84
|
this.touchActive = false;
|
|
77
85
|
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
86
|
+
} else {
|
|
80
87
|
this.lockRotationMode = true;
|
|
81
88
|
topLayer.style.pointerEvents = 'none';
|
|
82
|
-
if (event.type ===
|
|
89
|
+
if (event.type === 'touchstart') {
|
|
83
90
|
this.touchActive = true;
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
},
|
|
89
|
-
setRotationMode: function(event, mode) {
|
|
96
|
+
setRotationMode: function (event, mode) {
|
|
90
97
|
if (!this.lockRotationMode) {
|
|
91
98
|
this.$emit('onRotationModeChange', mode);
|
|
92
99
|
}
|
|
@@ -95,7 +102,7 @@ export default {
|
|
|
95
102
|
event.stopPropagation();
|
|
96
103
|
}
|
|
97
104
|
},
|
|
98
|
-
skipWhenInBound: function(event) {
|
|
105
|
+
skipWhenInBound: function (event) {
|
|
99
106
|
if (this.positionalRotation) {
|
|
100
107
|
const topLayer = this.$refs.topLayer;
|
|
101
108
|
const contentLayer = this.$refs.contentLayer;
|
|
@@ -110,7 +117,7 @@ export default {
|
|
|
110
117
|
}
|
|
111
118
|
}
|
|
112
119
|
},
|
|
113
|
-
forwardEvent: function(event) {
|
|
120
|
+
forwardEvent: function (event) {
|
|
114
121
|
const topLayer = this.$refs.topLayer;
|
|
115
122
|
if (!topLayer) return;
|
|
116
123
|
// Find the element directly underneath the cursor
|
|
@@ -125,23 +132,20 @@ export default {
|
|
|
125
132
|
if (elementBelow) {
|
|
126
133
|
// We create a new MouseEvent, copying the properties from the original event.
|
|
127
134
|
// This is more robust than dispatching the original event itself.
|
|
128
|
-
const newEvent = new MouseEvent(
|
|
129
|
-
event.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
button: event.button,
|
|
137
|
-
}
|
|
138
|
-
);
|
|
135
|
+
const newEvent = new MouseEvent(event.type, {
|
|
136
|
+
bubbles: event.bubbles,
|
|
137
|
+
cancelable: event.cancelable,
|
|
138
|
+
view: event.view,
|
|
139
|
+
clientX: event.clientX,
|
|
140
|
+
clientY: event.clientY,
|
|
141
|
+
button: event.button,
|
|
142
|
+
});
|
|
139
143
|
elementBelow.dispatchEvent(newEvent);
|
|
140
144
|
event.stopPropagation();
|
|
141
145
|
}
|
|
142
146
|
event.preventDefault();
|
|
143
147
|
},
|
|
144
|
-
forwardTouchEvent: function(event) {
|
|
148
|
+
forwardTouchEvent: function (event) {
|
|
145
149
|
const topLayer = this.$refs.topLayer;
|
|
146
150
|
if (!topLayer) return;
|
|
147
151
|
// Find the element directly underneath the cursor
|
|
@@ -167,69 +171,66 @@ export default {
|
|
|
167
171
|
rotationAngle: firstTouch.rotationAngle,
|
|
168
172
|
force: firstTouch.force,
|
|
169
173
|
});
|
|
170
|
-
const newEvent = new TouchEvent(
|
|
171
|
-
event.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
changedTouches: [newTouch],
|
|
180
|
-
}
|
|
181
|
-
);
|
|
174
|
+
const newEvent = new TouchEvent(event.type, {
|
|
175
|
+
bubbles: event.bubbles,
|
|
176
|
+
cancelable: event.cancelable,
|
|
177
|
+
composed: true,
|
|
178
|
+
view: event.view,
|
|
179
|
+
touches: [newTouch],
|
|
180
|
+
targetTouches: [newTouch],
|
|
181
|
+
changedTouches: [newTouch],
|
|
182
|
+
});
|
|
182
183
|
elementBelow.dispatchEvent(newEvent);
|
|
183
184
|
event.stopPropagation();
|
|
184
185
|
}
|
|
185
186
|
event.preventDefault();
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
};
|
|
189
190
|
</script>
|
|
190
191
|
|
|
191
192
|
<style scoped lang="scss">
|
|
192
193
|
.rotation-overlay {
|
|
193
194
|
z-index: 1;
|
|
194
195
|
background-color: transparent;
|
|
195
|
-
position:absolute;
|
|
196
|
+
position: absolute;
|
|
196
197
|
opacity: 0;
|
|
197
198
|
&.touch-active {
|
|
198
199
|
opacity: 1;
|
|
199
|
-
background-color: rgba(173,216,230, 0.1)
|
|
200
|
+
background-color: rgba(173, 216, 230, 0.1);
|
|
200
201
|
}
|
|
201
202
|
&:hover {
|
|
202
203
|
opacity: 1;
|
|
203
|
-
background-color: rgba(173,216,230, 0.1)
|
|
204
|
+
background-color: rgba(173, 216, 230, 0.1);
|
|
204
205
|
}
|
|
205
206
|
&.top {
|
|
206
|
-
top:0%;
|
|
207
|
-
height:20%;
|
|
207
|
+
top: 0%;
|
|
208
|
+
height: 20%;
|
|
208
209
|
left: 35%;
|
|
209
210
|
width: 30%;
|
|
210
211
|
}
|
|
211
212
|
&.bottom {
|
|
212
|
-
bottom:0%;
|
|
213
|
-
height:20%;
|
|
213
|
+
bottom: 0%;
|
|
214
|
+
height: 20%;
|
|
214
215
|
left: 35%;
|
|
215
216
|
width: 30%;
|
|
216
217
|
}
|
|
217
218
|
&.left {
|
|
218
|
-
top:35%;
|
|
219
|
-
height:30%;
|
|
219
|
+
top: 35%;
|
|
220
|
+
height: 30%;
|
|
220
221
|
left: 0%;
|
|
221
222
|
width: 20%;
|
|
222
223
|
}
|
|
223
224
|
&.right {
|
|
224
|
-
top:35%;
|
|
225
|
-
height:30%;
|
|
225
|
+
top: 35%;
|
|
226
|
+
height: 30%;
|
|
226
227
|
right: 0%;
|
|
227
228
|
width: 20%;
|
|
228
229
|
}
|
|
229
230
|
span {
|
|
230
231
|
position: relative;
|
|
231
|
-
color:black;
|
|
232
|
-
opacity:0.5;
|
|
232
|
+
color: black;
|
|
233
|
+
opacity: 0.5;
|
|
233
234
|
top: 50%;
|
|
234
235
|
text-shadow:
|
|
235
236
|
-1px -1px 0 white,
|
|
@@ -243,5 +244,4 @@ export default {
|
|
|
243
244
|
width: 100%;
|
|
244
245
|
height: 100%;
|
|
245
246
|
}
|
|
246
|
-
|
|
247
247
|
</style>
|
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
>
|
|
14
14
|
<template #default>
|
|
15
15
|
<div class="tooltip-text">{{ label }}</div>
|
|
16
|
-
<div class="tooltip-text" v-if="region && region != '/'">
|
|
17
|
-
Region: {{ region }}
|
|
18
|
-
</div>
|
|
16
|
+
<div class="tooltip-text" v-if="region && region != '/'">Region: {{ region }}</div>
|
|
19
17
|
<CreateTooltipContent
|
|
20
18
|
v-show="createData.toBeConfirmed"
|
|
21
19
|
:createData="createData"
|
|
@@ -38,53 +36,41 @@
|
|
|
38
36
|
</template>
|
|
39
37
|
|
|
40
38
|
<script>
|
|
41
|
-
import { shallowRef } from 'vue';
|
|
42
|
-
/* eslint-disable no-alert, no-console */
|
|
43
|
-
import {
|
|
44
|
-
ElCol as Col,
|
|
45
|
-
ElIcon as Icon,
|
|
46
|
-
ElPopover as Popover,
|
|
47
|
-
ElRow as Row,
|
|
48
|
-
} from "element-plus";
|
|
49
39
|
import { mapState } from 'pinia';
|
|
50
|
-
import { useMainStore } from
|
|
51
|
-
import { CreateTooltipContent, Tooltip } from '@abi-software/map-utilities'
|
|
52
|
-
import '@abi-software/map-utilities/dist/style.css'
|
|
40
|
+
import { useMainStore } from '@/store/index';
|
|
41
|
+
import { CreateTooltipContent, Tooltip } from '@abi-software/map-utilities';
|
|
42
|
+
import '@abi-software/map-utilities/dist/style.css';
|
|
53
43
|
|
|
54
44
|
/**
|
|
55
45
|
* A component to control the opacity of the target object.
|
|
56
46
|
*/
|
|
57
47
|
export default {
|
|
58
|
-
name:
|
|
48
|
+
name: 'ScaffoldTooltip',
|
|
59
49
|
components: {
|
|
60
|
-
Col,
|
|
61
50
|
CreateTooltipContent,
|
|
62
|
-
Icon,
|
|
63
|
-
Popover,
|
|
64
|
-
Row,
|
|
65
51
|
Tooltip,
|
|
66
52
|
},
|
|
67
53
|
props: {
|
|
68
54
|
createData: {
|
|
69
55
|
type: Object,
|
|
70
|
-
default:{
|
|
56
|
+
default: () => ({
|
|
71
57
|
drawingBox: false,
|
|
72
58
|
renaming: false,
|
|
73
59
|
toBeConfirmed: false,
|
|
74
60
|
points: [],
|
|
75
61
|
tempGroupName: undefined,
|
|
76
|
-
shape:
|
|
62
|
+
shape: '',
|
|
77
63
|
x: 0,
|
|
78
64
|
y: 0,
|
|
79
65
|
editingIndex: -1,
|
|
80
66
|
faceIndex: -1,
|
|
81
67
|
toBeDeleted: false,
|
|
82
|
-
regionPrefix:
|
|
83
|
-
},
|
|
68
|
+
regionPrefix: '__annotation',
|
|
69
|
+
}),
|
|
84
70
|
},
|
|
85
71
|
label: {
|
|
86
72
|
type: String,
|
|
87
|
-
default:
|
|
73
|
+
default: '',
|
|
88
74
|
},
|
|
89
75
|
annotationDisplay: {
|
|
90
76
|
type: Boolean,
|
|
@@ -92,7 +78,7 @@ export default {
|
|
|
92
78
|
},
|
|
93
79
|
annotationFeature: {
|
|
94
80
|
type: Object,
|
|
95
|
-
default: {},
|
|
81
|
+
default: () => ({}),
|
|
96
82
|
},
|
|
97
83
|
offlineAnnotationEnabled: {
|
|
98
84
|
type: Boolean,
|
|
@@ -100,7 +86,7 @@ export default {
|
|
|
100
86
|
},
|
|
101
87
|
region: {
|
|
102
88
|
type: String,
|
|
103
|
-
default:
|
|
89
|
+
default: '',
|
|
104
90
|
},
|
|
105
91
|
visible: {
|
|
106
92
|
type: Boolean,
|
|
@@ -124,41 +110,42 @@ export default {
|
|
|
124
110
|
data: function () {
|
|
125
111
|
return {
|
|
126
112
|
display: false,
|
|
127
|
-
annotationEntry: []
|
|
113
|
+
annotationEntry: [],
|
|
128
114
|
};
|
|
129
115
|
},
|
|
130
116
|
computed: {
|
|
131
|
-
...mapState(useMainStore,
|
|
117
|
+
...mapState(useMainStore, ['userToken']),
|
|
132
118
|
position: function () {
|
|
133
119
|
let yOffset = 40;
|
|
134
120
|
if (this.region) {
|
|
135
121
|
yOffset = 55;
|
|
136
122
|
}
|
|
137
123
|
const x = this.x - 40;
|
|
138
|
-
return { left: x +
|
|
124
|
+
return { left: x + 'px', top: this.y - yOffset + 'px' };
|
|
139
125
|
},
|
|
140
126
|
},
|
|
141
127
|
methods: {
|
|
142
128
|
checkForDisplay: function () {
|
|
143
|
-
if (this.visible && this.label && this.label !==
|
|
129
|
+
if (this.visible && this.label && this.label !== '') {
|
|
144
130
|
this.display = true;
|
|
145
131
|
if (this.annotationDisplay) {
|
|
146
|
-
const region = this.region ? this.region +
|
|
147
|
-
this.annotationEntry = [
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
132
|
+
const region = this.region ? this.region + '/' : '';
|
|
133
|
+
this.annotationEntry = [
|
|
134
|
+
{
|
|
135
|
+
featureId: region + this.label,
|
|
136
|
+
resourceId: this.scaffoldUrl,
|
|
137
|
+
resource: this.scaffoldUrl,
|
|
138
|
+
feature: this.annotationFeature,
|
|
139
|
+
offline: this.offlineAnnotationEnabled,
|
|
140
|
+
},
|
|
141
|
+
];
|
|
154
142
|
}
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
143
|
+
} else {
|
|
157
144
|
this.display = false;
|
|
158
145
|
this.annotationEntry = [];
|
|
159
146
|
}
|
|
160
147
|
},
|
|
161
|
-
hideTriggered: function() {
|
|
148
|
+
hideTriggered: function () {
|
|
162
149
|
this.$emit('tooltip-hide');
|
|
163
150
|
},
|
|
164
151
|
},
|
|
@@ -180,14 +167,13 @@ export default {
|
|
|
180
167
|
this.checkForDisplay();
|
|
181
168
|
},
|
|
182
169
|
immediate: true,
|
|
183
|
-
}
|
|
170
|
+
},
|
|
184
171
|
},
|
|
185
172
|
};
|
|
186
173
|
</script>
|
|
187
174
|
|
|
188
175
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
189
176
|
<style scoped lang="scss">
|
|
190
|
-
|
|
191
177
|
.region-tooltip {
|
|
192
178
|
position: absolute;
|
|
193
179
|
height: 50px;
|
|
@@ -201,9 +187,9 @@ export default {
|
|
|
201
187
|
border: 1px solid $app-primary-color;
|
|
202
188
|
border-radius: 4px;
|
|
203
189
|
white-space: nowrap;
|
|
204
|
-
min-width: unset!important;
|
|
205
|
-
max-width:fit-content;
|
|
206
|
-
width:unset!important;
|
|
190
|
+
min-width: unset !important;
|
|
191
|
+
max-width: fit-content;
|
|
192
|
+
width: unset !important;
|
|
207
193
|
pointer-events: none;
|
|
208
194
|
top: -15px !important;
|
|
209
195
|
.el-popper__arrow {
|
|
@@ -226,12 +212,13 @@ export default {
|
|
|
226
212
|
.p-tooltip {
|
|
227
213
|
display: flex;
|
|
228
214
|
width: 300px;
|
|
229
|
-
white-space:normal;
|
|
215
|
+
white-space: normal;
|
|
230
216
|
.attribute-content {
|
|
231
217
|
color: rgb(44, 62, 80);
|
|
232
218
|
}
|
|
233
|
-
&::before,
|
|
234
|
-
|
|
219
|
+
&::before,
|
|
220
|
+
&::after {
|
|
221
|
+
display: none;
|
|
235
222
|
}
|
|
236
223
|
}
|
|
237
224
|
}
|