export default { template: `
`, data() { return { viewBox: "0 0 0 0", loaded_image_width: 0, loaded_image_height: 0, x: 100, y: 100, showCross: false, 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); for (const event of [ "pointermove", "pointerdown", "pointerup", "pointerover", "pointerout", "pointerenter", "pointerleave", "pointercancel", ]) { this.$refs.svg.addEventListener(event, (e) => this.onPointerEvent(event, e)); } }, updated() { this.compute_src(); }, methods: { compute_src() { const suffix = this.t ? (this.src.includes("?") ? "&" : "?") + "_nicegui_t=" + this.t : ""; const new_src = (this.src.startsWith("/") ? window.path_prefix : "") + this.src + suffix; if (new_src == this.computed_src) { return; } if (this.loading) { this.waiting_source = new_src; } else { this.computed_src = new_src; this.loading = true; } if (!this.src && this.size) { this.updateViewbox(this.size[0], this.size[1]); } }, updateCrossHair(e) { const width = this.src ? this.loaded_image_width : this.size ? this.size[0] : 1; const height = this.src ? this.loaded_image_height : this.size ? this.size[1] : 1; this.x = (e.offsetX * width) / e.target.clientWidth; this.y = (e.offsetY * height) / e.target.clientHeight; }, onImageLoaded(e) { this.loaded_image_width = e.target.naturalWidth; this.loaded_image_height = e.target.naturalHeight; this.updateViewbox(this.loaded_image_width, this.loaded_image_height); this.$emit("loaded", { width: this.loaded_image_width, height: this.loaded_image_height, source: e.target.src }); }, onMouseEvent(type, e) { const imageWidth = this.src ? this.loaded_image_width : this.size ? this.size[0] : 1; const imageHeight = this.src ? this.loaded_image_height : this.size ? this.size[1] : 1; this.$emit("mouse", { mouse_event_type: type, image_x: (e.offsetX * imageWidth) / this.$refs.img.clientWidth, image_y: (e.offsetY * imageHeight) / this.$refs.img.clientHeight, button: e.button, buttons: e.buttons, altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey, }); }, onPointerEvent(type, e) { const imageWidth = this.src ? this.loaded_image_width : this.size ? this.size[0] : 1; const imageHeight = this.src ? this.loaded_image_height : this.size ? this.size[1] : 1; this.$emit(`svg:${type}`, { type: type, element_id: e.target.id, image_x: (e.offsetX * imageWidth) / this.$refs.svg.clientWidth, image_y: (e.offsetY * imageHeight) / this.$refs.svg.clientHeight, }); }, updateViewbox(width, height) { this.viewBox = `0 0 ${width} ${height}`; }, }, computed: { onCrossEvents() { if (!this.cross && !this.$slots.cross) return {}; return { mouseenter: () => (this.showCross = true), mouseleave: () => (this.showCross = false), mousemove: (event) => this.updateCrossHair(event), }; }, onUserEvents() { const events = {}; for (const type of this.events || []) { events[type] = (event) => this.onMouseEvent(type, event); } return events; }, }, props: { src: String, content: String, size: Object, events: Array, cross: Boolean, t: String, }, };