UNPKG

eyedropper-polyfill

Version:
81 lines (80 loc) 3.88 kB
import c from "html2canvas-pro"; function l() { return "EyeDropper" in window; } const r = "[EyeDropper]", s = { canvasError: r + " Error getting canvas", color: r + " Cannot get color" }; function n(i) { if (typeof i != "number" || Number.isNaN(i)) throw new Error(); return i + "px"; } const a = { value: !1 }; class d { colorSelectionResult; previousDocumentCursor; canvas; canvasCtx; resolve; lastPoint; magnification = { size: 4, scale: 12 }; constructor() { this.onMouseMove = this.onMouseMove.bind(this), this.onClick = this.onClick.bind(this); } async open(t = {}) { return a.value ? Promise.reject(new DOMException("Invalid state", "InvalidStateError")) : new Promise((o, e) => { if (t.signal) { if (t.signal.aborted) return this.stop(), e(t.signal.reason || new DOMException("Aborted", "AbortError")); t.signal.addEventListener("abort", () => { this.stop(), t.signal && e(t.signal.reason || new DOMException("Aborted", "AbortError")); }); } this.resolve = o, this.start(); }); } async start() { document.body.style.overflow = "hidden", this.setWaitingCursor(), await this.createScreenshot(), this.revertWaitingCursor(), this.bindEvents(); } stop() { document.body.style.overflow = "", this.unbindEvents(), this.removeScreenshot(), this.colorSelectionResult = void 0, this.lastPoint = void 0, a.value = !1; } async createScreenshot() { this.canvas = await c(document.body, { allowTaint: !0, useCORS: !0, height: document.body.scrollHeight, width: document.body.scrollWidth }), this.addCanvasStyle(this.canvas), this.canvasCtx = this.canvas.getContext("2d", { willReadFrequently: !0 }), document.body.appendChild(this.canvas); } removeScreenshot() { if (!this.canvas) throw new Error(s.canvasError); document.body.removeChild(this.canvas), this.canvas = void 0, this.canvasCtx = void 0; } setWaitingCursor() { this.previousDocumentCursor = document.documentElement.style.cursor, document.documentElement.style.cursor = "wait"; } revertWaitingCursor() { this.previousDocumentCursor ? document.documentElement.style.cursor = this.previousDocumentCursor : document.documentElement.style.cursor = "", this.previousDocumentCursor = void 0; } bindEvents() { window.addEventListener("mousemove", this.onMouseMove), window.addEventListener("click", this.onClick); } unbindEvents() { window.removeEventListener("mousemove", this.onMouseMove), window.removeEventListener("click", this.onClick); } onClick() { if (!this.lastPoint) throw new Error(s.color); this.detectColor(this.lastPoint); var t = this.colorSelectionResult; this.stop(), t && this.resolve && this.resolve(t); } onMouseMove(e) { if (!this.canvas || !this.canvasCtx) throw new Error(s.canvasError); var o = window.devicePixelRatio, e = (this.lastPoint = { x: (e.clientX + window.scrollX) * o, y: (e.clientY + window.scrollY) * o }, [n(this.lastPoint.x / o), n(this.lastPoint.y / o)].join(" ")); Object.assign(this.canvas.style, { opacity: 1, transformOrigin: e, clipPath: `circle(${n(this.magnification.size)} at ${e})` }); } detectColor(t) { if (!this.canvasCtx) throw new Error(s.canvasError); t = this.canvasCtx.getImageData(t.x, t.y, 1, 1).data, t = ((1 << 24) + (t[0] << 16) + (t[1] << 8) + t[2]).toString(16).slice(1), this.colorSelectionResult = { sRGBHex: "#" + t }; } addCanvasStyle(t) { Object.assign(t.style, { position: "fixed", top: "0px", marginTop: -window.scrollY + "px", left: "0px", zIndex: 999999, opacity: 0, transform: `scale(${this.magnification.scale})`, imageRendering: "pixelated" }); } } function h() { if (!Reflect.defineProperty(window, "EyeDropper", { value: d })) throw Error("Error attaching `EyeDropper` polyfill: couldn't attach `EyeDropper` to `window`"); } l() || h();