vue3-image-magnifier
Version:
Vue 3 Image Magnifier
164 lines (163 loc) • 5.01 kB
JavaScript
import { createElementBlock as h, openBlock as u, createElementVNode as m, createCommentVNode as p, normalizeStyle as z } from "vue";
const k = (e, o) => {
const i = e.__vccOpts || e;
for (const [n, r] of o)
i[n] = r;
return i;
}, v = {
props: {
src: {
type: String,
required: !0
},
alt: {
type: String,
default: "Image to magnify"
},
zoomLevel: {
type: Number,
default: 2
},
zoomWidth: {
type: Number,
default: 200
},
zoomHeight: {
type: Number,
default: 200
},
zoomBorder: {
type: String,
default: "2px solid #333"
},
zoomRadius: {
type: String,
default: "5px"
},
autoZoom: {
type: Boolean,
default: !0
}
},
data() {
return {
showZoom: !1,
// Controls the visibility of the zoom area
zoomStyle: {}
// Holds the dinamic styles settings for the zoom effect
};
},
methods: {
/**
* Toggles the zoom display on click when autoZoom is disabled.
*/
onClick() {
this.autoZoom || (this.showZoom = !this.showZoom);
},
/**
* Handles the keydown event to activate the zoom area when the Enter or Space key is pressed.
*
* @param {KeyboardEvent} event - The keydown event.
*/
onkeydown(e) {
(!this.autoZoom && e.key === "Enter" || e.key === " ") && (e.preventDefault(), this.onClick());
},
/**
* Updates the zoom style based on the provided x and y coordinates.
* Calculates the position of the zoom area and the corresponding background position.
*
* @param {Object} param0 - Object containing the x and y coordinates.
*/
updateZoomStyle({ x: e, y: o }) {
const i = this.$refs.imageRef, n = i.getBoundingClientRect(), r = e - n.left, t = o - n.top, s = r / n.width, d = t / n.height, a = i.width * this.zoomLevel, l = i.height * this.zoomLevel, c = a - this.zoomWidth, f = l - this.zoomHeight, g = s * c, y = d * f;
this.zoomStyle = {
left: `${r - this.zoomWidth / 2}px`,
top: `${t - this.zoomHeight / 2}px`,
width: `${this.zoomWidth}px`,
height: `${this.zoomHeight}px`,
border: this.zoomBorder,
borderRadius: this.zoomRadius,
backgroundImage: `url(${this.src})`,
backgroundSize: `${a}px ${l}px`,
backgroundPosition: `-${g}px -${y}px`
};
},
/**
* Handles both mouse and touch move events.
* Detects the type of event and extracts the appropriate x and y coordinates.
*
* @param {Event} event - The mouse or touch event.
*/
handleMove(e) {
let o, i;
if (e.type.startsWith("touch")) {
const n = e.touches[0];
o = n.clientX, i = n.clientY, e.preventDefault();
} else
o = e.clientX, i = e.clientY;
this.updateZoomStyle({ x: o, y: i });
},
/**
* Handles mouse move events.
* When autoZoom is enabled, the zoom area is activated and updated continuously.
*
* @param {MouseEvent} event - The mouse move event.
*/
onMouseMove(e) {
this.autoZoom ? (this.showZoom = !0, this.handleMove(e)) : this.showZoom && this.handleMove(e);
},
/**
* Hides the zoom area when the mouse leaves the image.
*/
onMouseLeave() {
this.showZoom = !1;
},
/**
* Activates the zoom area when a touch event starts.
*
* @param {TouchEvent} event - The touch start event.
*/
onTouchStart(e) {
this.showZoom = !0, this.handleMove(e);
},
/**
* Hides the zoom area when the touch event ends.
*/
onTouchEnd() {
this.showZoom = !1;
}
}
}, M = ["src", "alt"];
function b(e, o, i, n, r, t) {
return u(), h("div", {
class: "magnifier-container",
role: "button",
"aria-label": "Image magnifier",
tabindex: "0",
onClick: o[0] || (o[0] = (...s) => t.onClick && t.onClick(...s)),
onKeydown: o[1] || (o[1] = (...s) => t.onkeydown && t.onkeydown(...s)),
onMousemove: o[2] || (o[2] = (...s) => t.onMouseMove && t.onMouseMove(...s)),
onMouseleave: o[3] || (o[3] = (...s) => t.onMouseLeave && t.onMouseLeave(...s)),
onTouchstart: o[4] || (o[4] = (...s) => t.onTouchStart && t.onTouchStart(...s)),
onTouchmove: o[5] || (o[5] = (...s) => t.handleMove && t.handleMove(...s)),
onTouchend: o[6] || (o[6] = (...s) => t.onTouchEnd && t.onTouchEnd(...s))
}, [
m("img", {
src: i.src,
class: "magnifier-image",
ref: "imageRef",
alt: i.alt
}, null, 8, M),
r.showZoom ? (u(), h("div", {
key: 0,
class: "zoom-result",
style: z(r.zoomStyle),
"aria-hidden": "true"
}, null, 4)) : p("", !0),
o[7] || (o[7] = m("span", { class: "sr-only" }, " Use the mouse or the keyboard (Enter or Space) to activate the magnifier. ", -1))
], 32);
}
const w = /* @__PURE__ */ k(v, [["render", b], ["__scopeId", "data-v-76f1a2cb"]]);
export {
w as default
};