enlarger
Version:
A image enlarger library for web app.
188 lines (187 loc) • 8.44 kB
JavaScript
var E = Object.defineProperty;
var d = Object.getOwnPropertySymbols;
var b = Object.prototype.hasOwnProperty, C = Object.prototype.propertyIsEnumerable;
var m = (i, e, t) => e in i ? E(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, u = (i, e) => {
for (var t in e || (e = {}))
b.call(e, t) && m(i, t, e[t]);
if (d)
for (var t of d(e))
C.call(e, t) && m(i, t, e[t]);
return i;
};
var s = (i, e, t) => (m(i, typeof e != "symbol" ? e + "" : e, t), t);
import { css as f, addClass as W } from "fourdom";
var h = /* @__PURE__ */ ((i) => (i.getContainerError = "container element is missing.", i.getMagnifierElError = "magnifier element is missing.", i.getEnlargerImageWrapperElError = "enlarger image wrapper element is missing.", i.getPreviewContainerError = "preview container element is missing.", i.getPreviewImgElError = "preview <img /> element is missing.", i))(h || {}), n = /* @__PURE__ */ ((i) => (i.enlargerContainerClassName = "enlarger-container", i.enlargerImageWrapperClassName = "enlarger-image", i.enlargerImageClassName = "enlarger-image__inner", i.enlargerPreviewClassName = "enlarger-preview", i.enlargerPreviewImageClassName = "enlarger-preview__inner", i.enlargerMagnifierClassName = "enlarger-image__magnifier", i))(n || {});
class L {
constructor(e) {
s(this, "userOptions", {
container: "",
src: ""
});
s(this, "options", {
container: "",
src: "",
alt: "",
width: 0,
height: 0,
autoSize: !1,
magnification: 2,
magnifierColor: "rgba(255, 255, 255, 0.2)",
magnifierSizeRatio: 0.5,
magnifierCursor: "crosshair",
magnifierBorderColor: "#bbbbbb",
magnifierBorderWidth: "1px",
magnifierBorderStyle: "solid"
});
s(this, "magnifierWidth", 0);
s(this, "magnifierHeight", 0);
s(this, "magnifierVisible", !1);
s(this, "imgNaturalWidth", 0);
s(this, "imgNaturalHeight", 0);
s(this, "widthMagnification", 1);
s(this, "heightMagnification", 1);
s(this, "containerEl", null);
s(this, "resizeObserver", null);
this.userOptions = u({}, e), this.magnifierVisibleListener = this.magnifierVisibleListener.bind(this), this.previewListener = this.previewListener.bind(this), this.getImageNaturalSize(e.src, () => {
this.initResizeObserver(), this.render();
});
}
setOptions(e) {
return this.userOptions = Object.assign(this.userOptions, e), this.render(), this;
}
setWidth(e) {
return this.userOptions = Object.assign(this.userOptions, { width: e }), this.render(), this;
}
setHeight(e) {
return this.userOptions = Object.assign(this.userOptions, { height: e }), this.render(), this;
}
initResizeObserver() {
this.resizeObserver = new ResizeObserver((e) => {
for (const t of e) {
const r = t.target;
this.options.autoSize && this.setWidth(r.offsetWidth);
}
}), this.resizeObserver.observe(this.getContainer());
}
initOptions() {
const e = this.userOptions;
this.options = Object.assign(this.options, e), this.widthMagnification = e != null && e.width ? this.imgNaturalWidth / e.width : this.options.magnification, this.options.width = (e == null ? void 0 : e.width) || this.imgNaturalWidth / this.widthMagnification, this.heightMagnification = e != null && e.height ? this.imgNaturalHeight / e.height : this.widthMagnification, this.options.height = (e == null ? void 0 : e.height) || this.imgNaturalHeight / this.heightMagnification, this.magnifierWidth = this.options.width * this.options.magnifierSizeRatio, this.magnifierHeight = this.options.width * this.options.magnifierSizeRatio;
}
initCSSVars() {
const e = this.getContainer(), t = this.options.autoSize ? "auto" : `${this.options.width}px`, r = this.options.autoSize ? "auto" : `${this.options.height}px`;
f(e, {
"--enlarger-width": t,
"--enlarger-height": r,
"--enlarger-magnifier-color": this.options.magnifierColor,
"--enlarger-magnifier-width": `${this.magnifierWidth}px`,
"--enlarger-magnifier-height": `${this.magnifierHeight}px`,
"--enlarger-magnifier-border-width": this.options.magnifierBorderWidth,
"--enlarger-magnifier-border-color": this.options.magnifierBorderColor,
"--enlarger-magnifier-border-style": this.options.magnifierBorderStyle,
"--enlarger-magnifier-cursor": this.options.magnifierCursor,
"--enlarger-preview-position-left": `${this.options.width + 10}px`,
"--enlarger-preview-width": `${this.magnifierWidth * this.widthMagnification}px`,
"--enlarger-preview-height": `${this.magnifierHeight * this.heightMagnification}px`,
"--enlarger-preview-img-width": `${this.imgNaturalWidth}px`,
"--enlarger-preview-img-height": `${this.imgNaturalHeight}px`
});
}
getImageNaturalSize(e, t) {
const r = new Image();
r.src = e, r.onload = () => {
this.imgNaturalWidth = r.naturalWidth || r.width, this.imgNaturalHeight = r.naturalHeight || r.height, t && t();
};
}
getContainer() {
if (this.containerEl)
return this.containerEl;
try {
this.containerEl = typeof this.userOptions.container == "string" ? document.querySelector(this.userOptions.container) : this.userOptions.container;
} catch (e) {
throw Error(h.getContainerError);
}
return this.containerEl;
}
getMagnifierEl() {
const e = this.getContainer().querySelector(
`.${n.enlargerMagnifierClassName}`
);
if (!e)
throw Error(h.getMagnifierElError);
return e;
}
getEnlargerImageWrapperEl() {
const e = this.getContainer().querySelector(
`.${n.enlargerImageWrapperClassName}`
);
if (!e)
throw Error(h.getEnlargerImageWrapperElError);
return e;
}
getPreviewEl() {
const e = this.getContainer().querySelector(
`.${n.enlargerPreviewClassName}`
);
if (!e)
throw Error(h.getPreviewContainerError);
return e;
}
getPreviewImgEl() {
const e = this.getContainer().querySelector(
`.${n.enlargerPreviewImageClassName}`
);
if (!e)
throw Error(h.getPreviewImgElError);
return e;
}
magnifierVisibleListener() {
this.magnifierVisible = !this.magnifierVisible, f(this.getMagnifierEl(), {
display: this.magnifierVisible ? "block" : "none"
}), f(this.getPreviewEl(), {
display: this.magnifierVisible ? "block" : "none"
});
}
previewListener(e) {
const t = this.getContainer(), r = this.getEnlargerImageWrapperEl(), a = this.getMagnifierEl(), l = this.getPreviewImgEl(), v = e.pageX - t.offsetLeft, w = e.pageY - t.offsetTop, p = t.offsetWidth - a.offsetWidth, c = t.offsetHeight - a.offsetHeight;
let o = v - a.offsetWidth / 2, g = w - a.offsetHeight / 2;
o <= 0 && (o = 0), o >= p && (o = p), g < 0 && (g = 0), g >= c && (g = c), a.style.left = o + "px", a.style.top = g + "px", l.style.left = -o / r.offsetWidth * l.offsetWidth + "px", l.style.top = -g / r.offsetHeight * l.offsetHeight + "px";
}
registorListeners() {
const e = this.getEnlargerImageWrapperEl();
this.removeListeners(), e.addEventListener("mouseover", this.magnifierVisibleListener), e.addEventListener("mouseout", this.magnifierVisibleListener), e.addEventListener("mousemove", this.previewListener);
}
removeListeners() {
const e = this.getEnlargerImageWrapperEl();
e.removeEventListener(
"mouseover",
this.magnifierVisibleListener
), e.removeEventListener(
"mouseout",
this.magnifierVisibleListener
), e.removeEventListener("mousemove", this.previewListener);
}
render() {
this.initOptions(), this.initCSSVars();
const e = this.getContainer();
W(e, n.enlargerContainerClassName);
const t = `
<div class="${n.enlargerImageWrapperClassName}">
<img src="${this.options.src}" alt="${this.options.alt}" class="${n.enlargerImageClassName}" />
<div class="${n.enlargerMagnifierClassName}"></div>
</div>
<div class="${n.enlargerPreviewClassName}">
<img src="${this.options.src}" alt="${this.options.alt}" class="${n.enlargerPreviewImageClassName}" />
</div>
`;
e.innerHTML = t, this.registorListeners();
}
destory() {
var e;
this.removeListeners(), (e = this.resizeObserver) == null || e.unobserve(this.getContainer());
}
}
const y = (i) => new L(i);
export {
L as Enlarger,
y as createEnlarger
};