vue3-sign
Version:
electronic signature component library based on vue
167 lines (166 loc) • 5.31 kB
JavaScript
import { defineComponent, ref, onMounted, onUnmounted, openBlock, createElementBlock, createElementVNode, unref, withDirectives, vShow } from "vue";
var index_vue_vue_type_style_index_0_scoped_true_lang = "";
var _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _hoisted_1 = { class: "esign-wrapper" };
const _hoisted_2 = ["width", "height"];
const _hoisted_3 = { className: "sign-btnWrap" };
const _sfc_main = /* @__PURE__ */ defineComponent({
props: {
width: { default: 400 },
height: { default: 200 },
lineWidth: { default: 4 },
strokeColor: { default: "green" },
lineCap: { default: "round" },
lineJoin: { default: "round" },
bgColor: { default: "transparent" },
showBtn: { type: Boolean, default: true },
onSave: null,
onClear: null,
onDrawEnd: null
},
setup(__props) {
const props = __props;
const {
width,
height,
lineWidth,
strokeColor,
lineCap,
lineJoin,
bgColor,
showBtn,
onSave,
onClear,
onDrawEnd
} = props;
const canvasRef = ref(null);
const ctxRef = ref(null);
const client = ref({
offsetX: 0,
offsetY: 0,
endX: 0,
endY: 0
});
const mobileStatus = /Mobile|Android|iPhone/i.test(navigator.userAgent);
const cancel = () => {
if (canvasRef.value) {
const canvasCtx = canvasRef.value.getContext("2d");
canvasCtx.clearRect(0, 0, width, height);
onClear && onClear(canvasRef.value);
}
};
const save = () => {
canvasRef.value.toBlob((blob) => {
const date = Date.now().toString();
const a = document.createElement("a");
a.download = `${date}.png`;
a.href = URL.createObjectURL(blob);
a.click();
a.remove();
onSave && onSave(blob);
});
};
const draw = (event) => {
const { pageX, pageY } = mobileStatus ? event.changedTouches[0] : event;
const canvas = canvasRef.value;
const { x, y } = canvas.getBoundingClientRect();
client.value.endX = pageX;
client.value.endY = pageY;
ctxRef.value.lineTo(pageX - x, pageY - y);
ctxRef.value.stroke();
};
const init = (event) => {
const { offsetX, offsetY, pageX, pageY } = mobileStatus ? event.changedTouches[0] : event;
const canvas = canvasRef.value;
const { x, y } = canvas.getBoundingClientRect();
client.value.offsetX = offsetX;
client.value.offsetY = offsetY;
client.value.endX = pageX;
client.value.endY = pageY;
ctxRef.value.beginPath();
ctxRef.value.lineWidth = lineWidth;
ctxRef.value.strokeStyle = strokeColor;
ctxRef.value.lineCap = lineCap;
ctxRef.value.lineJoin = lineJoin;
ctxRef.value.moveTo(client.value.endX - x, client.value.endY - y);
window.addEventListener(mobileStatus ? "touchmove" : "mousemove", draw);
};
const closeDraw = () => {
console.log(ctxRef.value);
ctxRef.value.closePath();
window.removeEventListener("mousemove", draw);
onDrawEnd && onDrawEnd(canvasRef.current);
};
const initCanvas = () => {
const canvas = canvasRef.value;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctxRef.value = ctx;
ctxRef.value.fillStyle = bgColor;
ctxRef.value.fillRect(0, 0, width, height);
};
const addEventListener = () => {
window.addEventListener(mobileStatus ? "touchstart" : "mousedown", init);
window.addEventListener(mobileStatus ? "touchend" : "mouseup", closeDraw);
};
const removeEventListener = () => {
window.removeEventListener(mobileStatus ? "touchstart" : "mousedown", init);
window.removeEventListener(mobileStatus ? "touchend" : "mouseup", closeDraw);
};
const initEsign = () => {
initCanvas();
addEventListener();
};
onMounted(() => {
initEsign();
});
onUnmounted(() => {
removeEventListener();
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", _hoisted_1, [
createElementVNode("canvas", {
ref: (_value, _refs) => {
_refs["canvasRef"] = _value;
canvasRef.value = _value;
},
width: unref(width),
height: unref(height),
style: { "border": "1px solid #ccc" }
}, null, 8, _hoisted_2),
withDirectives(createElementVNode("div", _hoisted_3, [
createElementVNode("span", {
onClick: cancel,
className: "sign-btn"
}, "\u6E05\u9664"),
createElementVNode("span", {
onClick: save,
className: "sign-btn primary"
}, "\u4FDD\u5B58")
], 512), [
[vShow, unref(showBtn)]
])
]);
};
}
});
var ESign = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f9eba666"]]);
const ESignPlugin = {
install(app) {
app.component("ESign", ESign);
}
};
const XiPlugin = {
install(app) {
var _a;
(_a = ESignPlugin.install) == null ? void 0 : _a.call(ESignPlugin, app);
}
};
export { ESign, ESignPlugin, XiPlugin as default };