@abi-software/scaffoldvuer 1.18.0 → 1.19.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.
@@ -0,0 +1,23 @@
1
+ import js from "@eslint/js";
2
+ import vue from "eslint-plugin-vue";
3
+ import globals from "globals";
4
+
5
+ export default [
6
+ {
7
+ ignores: ["dist/**", "docs/.vitepress/**", "docs/components/**"],
8
+ },
9
+ js.configs.recommended,
10
+ ...vue.configs["flat/essential"],
11
+ {
12
+ files: ["**/*.{js,vue}"],
13
+ languageOptions: {
14
+ ecmaVersion: "latest",
15
+ sourceType: "module",
16
+ globals: {
17
+ ...globals.node,
18
+ ...globals.browser,
19
+ },
20
+ },
21
+ rules: {},
22
+ },
23
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/scaffoldvuer",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "license": "Apache-2.0",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -13,6 +13,7 @@
13
13
  "serve": "vite --host --force",
14
14
  "build-bundle": "vite build",
15
15
  "build-static": "vite build -c vite.static-build.js",
16
+ "lint": "eslint .",
16
17
  "vuese-gen": "node vuese-generator.js",
17
18
  "vuese-watch": "node vuese-generator.js watch",
18
19
  "changelog": "auto-changelog -p --output CHANGELOG.md --template keepachangelog",
@@ -44,54 +45,44 @@
44
45
  "*.js"
45
46
  ],
46
47
  "dependencies": {
47
- "@abi-software/map-utilities": "1.9.0",
48
+ "@abi-software/map-utilities": "1.10.0",
48
49
  "@abi-software/sparc-annotation": "^0.3.2",
49
- "@abi-software/svg-sprite": "1.1.0",
50
- "@element-plus/icons-vue": "^2.3.1",
51
- "core-js": "^3.22.5",
52
- "element-plus": "2.8.4",
53
- "minisearch": "^6.0.1",
54
- "pinia": "^2.1.7",
50
+ "@abi-software/svg-sprite": "1.2.0",
51
+ "@element-plus/icons-vue": "^2.3.2",
52
+ "core-js": "^3.50.0",
53
+ "element-plus": "^2.14.5",
54
+ "minisearch": "^7.2.0",
55
+ "pinia": "^4.0.3",
55
56
  "simple-dropzone": "^0.8.3",
56
- "unplugin-vue-components": "^0.26.0",
57
- "vue": "^3.4.21",
58
- "vue-router": "^4.2.5",
59
- "zincjs": "^2.0.1"
57
+ "vue": "^3.5.41",
58
+ "vue-router": "^5.2.0",
59
+ "zincjs": "^2.2.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@babel/eslint-parser": "^7.28.0",
63
- "@vitejs/plugin-vue": "^4.6.2",
62
+ "@eslint/js": "^10.0.1",
63
+ "@babel/eslint-parser": "^8.0.1",
64
+ "@vitejs/plugin-vue": "^6.0.8",
65
+ "unplugin-vue-components": "^32.1.0",
64
66
  "@vuese/markdown-render": "^2.11.3",
65
- "auto-changelog": "^2.4.0",
67
+ "auto-changelog": "^2.6.0",
66
68
  "babel-plugin-component": "^1.1.1",
67
- "chokidar": "^3.6.0",
68
- "concurrently": "^8.2.2",
69
- "eslint": "^9.34.0",
70
- "eslint-plugin-vue": "^9.19.2",
71
- "sass": "^1.69.5",
72
- "vite": "^5.0.10",
73
- "vite-plugin-node-polyfills": "^0.21.0",
74
- "vitepress": "^1.0.0-rc.42",
69
+ "chokidar": "^5.0.0",
70
+ "concurrently": "^9.2.4",
71
+ "eslint": "^10.9.1",
72
+ "eslint-plugin-vue": "^10.10.0",
73
+ "globals": "^17.11.0",
74
+ "sass": "^1.103.1",
75
+ "vite": "^8.2.1",
76
+ "vite-plugin-node-polyfills": "^0.28.0",
77
+ "vitepress": "^1.6.4",
75
78
  "vue-docgen-api": "^4.79.2"
76
79
  },
77
80
  "optionalDependencies": {
78
- "@rollup/rollup-darwin-arm64": "4.62.3",
79
- "@rollup/rollup-linux-x64-gnu": "4.62.3",
80
- "@rollup/rollup-win32-x64-msvc": "4.62.3"
81
- },
82
- "eslintConfig": {
83
- "root": true,
84
- "env": {
85
- "node": true
86
- },
87
- "extends": [
88
- "plugin:vue/essential",
89
- "eslint:recommended"
90
- ],
91
- "rules": {},
92
- "parserOptions": {
93
- "parser": "babel-eslint"
94
- }
81
+ "@esbuild/darwin-arm64": "0.28.2",
82
+ "@esbuild/linux-x64": "0.28.2",
83
+ "@rollup/rollup-darwin-arm64": "4.63.0",
84
+ "@rollup/rollup-linux-x64-gnu": "4.63.0",
85
+ "@rollup/rollup-win32-x64-msvc": "4.63.0"
95
86
  },
96
87
  "browserslist": [
97
88
  "> 1%",
package/src/App.vue CHANGED
@@ -50,7 +50,7 @@
50
50
  @show-next="onHelpModeShowNext"
51
51
  @finish-help-mode="onFinishHelpMode"
52
52
  />
53
- <el-popover popper-class="options-container" placement="bottom" trigger="click" width="500" :teleported="false">
53
+ <el-popover popper-class="options-container" placement="bottom" trigger="hover" width="500" :teleported="false">
54
54
  <div>
55
55
  <el-row :gutter="20">
56
56
  <el-col>
@@ -115,7 +115,9 @@
115
115
  </el-button>
116
116
  </el-col>
117
117
  <el-col :span="auto">
118
- <el-button size="small" @click="screenCapture()"> Capture </el-button>
118
+ <el-button type="primary" size="small" @click="screenshotDialog = true">
119
+ Screenshot
120
+ </el-button>
119
121
  </el-col>
120
122
  </el-row>
121
123
 
@@ -299,7 +301,7 @@
299
301
  </el-button>
300
302
  </template>
301
303
  </el-popover>
302
- <el-popover placement="bottom" trigger="click" width="800" popper-class="table-popover" :teleported="false">
304
+ <el-popover placement="bottom" trigger="hover" width="800" popper-class="table-popover" :teleported="false">
303
305
  <template #default>
304
306
  <Suspense>
305
307
  <ModelsTable @viewModelClicked="viewModelClicked" />
@@ -320,6 +322,64 @@
320
322
  </div>
321
323
  </template>
322
324
  </el-autocomplete>
325
+ <el-dialog
326
+ v-model="screenshotDialog"
327
+ title="Screenshot Settings"
328
+ width="450px"
329
+ destroy-on-close
330
+ >
331
+ <el-form
332
+ ref="formRef"-
333
+ :model="screenshotData"
334
+ :rules="rules"
335
+ label-width="100px"
336
+ status-icon
337
+ >
338
+ <!-- Filename Field -->
339
+ <el-form-item label="Filename" prop="filename">
340
+ <el-input
341
+ v-model="screenshotData.filename"
342
+ placeholder="scaffold"
343
+ >
344
+ <template #append>.png</template>
345
+ </el-input>
346
+ </el-form-item>
347
+
348
+ <!-- Width Field -->
349
+ <el-form-item label="Width (px)" prop="width">
350
+ <el-input-number
351
+ v-model="screenshotData.width"
352
+ :min="100"
353
+ :max="7680"
354
+ :step="100"
355
+ controls-position="right"
356
+ style="width: 100%"
357
+ />
358
+ </el-form-item>
359
+
360
+ <!-- Height Field -->
361
+ <el-form-item label="Height (px)" prop="height">
362
+ <el-input-number
363
+ v-model="screenshotData.height"
364
+ :min="100"
365
+ :max="4320"
366
+ :step="100"
367
+ controls-position="right"
368
+ style="width: 100%"
369
+ />
370
+ </el-form-item>
371
+ </el-form>
372
+
373
+ <!-- Dialog Footer Action Buttons -->
374
+ <template #footer>
375
+ <span class="dialog-footer">
376
+ <el-button @click="screenCancel">Cancel</el-button>
377
+ <el-button type="primary" :loading="loading" @click="screenCapture">
378
+ Capture
379
+ </el-button>
380
+ </span>
381
+ </template>
382
+ </el-dialog>
323
383
  </div>
324
384
  </template>
325
385
 
@@ -435,6 +495,7 @@ export default {
435
495
  helpModeLastItem: false,
436
496
  useHelpModeDialog: true,
437
497
  scaffoldRef: null,
498
+ screenshotDialog: false,
438
499
  route: useRoute(),
439
500
  router: useRouter(),
440
501
  ElIconSetting: shallowRef(ElIconSetting),
@@ -443,9 +504,24 @@ export default {
443
504
  annotator: markRaw(new AnnotationService(`https://mapcore-demo.org/devel/flatmap/v4/annotator`)),
444
505
  fitBoundingBox: false,
445
506
  usageConfig: {
507
+ tubeLines: false,
446
508
  showTubeLinesControls: true
447
509
  },
448
- };
510
+ screenshotData: {
511
+ filename: "screenshot",
512
+ width: 1920,
513
+ height: 1080
514
+ },
515
+ wholeBody: false,
516
+ rules: {
517
+ filename: [
518
+ { required: true, message: 'Please enter a filename', trigger: 'blur' },
519
+ { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Filename can only contain letters, numbers, hyphens, and underscores', trigger: 'blur' } ],
520
+ width: [ { required: true, message: 'Please specify width', trigger: 'change' } ],
521
+ height: [ { required: true, message: 'Please specify height', trigger: 'change' }
522
+ ]
523
+ }
524
+ }
449
525
  },
450
526
  watch: {
451
527
  input: function () {
@@ -544,6 +620,12 @@ export default {
544
620
  if (zincObject.isGeometry) {
545
621
  zincObject._lod._material.wireframe = this.wireframe;
546
622
  }
623
+ if (this.wholeBody) {
624
+ if (zincObject.getRegion().getName() === "Nerves") {
625
+ zincObject.setGreyScale(true);
626
+ }
627
+ }
628
+
547
629
  this._objects.push(zincObject);
548
630
  },
549
631
  openMap: function (map) {
@@ -671,8 +753,16 @@ export default {
671
753
  userPrimitivesUpdated: function (event) {
672
754
  console.log(event);
673
755
  },
756
+ screenCancel: function () {
757
+ this.screenshotDialog = false;
758
+ },
674
759
  screenCapture: function () {
675
- this.$refs.scaffold.captureScreenshot("capture.png");
760
+ this.$refs.scaffold.captureScreenshot(
761
+ this.screenshotData.filename,
762
+ this.screenshotData.width,
763
+ this.screenshotData.height,
764
+ );
765
+ this.screenshotDialog = false;
676
766
  },
677
767
  setSceneToWindo: function () {
678
768
  window.scene = this.$refs.scaffold.$module.scene;
@@ -839,6 +929,12 @@ export default {
839
929
  } else {
840
930
  this.viewURL = "";
841
931
  }
932
+
933
+ if (query.wholeBody && query.wholeBody === "true") {
934
+ console.log("wholebody", query.wholeBody)
935
+ this.wholeBody = true;
936
+ this.usageConfig.tubeLines = true;
937
+ }
842
938
  })
843
939
  },
844
940
  onHelpModeShowNext: function () {
@@ -1,6 +1,7 @@
1
- @import url('https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap');
1
+ @use '_variables' as *;
2
+ @forward '_variables';
2
3
 
3
- @import '_variables';
4
+ @import url('https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap');
4
5
 
5
6
  /* icon font path, required */
6
7
  $--color-primary: $app-primary-color !default;
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <el-container class="glyph-container">
3
+ <el-checkbox
4
+ v-model="displayLabels"
5
+ class="block"
6
+ >
7
+ Display labels
8
+ </el-checkbox>
9
+ </el-container>
10
+ </template>
11
+
12
+ <script>
13
+ /* eslint-disable no-alert, no-console */
14
+ import { markRaw } from 'vue';
15
+ import {
16
+ ElCheckbox as Checkbox,
17
+ ElContainer as Container,
18
+ ElMain as Main,
19
+ } from "element-plus";
20
+
21
+ /**
22
+ * A component to control the opacity of the target object.
23
+ */
24
+ export default {
25
+ name: "GlyphsControls",
26
+ components: {
27
+ Checkbox,
28
+ Container,
29
+ Main,
30
+ },
31
+ data: function () {
32
+ return {
33
+ displayLabels: true,
34
+ };
35
+ },
36
+ watch: {
37
+ displayLabels: {
38
+ handler: function (value) {
39
+ if (value) {
40
+ this.zincObject.showLabel();
41
+ } else {
42
+ this.zincObject.hideLabel();
43
+ }
44
+ },
45
+ },
46
+ },
47
+ methods: {
48
+ reset: function() {
49
+ this.displayLabels = true;
50
+ },
51
+ setObject: function (object) {
52
+ if (object.isGlyphset) {
53
+ this.zincObject = markRaw(object);
54
+ this.displayLabels = this.zincObject.isLabelDisplayed();
55
+ } else {
56
+ this.zincObject = undefined;
57
+ }
58
+ },
59
+ },
60
+ };
61
+ </script>
62
+
63
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
64
+ <style scoped lang="scss">
65
+
66
+ .block {
67
+ left: 40px;
68
+ :deep(.el-checkbox__label) {
69
+ font-size: 13px;
70
+ }
71
+ }
72
+
73
+ .glyph-container {
74
+ width: 250px;
75
+ height: auto;
76
+ overflow-y: none;
77
+ }
78
+
79
+
80
+
81
+ </style>
@@ -24,6 +24,13 @@
24
24
  @primitivesUpdated="$emit('primitivesUpdated', $event)"
25
25
  />
26
26
  </el-collapse-item>
27
+ <el-collapse-item v-show="isGlyph" title="Glyphset" name="gControls">
28
+ <glyphs-controls
29
+ class="glyph-controls"
30
+ ref="glyphControls"
31
+ @primitivesUpdated="$emit('primitivesUpdated', $event)"
32
+ />
33
+ </el-collapse-item>
27
34
  <el-collapse-item v-show="isLines" title="Lines" name="lControls">
28
35
  <lines-controls
29
36
  class="lines-controls"
@@ -51,6 +58,7 @@ import {
51
58
  import OpacityControls from "./OpacityControls.vue";
52
59
  import PointsControls from "./PointsControls.vue";
53
60
  import LinesControls from "./LinesControls.vue";
61
+ import GlyphsControls from "./GlyphsControls.vue";
54
62
  import TextureSlidesControls from "./TextureSlidesControls.vue";
55
63
  import TransformationControls from "./TransformationControls.vue";
56
64
 
@@ -62,6 +70,7 @@ export default {
62
70
  components: {
63
71
  Collapse,
64
72
  CollapseItem,
73
+ GlyphsControls,
65
74
  LinesControls,
66
75
  OpacityControls,
67
76
  PointsControls,
@@ -88,7 +97,7 @@ export default {
88
97
  isTextureSlides: false,
89
98
  isPointset: false,
90
99
  isLines: false,
91
-
100
+ isGlyph: false,
92
101
  zincObject: undefined,
93
102
  isEditable: false,
94
103
  displayString: "100%"
@@ -117,6 +126,7 @@ export default {
117
126
  this.isPointset = false;
118
127
  this.isTextureSlides = false;
119
128
  this.isLines = false;
129
+ this.isGlyph = false,
120
130
  this.activeName = "trControls";
121
131
  if (object) {
122
132
  if (object.isTextureSlides) {
@@ -132,6 +142,12 @@ export default {
132
142
  this.isLines = true;
133
143
  this.$refs.linesControls.setObject(object);
134
144
  this.activeName = "lControls";
145
+ } else if (object.isGlyphset) {
146
+ if (object.canShowLabel()) {
147
+ this.isGlyph = true;
148
+ this.$refs.glyphControls.setObject(object);
149
+ this.activeName = "gControls";
150
+ }
135
151
  }
136
152
  this.$refs.transformationControls.setObject(object);
137
153
  }
@@ -1288,21 +1288,47 @@ export default {
1288
1288
  * This is called by captueeScreenshot and after the last render
1289
1289
  * loop, it download a screenshot of the current scene with no UI.
1290
1290
  */
1291
- captureScreenshotCallback: function () {
1291
+ captureScreenshotCallback: function (filename, width, height) {
1292
+ return () => {
1292
1293
  //Remove the callback, only needs to happen once
1293
- this.$module.zincRenderer.removePostRenderCallbackFunction(
1294
- this.captureID
1295
- );
1296
- let screenshot = this.$module.zincRenderer
1297
- .getThreeJSRenderer()
1298
- .domElement.toDataURL("image/png");
1299
- let hrefElement = document.createElement("a");
1300
- document.body.append(hrefElement);
1301
- if (!this.captureFilename) hrefElement.download = `screenshot.png`;
1302
- else hrefElement.download = this.captureFilename;
1303
- hrefElement.href = screenshot;
1304
- hrefElement.click();
1305
- hrefElement.remove();
1294
+ this.$module.zincRenderer.removePostRenderCallbackFunction(
1295
+ this.captureID
1296
+ );
1297
+
1298
+ const renderer = this.$module.zincRenderer.getThreeJSRenderer();
1299
+ const camera = this.$module.scene.camera;
1300
+
1301
+ const originalWidth = renderer.domElement.width;
1302
+ const originalHeight = renderer.domElement.height;
1303
+ const originalAspect = camera.aspect;
1304
+ const originalPixelRatio = renderer.getPixelRatio();
1305
+
1306
+ renderer.setPixelRatio(1);
1307
+ renderer.setSize(width, height, false);
1308
+ camera.aspect = width / height;
1309
+ camera.updateProjectionMatrix();
1310
+ //this.$module.zincRenderer.onWindowResize();
1311
+ this.$module.zincRenderer.render();
1312
+ //renderer.render(this.$module.scene, camera);
1313
+
1314
+ let screenshot = renderer.domElement.toDataURL("image/png");
1315
+
1316
+ renderer.setPixelRatio(originalPixelRatio);
1317
+ renderer.setSize(originalWidth, originalHeight, false);
1318
+ camera.aspect = originalAspect;
1319
+ camera.updateProjectionMatrix();
1320
+ //this.$module.zincRenderer.onWindowResize();
1321
+ this.$module.zincRenderer.render();
1322
+ //renderer.render(this.$module.scene, camera);
1323
+
1324
+ let hrefElement = document.createElement("a");
1325
+ //document.body.append(hrefElement);
1326
+ if (!filename) hrefElement.download = `screenshot.png`;
1327
+ else hrefElement.download = filename;
1328
+ hrefElement.href = screenshot;
1329
+ hrefElement.click();
1330
+ hrefElement.remove();
1331
+ }
1306
1332
  },
1307
1333
  /**
1308
1334
  * @public
@@ -1310,10 +1336,9 @@ export default {
1310
1336
  *
1311
1337
  * @arg {String} "filename given to the screenshot."
1312
1338
  */
1313
- captureScreenshot: function (filename) {
1314
- this.captureFilename = filename;
1339
+ captureScreenshot: function (filename, width = 1920, height = 1080) {
1315
1340
  this.captureID = this.$module.zincRenderer.addPostRenderCallbackFunction(
1316
- this.captureScreenshotCallback
1341
+ this.captureScreenshotCallback(filename, width, height)
1317
1342
  );
1318
1343
  },
1319
1344
  /**
@@ -2851,10 +2876,10 @@ export default {
2851
2876
  this._slides = this.$module.scene.addSlicesPrimitive(
2852
2877
  "_helper", ["x-plane", "y-plane", "z-plane"], [0xFF5555, 0x55FF55, 0x5555FF],
2853
2878
  0.5);
2854
- this.calculateBoundingBox();
2855
2879
  //this.$module.scene.createAxisDisplay(false);
2856
2880
  //this.$module.scene.enableAxisDisplay(true, true);
2857
2881
  this.isReady = true;
2882
+ this.calculateBoundingBox();
2858
2883
  //console.log(`found ${foundNerves}`);
2859
2884
  this.$nextTick(() => {
2860
2885
  this.restoreSettings(options);
@@ -1,10 +1,14 @@
1
1
  /* eslint-disable */
2
- /* prettier-ignore */
3
2
  // @ts-nocheck
3
+ // biome-ignore lint: disable
4
+ // oxlint-disable
5
+ // ------
4
6
  // Generated by unplugin-vue-components
5
7
  // Read more: https://github.com/vuejs/core/pull/3399
8
+
6
9
  export {}
7
10
 
11
+ /* prettier-ignore */
8
12
  declare module 'vue' {
9
13
  export interface GlobalComponents {
10
14
  ElButton: typeof import('element-plus/es')['ElButton']
@@ -31,6 +35,7 @@ declare module 'vue' {
31
35
  ElSlider: typeof import('element-plus/es')['ElSlider']
32
36
  ElTabPane: typeof import('element-plus/es')['ElTabPane']
33
37
  ElTabs: typeof import('element-plus/es')['ElTabs']
38
+ GlyphsControls: typeof import('./components/GlyphsControls.vue')['default']
34
39
  LinesControls: typeof import('./components/LinesControls.vue')['default']
35
40
  OpacityControls: typeof import('./components/OpacityControls.vue')['default']
36
41
  PointsControls: typeof import('./components/PointsControls.vue')['default']
@@ -44,7 +49,7 @@ declare module 'vue' {
44
49
  TextureSlidesControls: typeof import('./components/TextureSlidesControls.vue')['default']
45
50
  TransformationControls: typeof import('./components/TransformationControls.vue')['default']
46
51
  }
47
- export interface ComponentCustomProperties {
52
+ export interface GlobalDirectives {
48
53
  vLoading: typeof import('element-plus/es')['ElLoadingDirective']
49
54
  }
50
55
  }
package/vite.config.js CHANGED
@@ -11,7 +11,8 @@ export default defineConfig(({ command, mode }) => {
11
11
  css: {
12
12
  preprocessorOptions: {
13
13
  scss: {
14
- additionalData: `@use './src/assets/styles' as *;`
14
+ api: 'modern-compiler',
15
+ additionalData: `@use '@/assets/styles' as *;`
15
16
  },
16
17
  },
17
18
  },
@@ -35,12 +36,12 @@ export default defineConfig(({ command, mode }) => {
35
36
  ],
36
37
  resolve: {
37
38
  alias: {
38
- '@': path.resolve(__dirname, './src'),
39
+ '@': path.resolve(import.meta.dirname, './src'),
39
40
  }
40
41
  },
41
42
  build: {
42
43
  lib: {
43
- entry: path.resolve(__dirname, "./src/components/index.js"),
44
+ entry: path.resolve(import.meta.dirname, "./src/components/index.js"),
44
45
  name: "ScaffoldVuer",
45
46
  fileName: 'scaffoldvuer',
46
47
  },
@@ -54,6 +55,11 @@ export default defineConfig(({ command, mode }) => {
54
55
  "@abi-software/map-utilities": "@abi-software/map-utilities",
55
56
  "pinia": "pinia"
56
57
  },
58
+ // keep css output name stable for the "./dist/style.css" export/import paths
59
+ assetFileNames: (assetInfo) =>
60
+ assetInfo.name?.endsWith(".css")
61
+ ? "style.css"
62
+ : "assets/[name][extname]",
57
63
  },
58
64
  },
59
65
  },
package/.eslintrc.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- env: {
3
- node: true,
4
- es2020: true,
5
- },
6
- parser: '@babel/eslint-parser', // Use the modern parser
7
- }
package/babel.config.js DELETED
File without changes