|
@@ -1,19 +1,23 @@
|
|
|
-Vue.component("interactive_image", {
|
|
|
+export default {
|
|
|
template: `
|
|
|
- <div :id="jp_props.id" style="position:relative" :style="jp_props.style" :class="jp_props.classes">
|
|
|
- <img style="width:100%; height:100%">
|
|
|
+ <div style="position:relative">
|
|
|
+ <img style="width:100%; height:100%" />
|
|
|
<svg style="position:absolute;top:0;left:0;pointer-events:none">
|
|
|
<g style="display:none">
|
|
|
<line x1="100" y1="0" x2="100" y2="100%" stroke="black" />
|
|
|
<line x1="0" y1="100" x2="100%" y2="100" stroke="black" />
|
|
|
</g>
|
|
|
- <g v-html="jp_props.options.svg_content"></g>
|
|
|
+ <g v-html="content"></g>
|
|
|
</svg>
|
|
|
</div>
|
|
|
`,
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ content: "",
|
|
|
+ };
|
|
|
+ },
|
|
|
mounted() {
|
|
|
- comp_dict[this.$props.jp_props.id] = this;
|
|
|
- this.image = document.getElementById(this.$props.jp_props.id).firstChild;
|
|
|
+ this.image = this.$el.firstChild;
|
|
|
const handle_completion = () => {
|
|
|
if (this.waiting_source) {
|
|
|
this.image.src = this.waiting_source;
|
|
@@ -24,10 +28,10 @@ Vue.component("interactive_image", {
|
|
|
};
|
|
|
this.image.addEventListener("load", handle_completion);
|
|
|
this.image.addEventListener("error", handle_completion);
|
|
|
- const svg = document.getElementById(this.$props.jp_props.id).lastChild;
|
|
|
- const cross = svg.firstChild;
|
|
|
+ this.svg = this.$el.lastChild;
|
|
|
+ const cross = this.svg.firstChild;
|
|
|
this.image.ondragstart = () => false;
|
|
|
- if (this.$props.jp_props.options.cross) {
|
|
|
+ if (this.cross) {
|
|
|
this.image.style.cursor = "none";
|
|
|
this.image.addEventListener("mouseenter", (e) => {
|
|
|
cross.style.display = "block";
|
|
@@ -46,46 +50,29 @@ Vue.component("interactive_image", {
|
|
|
}
|
|
|
this.image.onload = (e) => {
|
|
|
const viewBox = `0 0 ${this.image.naturalWidth} ${this.image.naturalHeight}`;
|
|
|
- svg.setAttribute("viewBox", viewBox);
|
|
|
+ this.svg.setAttribute("viewBox", viewBox);
|
|
|
};
|
|
|
- this.image.src = this.$props.jp_props.options.source;
|
|
|
- for (const type of this.$props.jp_props.options.events) {
|
|
|
+ this.image.src = this.src;
|
|
|
+ for (const type of this.events) {
|
|
|
this.image.addEventListener(type, (e) => {
|
|
|
- const event = {
|
|
|
- event_type: "onMouse",
|
|
|
+ this.$emit("mouse", {
|
|
|
mouse_event_type: type,
|
|
|
- vue_type: this.$props.jp_props.vue_type,
|
|
|
- id: this.$props.jp_props.id,
|
|
|
- page_id: page_id,
|
|
|
- websocket_id: websocket_id,
|
|
|
image_x: (e.offsetX * e.target.naturalWidth) / e.target.clientWidth,
|
|
|
image_y: (e.offsetY * e.target.naturalHeight) / e.target.clientHeight,
|
|
|
- };
|
|
|
- send_to_server(event, "event");
|
|
|
+ });
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ this.is_initialized = false;
|
|
|
const sendConnectEvent = () => {
|
|
|
- if (websocket_id === "") return;
|
|
|
- const event = {
|
|
|
- event_type: "onConnect",
|
|
|
- vue_type: this.$props.jp_props.vue_type,
|
|
|
- id: this.$props.jp_props.id,
|
|
|
- page_id: page_id,
|
|
|
- websocket_id: websocket_id,
|
|
|
- };
|
|
|
- send_to_server(event, "event");
|
|
|
- clearInterval(connectInterval);
|
|
|
+ if (!this.is_initialized) this.$emit("connect");
|
|
|
+ else clearInterval(connectInterval);
|
|
|
};
|
|
|
const connectInterval = setInterval(sendConnectEvent, 100);
|
|
|
},
|
|
|
- updated() {
|
|
|
- if (this.image.src != this.$props.jp_props.options.source) {
|
|
|
- this.image.src = this.$props.jp_props.options.source;
|
|
|
- }
|
|
|
- },
|
|
|
methods: {
|
|
|
set_source(source) {
|
|
|
+ this.is_initialized = true;
|
|
|
if (this.loading) {
|
|
|
this.waiting_source = source;
|
|
|
return;
|
|
@@ -93,8 +80,13 @@ Vue.component("interactive_image", {
|
|
|
this.loading = true;
|
|
|
this.image.src = source;
|
|
|
},
|
|
|
+ set_content(content) {
|
|
|
+ this.content = content;
|
|
|
+ },
|
|
|
},
|
|
|
props: {
|
|
|
- jp_props: Object,
|
|
|
+ src: String,
|
|
|
+ events: Array,
|
|
|
+ cross: Boolean,
|
|
|
},
|
|
|
-});
|
|
|
+};
|