|
@@ -1,7 +1,7 @@
|
|
|
export default {
|
|
|
template: `
|
|
|
<div style="position:relative">
|
|
|
- <img :src="computed_src" style="width:100%; height:100%;" v-on="onEvents" draggable="false" />
|
|
|
+ <img ref="img" :src="computed_src" style="width:100%; height:100%;" v-on="onEvents" draggable="false" />
|
|
|
<svg style="position:absolute;top:0;left:0;pointer-events:none" :viewBox="viewBox">
|
|
|
<g v-if="cross" :style="{ display: cssDisplay }">
|
|
|
<line :x1="x" y1="0" :x2="x" y2="100%" stroke="black" />
|
|
@@ -19,17 +19,38 @@ export default {
|
|
|
y: 100,
|
|
|
cssDisplay: "none",
|
|
|
computed_src: undefined,
|
|
|
+ waiting_source: undefined,
|
|
|
+ loading: false,
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
setTimeout(() => this.compute_src(), 0); // NOTE: wait for window.path_prefix to be set in app.mounted()
|
|
|
+ const handle_completion = () => {
|
|
|
+ if (this.waiting_source) {
|
|
|
+ this.computed_src = this.waiting_source;
|
|
|
+ this.waiting_source = undefined;
|
|
|
+ } else {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.$refs.img.addEventListener("load", handle_completion);
|
|
|
+ this.$refs.img.addEventListener("error", handle_completion);
|
|
|
},
|
|
|
updated() {
|
|
|
this.compute_src();
|
|
|
},
|
|
|
methods: {
|
|
|
compute_src() {
|
|
|
- this.computed_src = (this.src.startsWith("/") ? window.path_prefix : "") + this.src;
|
|
|
+ const new_src = (this.src.startsWith("/") ? window.path_prefix : "") + this.src;
|
|
|
+ if (new_src == this.computed_src) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.loading) {
|
|
|
+ this.waiting_source = new_src;
|
|
|
+ } else {
|
|
|
+ this.computed_src = new_src;
|
|
|
+ this.loading = true;
|
|
|
+ }
|
|
|
},
|
|
|
updateCrossHair(e) {
|
|
|
this.x = (e.offsetX * e.target.naturalWidth) / e.target.clientWidth;
|