UNPKG

6.34 kBJavaScriptView Raw
1var __defProp = Object.defineProperty;
2var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3var __getOwnPropNames = Object.getOwnPropertyNames;
4var __hasOwnProp = Object.prototype.hasOwnProperty;
5var __export = (target, all) => {
6 for (var name2 in all)
7 __defProp(target, name2, { get: all[name2], enumerable: true });
8};
9var __copyProps = (to, from, except, desc) => {
10 if (from && typeof from === "object" || typeof from === "function") {
11 for (let key of __getOwnPropNames(from))
12 if (!__hasOwnProp.call(to, key) && key !== except)
13 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14 }
15 return to;
16};
17var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18var stdin_exports = {};
19__export(stdin_exports, {
20 default: () => stdin_default,
21 signatureProps: () => signatureProps
22});
23module.exports = __toCommonJS(stdin_exports);
24var import_vue = require("vue");
25var import_utils = require("../utils");
26var import_use = require("@vant/use");
27var import_use_expose = require("../composables/use-expose");
28var import_button = require("../button");
29const [name, bem, t] = (0, import_utils.createNamespace)("signature");
30const signatureProps = {
31 tips: String,
32 type: (0, import_utils.makeStringProp)("png"),
33 penColor: (0, import_utils.makeStringProp)("#000"),
34 lineWidth: (0, import_utils.makeNumberProp)(3),
35 clearButtonText: String,
36 backgroundColor: (0, import_utils.makeStringProp)(""),
37 confirmButtonText: String
38};
39const hasCanvasSupport = () => {
40 var _a;
41 const canvas = document.createElement("canvas");
42 return !!((_a = canvas.getContext) == null ? void 0 : _a.call(canvas, "2d"));
43};
44var stdin_default = (0, import_vue.defineComponent)({
45 name,
46 props: signatureProps,
47 emits: ["submit", "clear", "start", "end", "signing"],
48 setup(props, {
49 emit
50 }) {
51 const canvasRef = (0, import_vue.ref)();
52 const wrapRef = (0, import_vue.ref)();
53 const ctx = (0, import_vue.computed)(() => {
54 if (!canvasRef.value) return null;
55 return canvasRef.value.getContext("2d");
56 });
57 const isRenderCanvas = import_utils.inBrowser ? hasCanvasSupport() : true;
58 let canvasWidth = 0;
59 let canvasHeight = 0;
60 let canvasRect;
61 const touchStart = () => {
62 if (!ctx.value) {
63 return false;
64 }
65 ctx.value.beginPath();
66 ctx.value.lineWidth = props.lineWidth;
67 ctx.value.strokeStyle = props.penColor;
68 canvasRect = (0, import_use.useRect)(canvasRef);
69 emit("start");
70 };
71 const touchMove = (event) => {
72 if (!ctx.value) {
73 return false;
74 }
75 (0, import_utils.preventDefault)(event);
76 const touch = event.touches[0];
77 const mouseX = touch.clientX - ((canvasRect == null ? void 0 : canvasRect.left) || 0);
78 const mouseY = touch.clientY - ((canvasRect == null ? void 0 : canvasRect.top) || 0);
79 ctx.value.lineCap = "round";
80 ctx.value.lineJoin = "round";
81 ctx.value.lineTo(mouseX, mouseY);
82 ctx.value.stroke();
83 emit("signing", event);
84 };
85 const touchEnd = (event) => {
86 (0, import_utils.preventDefault)(event);
87 emit("end");
88 };
89 const isCanvasEmpty = (canvas) => {
90 const empty = document.createElement("canvas");
91 empty.width = canvas.width;
92 empty.height = canvas.height;
93 if (props.backgroundColor) {
94 const emptyCtx = empty.getContext("2d");
95 setCanvasBgColor(emptyCtx);
96 }
97 return canvas.toDataURL() === empty.toDataURL();
98 };
99 const setCanvasBgColor = (ctx2) => {
100 if (ctx2 && props.backgroundColor) {
101 ctx2.fillStyle = props.backgroundColor;
102 ctx2.fillRect(0, 0, canvasWidth, canvasHeight);
103 }
104 };
105 const submit = () => {
106 var _a, _b;
107 const canvas = canvasRef.value;
108 if (!canvas) {
109 return;
110 }
111 const isEmpty = isCanvasEmpty(canvas);
112 const image = isEmpty ? "" : ((_b = (_a = {
113 jpg: () => canvas.toDataURL("image/jpeg", 0.8),
114 jpeg: () => canvas.toDataURL("image/jpeg", 0.8)
115 })[props.type]) == null ? void 0 : _b.call(_a)) || canvas.toDataURL(`image/${props.type}`);
116 emit("submit", {
117 image,
118 canvas
119 });
120 };
121 const clear = () => {
122 if (ctx.value) {
123 ctx.value.clearRect(0, 0, canvasWidth, canvasHeight);
124 ctx.value.closePath();
125 setCanvasBgColor(ctx.value);
126 }
127 emit("clear");
128 };
129 const initialize = () => {
130 var _a, _b, _c;
131 if (isRenderCanvas && canvasRef.value) {
132 const canvas = canvasRef.value;
133 const dpr = import_utils.inBrowser ? window.devicePixelRatio : 1;
134 canvasWidth = canvas.width = (((_a = wrapRef.value) == null ? void 0 : _a.offsetWidth) || 0) * dpr;
135 canvasHeight = canvas.height = (((_b = wrapRef.value) == null ? void 0 : _b.offsetHeight) || 0) * dpr;
136 (_c = ctx.value) == null ? void 0 : _c.scale(dpr, dpr);
137 setCanvasBgColor(ctx.value);
138 }
139 };
140 const resize = () => {
141 if (ctx.value) {
142 const data = ctx.value.getImageData(0, 0, canvasWidth, canvasHeight);
143 initialize();
144 ctx.value.putImageData(data, 0, 0);
145 }
146 };
147 (0, import_vue.watch)(import_utils.windowWidth, resize);
148 (0, import_vue.onMounted)(initialize);
149 (0, import_use_expose.useExpose)({
150 resize,
151 clear,
152 submit
153 });
154 return () => (0, import_vue.createVNode)("div", {
155 "class": bem()
156 }, [(0, import_vue.createVNode)("div", {
157 "class": bem("content"),
158 "ref": wrapRef
159 }, [isRenderCanvas ? (0, import_vue.createVNode)("canvas", {
160 "ref": canvasRef,
161 "onTouchstartPassive": touchStart,
162 "onTouchmove": touchMove,
163 "onTouchend": touchEnd
164 }, null) : (0, import_vue.createVNode)("p", null, [props.tips])]), (0, import_vue.createVNode)("div", {
165 "class": bem("footer")
166 }, [(0, import_vue.createVNode)(import_button.Button, {
167 "size": "small",
168 "onClick": clear
169 }, {
170 default: () => [props.clearButtonText || t("clear")]
171 }), (0, import_vue.createVNode)(import_button.Button, {
172 "type": "primary",
173 "size": "small",
174 "onClick": submit
175 }, {
176 default: () => [props.confirmButtonText || t("confirm")]
177 })])]);
178 }
179});