UNPKG

magic-img

Version:

让你的图片加载更加优雅

113 lines (110 loc) 3.96 kB
import { __publicField } from "./chunk-NHABU752.mjs"; // src/magic.ts var wait = (time = 0) => new Promise((r) => setTimeout(r, time)); var imgPlaceholder = ["lqip", "blurhash"]; function install() { try { class MagicImg extends HTMLElement { constructor() { super(); __publicField(this, "initial", false); __publicField(this, "width", 0); __publicField(this, "height", 0); __publicField(this, "src", ""); __publicField(this, "content", ""); __publicField(this, "svg"); __publicField(this, "img"); __publicField(this, "smallImg"); this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); this.svg.setAttribute("preserveAspectRatio", "none"); this.img = new Image(); this.smallImg = new Image(); this.svg.classList.add("magic-placeholder"); this.smallImg.classList.add("magic-placeholder"); this.img.classList.add("magic-target"); } get data() { try { const src = this.getAttribute("src") || this.src; return JSON.parse(src); } catch (e) { console.log("src attribute error", e); return {}; } } async connectedCallback() { this.initial = true; if (!this.getAttribute("src") && !this.src) throw new Error("<magic-img /> src attribute is required\uFF0Csee\uFF1Ahttps://github.com/lishaobos/magic-img#%E4%BD%BF%E7%94%A8"); this.setPlaceholder(); this.appendChild(this.img); const intersection = new IntersectionObserver(async (entrys) => { for (const { isIntersecting } of entrys) { if (isIntersecting) { await this.start(); intersection.unobserve(this); intersection.disconnect(); } } }); intersection.observe(this); } setPlaceholder() { const { data } = this; this.setAttribute("magic", data.magic); this.img.removeAttribute("status"); if (imgPlaceholder.includes(data.magic)) { this.smallImg.src = data.content; this.smallImg.setAttribute("width", data.width); this.smallImg.setAttribute("height", data.height); this.svg.parentNode && this.svg.parentNode.removeChild(this.svg); this.appendChild(this.smallImg); } else { this.svg.setAttribute("width", data.width); this.svg.setAttribute("height", data.height); this.svg.setAttribute("viewBox", `0 0 ${data.width_ || data.width} ${data.height_ || data.height}`); this.svg.innerHTML = data.content; this.smallImg.parentNode && this.smallImg.parentNode.removeChild(this.smallImg); this.appendChild(this.svg); } } async start() { const { data } = this; requestAnimationFrame(() => { this.svg.setAttribute("status", "from"); this.smallImg.setAttribute("status", "from"); this.img.setAttribute("status", "from"); const start = performance.now(); this.img.onload = () => { const to = (isPrecive) => requestAnimationFrame(() => { const status = isPrecive ? "to" : "noPrevice"; this.svg.setAttribute("status", status); this.smallImg.setAttribute("status", status); this.img.setAttribute("status", status); }); to(performance.now() - start > 100); }; this.img.src = data.src; }); } static get observedAttributes() { return ["src"]; } async attributeChangedCallback() { if (!this.initial) return; this.setPlaceholder(); await wait(); await this.start(); } } customElements.define("magic-img", MagicImg); } catch { } } export { imgPlaceholder, install };