@3cr/viewer-browser 0.0.52 → 0.0.55
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 +108 -81
- package/__tests__/index.spec.ts +31 -0
- package/components.d.ts +2 -2
- package/coverage/3cr-viewer-browser/index.html +116 -0
- package/coverage/3cr-viewer-browser/index.ts.html +211 -0
- package/coverage/3cr-viewer-browser/src/App.vue.html +313 -0
- package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +442 -0
- package/coverage/3cr-viewer-browser/src/components/icons/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +148 -0
- package/coverage/3cr-viewer-browser/src/components/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +556 -0
- package/coverage/3cr-viewer-browser/src/components/loading/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +3931 -0
- package/coverage/3cr-viewer-browser/src/components/modal/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +331 -0
- package/coverage/3cr-viewer-browser/src/components/selectors/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +445 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +349 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/helpers/index.html +146 -0
- package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +406 -0
- package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +412 -0
- package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +133 -0
- package/coverage/3cr-viewer-browser/src/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/main.ts.html +124 -0
- package/coverage/3cr-viewer-browser/src/plugins/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +130 -0
- package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +220 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +251 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/dist/Viewer3CR.js +17 -11
- package/dist/Viewer3CR.mjs +5352 -5183
- package/dist/Viewer3CR.umd.js +17 -11
- package/index.html +4 -1
- package/index.ts +16 -12
- package/package.json +8 -3
- package/src/App.vue +1 -9
- package/src/__tests__/app.spec.ts +27 -0
- package/src/components/WebGL3DR.vue +49 -37
- package/src/components/__tests__/webgl3dr.spec.ts +56 -0
- package/src/components/icons/liver.vue +21 -0
- package/src/components/loading/__tests__/loading-spinner.spec.ts +11 -0
- package/src/components/modal/MftpWebGL3DRModal.vue +662 -394
- package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +690 -0
- package/src/components/selectors/__tests__/value-selector.spec.ts +35 -0
- package/src/components/sliders/DoubleSliderSelector.vue +30 -24
- package/src/components/sliders/VerticalSliderSelector.vue +25 -21
- package/src/components/sliders/__tests__/double-slider-selector.spec.ts +72 -0
- package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +61 -0
- package/src/helpers/__tests__/layout-overlay-style.spec.ts +288 -0
- package/src/helpers/__tests__/model-helper.spec.ts +118 -0
- package/src/helpers/__tests__/utils.spec.ts +70 -0
- package/src/helpers/layoutOverlayStyle.ts +50 -30
- package/src/plugins/__tests__/index.spec.ts +19 -0
- package/src/plugins/__tests__/vuetify.spec.ts +8 -0
- package/src/plugins/vuetify.ts +25 -8
- package/test/helper.ts +35 -0
- package/test/setup.ts +1 -0
- package/tsconfig.json +5 -2
- package/vite.config.mts +1 -0
- package/vitest.config.mts +44 -0
- package/README2.md +0 -201
- package/src/components/expansion-panels/ExpansionHeaderMiniMenu.vue +0 -19
- package/src/helpers/models.ts +0 -69
- /package/src/components/{sliders/SliderSelector.vue → selectors/ValueSelector.vue} +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { fn } from "@vitest/spy";
|
|
3
|
+
import { MockRunOnNewThread, registerEvents, toNumber } from "@/helpers/utils";
|
|
4
|
+
|
|
5
|
+
describe("MockRunOnNewThread", () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
vi.useFakeTimers();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
vi.useRealTimers();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should MockRunOnNewThread", () => {
|
|
15
|
+
const callback = fn();
|
|
16
|
+
|
|
17
|
+
MockRunOnNewThread(callback);
|
|
18
|
+
|
|
19
|
+
expect(callback).not.toHaveBeenCalledOnce();
|
|
20
|
+
|
|
21
|
+
vi.advanceTimersByTime(1);
|
|
22
|
+
expect(callback).toHaveBeenCalledOnce();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("toNumber", () => {
|
|
27
|
+
it("should '1'", () => {
|
|
28
|
+
expect(toNumber("1")).toBe(1);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should '100'", () => {
|
|
32
|
+
expect(toNumber("100")).toBe(100);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should 1 ", () => {
|
|
36
|
+
expect(toNumber(1)).toBe(1);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should undefined ", () => {
|
|
40
|
+
expect(toNumber(undefined)).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should test ", () => {
|
|
44
|
+
expect(toNumber("test")).toBe(NaN);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("registerEvents", () => {
|
|
49
|
+
it("should registerEvents", () => {
|
|
50
|
+
const fakeEvents = ["drag", "drop"];
|
|
51
|
+
const fakeListener = () => {};
|
|
52
|
+
const fakeElement = {
|
|
53
|
+
addEventListener: fn(),
|
|
54
|
+
} as unknown as HTMLElement;
|
|
55
|
+
|
|
56
|
+
registerEvents(fakeElement, fakeEvents, fakeListener);
|
|
57
|
+
|
|
58
|
+
expect(fakeElement.addEventListener).toHaveBeenCalledTimes(2);
|
|
59
|
+
expect(fakeElement.addEventListener).toHaveBeenNthCalledWith(
|
|
60
|
+
1,
|
|
61
|
+
fakeEvents[0],
|
|
62
|
+
fakeListener
|
|
63
|
+
);
|
|
64
|
+
expect(fakeElement.addEventListener).toHaveBeenNthCalledWith(
|
|
65
|
+
2,
|
|
66
|
+
fakeEvents[1],
|
|
67
|
+
fakeListener
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { AnchorPoint, PositionData } from
|
|
1
|
+
import { AnchorPoint, PositionData } from "@3cr/types-ts";
|
|
2
2
|
|
|
3
|
-
import { toNumber } from
|
|
3
|
+
import { toNumber } from "@/helpers/utils";
|
|
4
4
|
|
|
5
5
|
export function generateDivStyleForLayout(layout: PositionData) {
|
|
6
|
-
const padding =
|
|
7
|
-
const canvas = document.getElementById(
|
|
6
|
+
const padding = "0px";
|
|
7
|
+
const canvas = document.getElementById("unity-canvas");
|
|
8
8
|
|
|
9
9
|
const props = {} as any;
|
|
10
10
|
|
|
11
11
|
if (layout.Anchor === AnchorPoint.TOP) {
|
|
12
|
-
props[
|
|
13
|
-
props[
|
|
12
|
+
props["left"] = "50%";
|
|
13
|
+
props["transform"] = "translateX(-50%)";
|
|
14
14
|
}
|
|
15
15
|
if (layout.Anchor === AnchorPoint.BOTTOM) {
|
|
16
|
-
props[
|
|
17
|
-
props[
|
|
16
|
+
props["left"] = "50%";
|
|
17
|
+
props["transform"] = "translateX(-50%)";
|
|
18
18
|
}
|
|
19
19
|
if (layout.Anchor === AnchorPoint.LEFT) {
|
|
20
|
-
props[
|
|
21
|
-
props[
|
|
20
|
+
props["top"] = "50%";
|
|
21
|
+
props["transform"] = "translateY(-50%)";
|
|
22
22
|
}
|
|
23
23
|
if (layout.Anchor === AnchorPoint.RIGHT) {
|
|
24
|
-
props[
|
|
25
|
-
props[
|
|
24
|
+
props["top"] = "50%";
|
|
25
|
+
props["transform"] = "translateY(-50%)";
|
|
26
26
|
}
|
|
27
27
|
if (
|
|
28
28
|
layout.Anchor === AnchorPoint.TOP_LEFT ||
|
|
@@ -30,7 +30,7 @@ export function generateDivStyleForLayout(layout: PositionData) {
|
|
|
30
30
|
layout.Anchor === AnchorPoint.TOP_RIGHT ||
|
|
31
31
|
layout.Anchor === AnchorPoint.CENTER
|
|
32
32
|
) {
|
|
33
|
-
props[
|
|
33
|
+
props["top"] = padding;
|
|
34
34
|
}
|
|
35
35
|
if (
|
|
36
36
|
layout.Anchor === AnchorPoint.LEFT ||
|
|
@@ -38,48 +38,68 @@ export function generateDivStyleForLayout(layout: PositionData) {
|
|
|
38
38
|
layout.Anchor === AnchorPoint.TOP_LEFT ||
|
|
39
39
|
layout.Anchor === AnchorPoint.CENTER
|
|
40
40
|
) {
|
|
41
|
-
props[
|
|
41
|
+
props["left"] = padding;
|
|
42
42
|
}
|
|
43
43
|
if (
|
|
44
44
|
layout.Anchor === AnchorPoint.RIGHT ||
|
|
45
45
|
layout.Anchor === AnchorPoint.TOP_RIGHT ||
|
|
46
46
|
layout.Anchor === AnchorPoint.BOTTOM_RIGHT
|
|
47
47
|
) {
|
|
48
|
-
props[
|
|
48
|
+
props["right"] = padding;
|
|
49
49
|
}
|
|
50
50
|
if (
|
|
51
51
|
layout.Anchor === AnchorPoint.BOTTOM ||
|
|
52
52
|
layout.Anchor === AnchorPoint.BOTTOM_LEFT ||
|
|
53
53
|
layout.Anchor === AnchorPoint.BOTTOM_RIGHT
|
|
54
54
|
) {
|
|
55
|
-
props[
|
|
55
|
+
props["bottom"] = "4px";
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
58
|
-
|
|
57
|
+
if (
|
|
58
|
+
layout.Anchor === AnchorPoint.TOP_LEFT ||
|
|
59
|
+
layout.Anchor === AnchorPoint.CENTER
|
|
60
|
+
) {
|
|
61
|
+
props["border-top-left-radius"] = padding;
|
|
59
62
|
}
|
|
60
|
-
if (
|
|
61
|
-
|
|
63
|
+
if (
|
|
64
|
+
layout.Anchor === AnchorPoint.TOP_RIGHT ||
|
|
65
|
+
layout.Anchor === AnchorPoint.CENTER
|
|
66
|
+
) {
|
|
67
|
+
props["border-top-right-radius"] = padding;
|
|
62
68
|
}
|
|
63
|
-
if (
|
|
64
|
-
|
|
69
|
+
if (
|
|
70
|
+
layout.Anchor === AnchorPoint.BOTTOM_LEFT ||
|
|
71
|
+
layout.Anchor === AnchorPoint.CENTER
|
|
72
|
+
) {
|
|
73
|
+
props["border-bottom-left-radius"] = padding;
|
|
65
74
|
}
|
|
66
|
-
if (
|
|
67
|
-
|
|
75
|
+
if (
|
|
76
|
+
layout.Anchor === AnchorPoint.BOTTOM_RIGHT ||
|
|
77
|
+
layout.Anchor === AnchorPoint.CENTER
|
|
78
|
+
) {
|
|
79
|
+
props["border-bottom-right-radius"] = padding;
|
|
68
80
|
}
|
|
69
81
|
|
|
70
|
-
props[
|
|
71
|
-
props[
|
|
82
|
+
props["width"] = `calc(${layout.MaxSize.X * 100}% - ${padding})`;
|
|
83
|
+
props["height"] = `calc(${layout.MaxSize.Y * 100}% - ${"2px"})`;
|
|
72
84
|
if (layout.Anchor === AnchorPoint.CENTER) {
|
|
73
|
-
props[
|
|
74
|
-
|
|
85
|
+
props["width"] = `calc(${
|
|
86
|
+
layout.MaxSize.X * 100
|
|
87
|
+
}% - ${padding} - ${padding})`;
|
|
88
|
+
props["height"] = `calc(${
|
|
89
|
+
layout.MaxSize.Y * 100
|
|
90
|
+
}% - ${"2px"} - ${"2px"})`;
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
if (layout.AspectRatio === 1) {
|
|
78
94
|
if (layout.MaxSize.X === 1) {
|
|
79
|
-
props[
|
|
95
|
+
props["width"] = `calc(${
|
|
96
|
+
layout.MaxSize.Y * toNumber(canvas?.offsetHeight)
|
|
97
|
+
}px)`;
|
|
80
98
|
}
|
|
81
99
|
if (layout.MaxSize.Y === 1) {
|
|
82
|
-
props[
|
|
100
|
+
props["height"] = `calc(${
|
|
101
|
+
layout.MaxSize.X * toNumber(canvas?.offsetWidth)
|
|
102
|
+
}px)`;
|
|
83
103
|
}
|
|
84
104
|
}
|
|
85
105
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import vuetify from "@/plugins/vuetify";
|
|
3
|
+
import { fn } from "@vitest/spy";
|
|
4
|
+
import { registerPlugins } from "@/plugins";
|
|
5
|
+
import { App } from "vue";
|
|
6
|
+
|
|
7
|
+
describe("index.ts", () => {
|
|
8
|
+
it("should registerPlugins", () => {
|
|
9
|
+
const app = {
|
|
10
|
+
use: fn(),
|
|
11
|
+
} as unknown as App;
|
|
12
|
+
|
|
13
|
+
expect(app.use).not.toHaveBeenCalledWith(vuetify);
|
|
14
|
+
|
|
15
|
+
registerPlugins(app);
|
|
16
|
+
|
|
17
|
+
expect(app.use).toHaveBeenCalledWith(vuetify);
|
|
18
|
+
});
|
|
19
|
+
});
|
package/src/plugins/vuetify.ts
CHANGED
|
@@ -5,24 +5,41 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Styles
|
|
8
|
-
import
|
|
8
|
+
import "vuetify/styles";
|
|
9
9
|
|
|
10
10
|
// Composables
|
|
11
|
-
import { createVuetify } from
|
|
12
|
-
import { aliases, md
|
|
13
|
-
import { mdi
|
|
11
|
+
import { createVuetify, IconProps } from "vuetify";
|
|
12
|
+
import { aliases, md } from "vuetify/iconsets/md";
|
|
13
|
+
import { mdi } from "vuetify/iconsets/mdi";
|
|
14
|
+
import { fa } from "vuetify/iconsets/fa";
|
|
15
|
+
import { h } from "vue";
|
|
16
|
+
import liver from "@/components/icons/liver.vue";
|
|
17
|
+
|
|
18
|
+
const customComponents: any = {
|
|
19
|
+
liver,
|
|
20
|
+
};
|
|
14
21
|
|
|
15
22
|
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
|
|
23
|
+
/* istanbul ignore next -- @preserve */
|
|
16
24
|
export default createVuetify({
|
|
17
25
|
theme: {
|
|
18
|
-
defaultTheme:
|
|
26
|
+
defaultTheme: "light",
|
|
19
27
|
},
|
|
20
28
|
icons: {
|
|
21
|
-
defaultSet:
|
|
29
|
+
defaultSet: "md",
|
|
22
30
|
aliases,
|
|
23
31
|
sets: {
|
|
24
32
|
md,
|
|
25
|
-
mdi
|
|
33
|
+
mdi,
|
|
34
|
+
fa,
|
|
35
|
+
custom: {
|
|
36
|
+
/* c8 ignore start */
|
|
37
|
+
component: (props: IconProps) =>
|
|
38
|
+
h(props.tag, [
|
|
39
|
+
h(customComponents[props.icon as string], { class: "v-icon__svg" }),
|
|
40
|
+
]),
|
|
41
|
+
/* c8 ignore stop */
|
|
42
|
+
},
|
|
26
43
|
},
|
|
27
44
|
},
|
|
28
|
-
})
|
|
45
|
+
});
|
package/test/helper.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { mount, shallowMount } from "@vue/test-utils";
|
|
2
|
+
import { createVuetify } from "vuetify";
|
|
3
|
+
import { expect } from "vitest";
|
|
4
|
+
|
|
5
|
+
export function mountVuetify<T>(
|
|
6
|
+
component: T,
|
|
7
|
+
props: any = {},
|
|
8
|
+
stubs: any = {}
|
|
9
|
+
) {
|
|
10
|
+
const vuetify = createVuetify({});
|
|
11
|
+
return mount(component, {
|
|
12
|
+
props,
|
|
13
|
+
global: {
|
|
14
|
+
plugins: [vuetify],
|
|
15
|
+
stubs,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function shallowMountVuetify<T>(component: T, props: any = {}) {
|
|
20
|
+
const vuetify = createVuetify({});
|
|
21
|
+
return shallowMount(component, {
|
|
22
|
+
props,
|
|
23
|
+
global: {
|
|
24
|
+
plugins: [vuetify],
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function checkComponentProps(
|
|
30
|
+
component: any,
|
|
31
|
+
propKey: string,
|
|
32
|
+
equal: any
|
|
33
|
+
) {
|
|
34
|
+
expect(component.props()[propKey] as any).toBe(equal);
|
|
35
|
+
}
|
package/test/setup.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
global.ResizeObserver = require("resize-observer-polyfill");
|
package/tsconfig.json
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"module": "ESNext",
|
|
13
13
|
"moduleResolution": "node",
|
|
14
14
|
"paths": {
|
|
15
|
-
"@/*": ["src/*"]
|
|
15
|
+
"@/*": ["src/*"],
|
|
16
|
+
"~/*": ["test/*"]
|
|
16
17
|
},
|
|
17
18
|
"resolveJsonModule": true,
|
|
18
19
|
|
|
@@ -27,7 +28,9 @@
|
|
|
27
28
|
},
|
|
28
29
|
"include": [
|
|
29
30
|
"./src/typed-router.d.ts",
|
|
30
|
-
"**/*.
|
|
31
|
+
"**/*.ts",
|
|
32
|
+
"**/*.spec.ts",
|
|
33
|
+
"**/*.vue",
|
|
31
34
|
],
|
|
32
35
|
"exclude": ["dist", "node_modules", "cypress"],
|
|
33
36
|
"references": [{ "path": "./tsconfig.node.json" }]
|
package/vite.config.mts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
// vitest.config.ts
|
|
3
|
+
import {defineConfig, mergeConfig} from 'vite'
|
|
4
|
+
import viteConfig from "./vite.config.mjs";
|
|
5
|
+
|
|
6
|
+
export default mergeConfig(viteConfig, defineConfig({
|
|
7
|
+
test: {
|
|
8
|
+
globals: true,
|
|
9
|
+
environment: 'jsdom',
|
|
10
|
+
server: {
|
|
11
|
+
deps: {
|
|
12
|
+
inline: ['vuetify'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
exclude: ['node_modules/**'],
|
|
16
|
+
include: ['**/*.spec.ts'],
|
|
17
|
+
setupFiles: ['/test/setup.ts'],
|
|
18
|
+
coverage: {
|
|
19
|
+
provider: 'v8', // or 'v8',
|
|
20
|
+
enabled: true,
|
|
21
|
+
reporter: ['html'],
|
|
22
|
+
include: ['src/**/*', 'index.ts'],
|
|
23
|
+
exclude: [
|
|
24
|
+
'coverage/**',
|
|
25
|
+
'dist/**',
|
|
26
|
+
'scripts/**',
|
|
27
|
+
'**/[.]**',
|
|
28
|
+
'packages/*/test?(s)/**',
|
|
29
|
+
'**/*.d.ts',
|
|
30
|
+
'**/virtual:*',
|
|
31
|
+
'**/__x00__*',
|
|
32
|
+
'**/\x00*',
|
|
33
|
+
'cypress/**',
|
|
34
|
+
'test?(s)/**',
|
|
35
|
+
'test?(-*).?(c|m)[jt]s?(x)',
|
|
36
|
+
'**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
|
|
37
|
+
'**/__tests__/**',
|
|
38
|
+
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
|
|
39
|
+
'**/vitest.{workspace,projects}.[jt]s?(on)',
|
|
40
|
+
'**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}))
|
package/README2.md
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
# @3cr/sdk-browser
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-

|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Ecosystem integration for installing and running [3DICOM Online Viewer (3CR-OV)](https://docs.3cr.singular.health/) within the Browser (client-side)
|
|
8
|
-
|
|
9
|
-
## Include `@3cr/viewer-browser` script
|
|
10
|
-
|
|
11
|
-
Choose one of the following ways
|
|
12
|
-
- ### HTML Script Tag
|
|
13
|
-
|
|
14
|
-
Insert this line into your `index.html`
|
|
15
|
-
|
|
16
|
-
```html
|
|
17
|
-
<script src="https://cdn.jsdelivr.net/npm/@3cr/viewer-browser@{{version}}/dist/Viewer3CR.umd.js"> </script>
|
|
18
|
-
```
|
|
19
|
-
Note: Please ensure you replace the `{{version}}` with the version of the viewer you want.
|
|
20
|
-
|
|
21
|
-
- ### JS/TS way
|
|
22
|
-
|
|
23
|
-
You can also include it dynamically within your code.
|
|
24
|
-
|
|
25
|
-
`Typescript (.ts)`
|
|
26
|
-
```ts
|
|
27
|
-
export async function loadViewerScript(version: string): Promise<void> {
|
|
28
|
-
return new Promise<void>((resolve) => {
|
|
29
|
-
const s = document.createElement('script');
|
|
30
|
-
s.onload = () => {
|
|
31
|
-
resolve()
|
|
32
|
-
}
|
|
33
|
-
s.src = `https://cdn.jsdelivr.net/npm/@3cr/viewer-browser@${version}/dist/Viewer3CR.umd.js`;
|
|
34
|
-
document.head.appendChild(s);
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// ...
|
|
39
|
-
|
|
40
|
-
await loadViewerScript("1.0.0");
|
|
41
|
-
```
|
|
42
|
-
`Javascript (.js)`
|
|
43
|
-
```js
|
|
44
|
-
export async function loadViewerScript(version) {
|
|
45
|
-
return new Promise((resolve) => {
|
|
46
|
-
const s = document.createElement('script');
|
|
47
|
-
s.onload = () => {
|
|
48
|
-
resolve()
|
|
49
|
-
}
|
|
50
|
-
s.src = `https://cdn.jsdelivr.net/npm/@3cr/viewer-browser@${version}/dist/Viewer3CR.umd.js`;
|
|
51
|
-
document.head.appendChild(s);
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// ...
|
|
56
|
-
|
|
57
|
-
await loadViewerScript("1.0.0");
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
## Using the Package
|
|
62
|
-
|
|
63
|
-
1. #### Register 3DICOM Online Viewer version
|
|
64
|
-
|
|
65
|
-
Call the `registerViewer` function with the version of 3CR you would like to view. You also need to supply a
|
|
66
|
-
|
|
67
|
-
`Typescript (.ts)`
|
|
68
|
-
```ts
|
|
69
|
-
import { registerVersion } from '@3cr/sdk-browser';
|
|
70
|
-
|
|
71
|
-
const VERSION_3CR: string = '1.0.0';
|
|
72
|
-
|
|
73
|
-
await registerVersion(VERSION_3CR);
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
`Javascript (.js)`
|
|
77
|
-
```js
|
|
78
|
-
import { registerVersion } from '@3cr/sdk-browser';
|
|
79
|
-
|
|
80
|
-
const VERSION_3CR = '1.0.0';
|
|
81
|
-
|
|
82
|
-
await registerVersion(VERSION_3CR);
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
2. #### Create HTML Canvas
|
|
86
|
-
|
|
87
|
-
Create a canvas element within your HTML Markup and assign it an `id`.
|
|
88
|
-
|
|
89
|
-
You will have to ensure that the size (width & height) both match the inline css styling and the canvas styling
|
|
90
|
-
|
|
91
|
-
`html`
|
|
92
|
-
```html
|
|
93
|
-
<canvas
|
|
94
|
-
id="renderer-canvas"
|
|
95
|
-
width="1080"
|
|
96
|
-
height="1920"
|
|
97
|
-
tabindex="-1"
|
|
98
|
-
style=" width: 1920px; height: 1080px; "
|
|
99
|
-
>
|
|
100
|
-
</canvas>
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
3. #### Register response handler for 3DICOM Core Renderer Instance
|
|
104
|
-
|
|
105
|
-
You will need to register a function that can accept the responses from the 3CR instance.
|
|
106
|
-
|
|
107
|
-
`Typescript (.ts)`
|
|
108
|
-
```ts
|
|
109
|
-
import { registerOnPayloadHandler } from '@3cr/sdk-browser';
|
|
110
|
-
import { FrontEndPayload } from '@3cr/sdk-browser/types/payload';
|
|
111
|
-
|
|
112
|
-
function onPayload(json: FrontEndPayload) {
|
|
113
|
-
console.log("Payload recieved from 3CR!", json)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
await registerOnPayloadHandler(onPayload);
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
`Javascript (.js)`
|
|
120
|
-
```js
|
|
121
|
-
import { registerOnPayloadHandler } from '@3cr/sdk-browser';
|
|
122
|
-
|
|
123
|
-
function onPayload(json) {
|
|
124
|
-
console.log("Payload recieved from 3CR!", json)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
await registerOnPayloadHandler(onPayload);
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
4. #### Attach the 3CR Instance to the HTML Canvas
|
|
131
|
-
Get the HTML Element from the DOM Object and inject it into the instance.
|
|
132
|
-
|
|
133
|
-
`Typescript (.ts)`
|
|
134
|
-
```ts
|
|
135
|
-
import { createInstance } from '@3cr/sdk-browser';
|
|
136
|
-
const canvas: HTMLCanvasElement = document.querySelector('#renderer-canvas') as HTMLCanvasElement;
|
|
137
|
-
|
|
138
|
-
await createInstance(canvas);
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
`Javascript (.js)`
|
|
142
|
-
```js
|
|
143
|
-
import { createInstance } from '@3cr/sdk-browser';
|
|
144
|
-
const canvas = document.querySelector('#renderer-canvas');
|
|
145
|
-
|
|
146
|
-
await createInstance(canvas);
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
5. #### Execute payload on Instance
|
|
151
|
-
Get the HTML Element from the DOM Object and inject it into the instance.
|
|
152
|
-
|
|
153
|
-
`Typescript (.ts)`
|
|
154
|
-
```ts
|
|
155
|
-
import { executePayload } from '@3cr/sdk-browser';
|
|
156
|
-
import { FrontEndInterfaces, FileManagementActions } from '@3cr/sdk-browser/types/payload';
|
|
157
|
-
|
|
158
|
-
await executePayload({
|
|
159
|
-
Version: '1.0.0',
|
|
160
|
-
Interface: FrontEndInterfaces.file_management,
|
|
161
|
-
Action: FileManagementActions.fm_01,
|
|
162
|
-
Message: JSON.stringify({
|
|
163
|
-
Url: 'https://somethingtodownload.com/some.3vxl.compressed.encrypted',
|
|
164
|
-
DecryptionKey: {
|
|
165
|
-
Key: '<Encryption Key>',
|
|
166
|
-
Iv: '<Encryption IV>'
|
|
167
|
-
}
|
|
168
|
-
}),
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
`Javascript (.js)`
|
|
173
|
-
```js
|
|
174
|
-
import { executePayload } from '@3cr/sdk-browser';
|
|
175
|
-
|
|
176
|
-
await executePayload({
|
|
177
|
-
Version: '1.0.0',
|
|
178
|
-
Interface: 'file_management',
|
|
179
|
-
Action: 'fm_01',
|
|
180
|
-
Message: JSON.stringify({
|
|
181
|
-
Url: 'https://somethingtodownload.com/some.3vxl.compressed.encrypted',
|
|
182
|
-
DecryptionKey: {
|
|
183
|
-
Key: '<Encryption Key>',
|
|
184
|
-
Iv: '<Encryption IV>'
|
|
185
|
-
}
|
|
186
|
-
}),
|
|
187
|
-
});
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
## Contributing
|
|
193
|
-
|
|
194
|
-
Pull requests are welcome. For changes, please open an issue first
|
|
195
|
-
to discuss what you would like to change.
|
|
196
|
-
|
|
197
|
-
Please make sure to update tests as appropriate.
|
|
198
|
-
|
|
199
|
-
## License
|
|
200
|
-
|
|
201
|
-
[MIT](https://choosealicense.com/licenses/mit/)
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-expansion-panel-title class="font-weight-bold transparent">
|
|
3
|
-
<span
|
|
4
|
-
><v-icon small>{{ props.miniMenu.icon }}</v-icon
|
|
5
|
-
> {{ props.miniMenu.text }}</span
|
|
6
|
-
>
|
|
7
|
-
<v-spacer />
|
|
8
|
-
</v-expansion-panel-title>
|
|
9
|
-
</template>
|
|
10
|
-
<script setup lang="ts">
|
|
11
|
-
|
|
12
|
-
export interface Props {
|
|
13
|
-
miniMenu: { icon: string; text: string };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
17
|
-
miniMenu: () => ({ icon: '', text: '' }),
|
|
18
|
-
});
|
|
19
|
-
</script>
|
package/src/helpers/models.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
export interface FrontEndPayload {
|
|
2
|
-
Interface: FrontEndInterfaces;
|
|
3
|
-
Action: FrontEndInterfaces;
|
|
4
|
-
Message: string;
|
|
5
|
-
}
|
|
6
|
-
export enum FrontEndInterfaces {
|
|
7
|
-
scan_loading = 'scan_loading',
|
|
8
|
-
file_management = 'file_management',
|
|
9
|
-
view_selection = 'view_selection',
|
|
10
|
-
layout = 'layout',
|
|
11
|
-
presets = 'presets',
|
|
12
|
-
sliders = 'sliders',
|
|
13
|
-
scan_orientation = 'scan_orientation',
|
|
14
|
-
scan_movement = 'scan_movement',
|
|
15
|
-
interactivity = 'interactivity',
|
|
16
|
-
}
|
|
17
|
-
export enum FrontEndActions {
|
|
18
|
-
pong = 'pong',
|
|
19
|
-
announcement = 'announcement',
|
|
20
|
-
fm02 = 'fm_02',
|
|
21
|
-
}
|
|
22
|
-
export enum FileManagementActions {
|
|
23
|
-
fm01 = 'fm_01',
|
|
24
|
-
fm02 = 'fm_02',
|
|
25
|
-
}
|
|
26
|
-
export enum NotificationActions {
|
|
27
|
-
no01 = 'no_01',
|
|
28
|
-
no02 = 'no_02',
|
|
29
|
-
no03 = 'no_03',
|
|
30
|
-
}
|
|
31
|
-
export enum ScanOrientationActions {
|
|
32
|
-
so01 = 'so_01',
|
|
33
|
-
}
|
|
34
|
-
export enum PresetActions {
|
|
35
|
-
pr01 = 'pr_01',
|
|
36
|
-
pr02 = 'pr_02',
|
|
37
|
-
}
|
|
38
|
-
export enum ScanMovementActions {
|
|
39
|
-
sm01 = 'sm_01',
|
|
40
|
-
sm02 = 'sm_02',
|
|
41
|
-
sm03 = 'sm_03',
|
|
42
|
-
sm04 = 'sm_04',
|
|
43
|
-
sm05 = 'sm_05',
|
|
44
|
-
sm06 = 'sm_06',
|
|
45
|
-
sm07 = 'sm_07',
|
|
46
|
-
sm08 = 'sm_08',
|
|
47
|
-
sm09 = 'sm_09',
|
|
48
|
-
sm10 = 'sm_10',
|
|
49
|
-
sm11 = 'sm_11',
|
|
50
|
-
sm12 = 'sm_12',
|
|
51
|
-
}
|
|
52
|
-
export enum SliderActions {
|
|
53
|
-
sl01 = 'sl_01',
|
|
54
|
-
sl02 = 'sl_02',
|
|
55
|
-
sl03 = 'sl_03',
|
|
56
|
-
sl04 = 'sl_04',
|
|
57
|
-
sl05 = 'sl_05',
|
|
58
|
-
sl06 = 'sl_06',
|
|
59
|
-
sl07 = 'sl_07',
|
|
60
|
-
sl08 = 'sl_08',
|
|
61
|
-
sl09 = 'sl_09',
|
|
62
|
-
sl10 = 'sl_10',
|
|
63
|
-
sl11 = 'sl_11',
|
|
64
|
-
sl12 = 'sl_12',
|
|
65
|
-
sl13 = 'sl_13',
|
|
66
|
-
sl14 = 'sl_14',
|
|
67
|
-
sl15 = 'sl_15',
|
|
68
|
-
sl16 = 'sl_16',
|
|
69
|
-
}
|