UNPKG

deary-sign

Version:
178 lines (177 loc) 6.14 kB
import { ref as r, computed as D, onMounted as J, onUnmounted as O, openBlock as A, createElementBlock as H } from "vue"; const G = { __name: "DearySign", props: { width: { type: Number, default: 800 }, height: { type: Number, default: 300 }, lineWidth: { type: Number, default: 4 }, lineColor: { type: String, default: "#000000" }, bgColor: { type: String, default: "" }, isCrop: { type: Boolean, default: !1 }, isClearBgColor: { type: Boolean, default: !0 }, format: { type: String, default: "image/png" }, quality: { type: Number, default: 1 } }, setup(X, { expose: Y }) { const l = r(null), y = r(!1), C = r(""), d = r([]), f = r(0), p = r(0), w = r(!1), c = r(1), o = X, B = D(() => o.height / o.width), g = D(() => l.value.getBoundingClientRect()), b = D(() => o.bgColor ? o.bgColor : "rgba(255, 255, 255, 0)"), T = () => { const e = l.value; e.style.width = o.width + "px"; const t = parseFloat(window.getComputedStyle(e).width); e.style.height = B.value * t + "px"; const u = e.getContext("2d"); u.scale(1 * c.value, 1 * c.value), c.value = t / o.width, u.scale(1 / c.value, 1 / c.value); }, M = (e) => { f.value = e.x, p.value = e.y; const t = l.value.getContext("2d"); t.beginPath(), t.moveTo(f.value, p.value), t.lineTo(e.x, e.y), t.lineCap = "round", t.lineJoin = "round", t.lineWidth = o.lineWidth * c.value, t.stroke(), t.closePath(), d.value.push(e); }, S = (e) => { const t = l.value.getContext("2d"); t.beginPath(), t.moveTo(f.value, p.value), t.lineTo(e.x, e.y), t.strokeStyle = o.lineColor, t.lineWidth = o.lineWidth * c.value, t.lineCap = "round", t.lineJoin = "round", t.stroke(), t.closePath(), p.value = e.y, f.value = e.x, d.value.push(e); }, _ = (e) => { const t = l.value.getContext("2d"); t.beginPath(), t.moveTo(f.value, p.value), t.lineTo(e.x, e.y), t.lineCap = "round", t.lineJoin = "round", t.stroke(), t.closePath(), d.value.push(e), d.value.push({ x: -1, y: -1 }); }, I = (e) => { e.preventDefault(), w.value = !0, y.value = !0; let t = { x: e.offsetX, y: e.offsetY }; M(t); }, P = (e) => { if (e.preventDefault(), w.value) { let t = { x: e.offsetX, y: e.offsetY }; S(t); } }, E = (e) => { e.preventDefault(); let t = { x: e.offsetX, y: e.offsetY }; _(t), w.value = !1; }, W = (e) => { if (e.preventDefault(), y.value = !0, e.touches.length === 1) { let t = { x: e.targetTouches[0].clientX - g.value.left, y: e.targetTouches[0].clientY - g.value.top }; M(t); } }, q = (e) => { if (e.preventDefault(), e.touches.length === 1) { let t = { x: e.targetTouches[0].clientX - g.value.left, y: e.targetTouches[0].clientY - g.value.top }; S(t); } }, F = (e) => { if (e.preventDefault(), e.touches.length === 1) { let t = { x: e.targetTouches[0].clientX - g.value.left, y: e.targetTouches[0].clientY - g.value.top }; _(t); } }, k = (e) => { let t = e && e.format ? e.format : o.format, u = e && e.quality ? e.quality : o.quality; return new Promise((s, i) => { if (!y.value) { i("未签名"); return; } const a = l.value, n = a.getContext("2d"), v = n.getImageData(0, 0, a.width, a.height); n.globalCompositeOperation = "destination-over", n.fillStyle = b.value, n.fillRect(0, 0, a.width, a.height), C.value = a.toDataURL(t, u); let R = C.value; if (n.clearRect(0, 0, a.width, a.height), n.putImageData(v, 0, 0), n.globalCompositeOperation = "source-over", o.isCrop) { const m = U(v.data); let h = document.createElement("canvas"); const x = h.getContext("2d"); h.width = m[2] - m[0], h.height = m[3] - m[1]; const z = n.getImageData(...m); x.globalCompositeOperation = "destination-over", x.putImageData(z, 0, 0), x.fillStyle = b.value, x.fillRect(0, 0, 0, h.width, h.height), R = h.toDataURL(t, u), h = null; } s(R); }); }, L = (e) => new Promise((t, u) => { k(e).then((s) => { fetch(s).then((i) => i.blob()).then((i) => { const a = new File([i], "sign.png", { type: "image/png" }); t({ file: a, base64: s }); }); }).catch((s) => { u(s); }); }), N = () => { const e = l.value; e.getContext("2d").clearRect(0, 0, e.width, e.height), o.isClearBgColor && (e.style.background = "rgba(255, 255, 255, 0)"), d.value = [], y.value = !1, C.value = ""; }, U = (e) => { let t = l.value.width, u = 0, s = l.value.height, i = 0; for (let a = 0; a < l.value.width; a++) for (let n = 0; n < l.value.height; n++) { const v = (a + l.value.width * n) * 4; (e[v] > 0 || e[v + 1] > 0 || e[v + 2] || e[v + 3] > 0) && (i = Math.max(n, i), u = Math.max(a, u), s = Math.min(n, s), t = Math.min(a, t)); } return t++, u++, s++, i++, [t, s, u, i]; }; return J(() => { const e = l.value; e.height = o.height, e.width = o.width, e.style.background = b.value, T(), document.onmouseup = () => { w.value = !1; }, window.addEventListener("resize", T); }), O(() => { document.onmouseup = null, window.removeEventListener("resize", T); }), Y({ generate: k, generateFile: L, reset: N }), (e, t) => (A(), H("canvas", { class: "deary-sign", ref_key: "canvasRef", ref: l, style: { "max-width": "100%", display: "block" }, onMousedown: I, onMousemove: P, onMouseup: E, onTouchstart: W, onTouchmove: q, onTouchend: F }, null, 544)); } }; export { G as DearySign };