1 | var __defProp = Object.defineProperty;
|
2 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
3 | var __getOwnPropNames = Object.getOwnPropertyNames;
|
4 | var __hasOwnProp = Object.prototype.hasOwnProperty;
|
5 | var __export = (target, all) => {
|
6 | for (var name2 in all)
|
7 | __defProp(target, name2, { get: all[name2], enumerable: true });
|
8 | };
|
9 | var __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 | };
|
17 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
18 | var stdin_exports = {};
|
19 | __export(stdin_exports, {
|
20 | default: () => stdin_default,
|
21 | signatureProps: () => signatureProps
|
22 | });
|
23 | module.exports = __toCommonJS(stdin_exports);
|
24 | var import_vue = require("vue");
|
25 | var import_utils = require("../utils");
|
26 | var import_use = require("@vant/use");
|
27 | var import_use_expose = require("../composables/use-expose");
|
28 | var import_button = require("../button");
|
29 | const [name, bem, t] = (0, import_utils.createNamespace)("signature");
|
30 | const 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 | };
|
39 | const hasCanvasSupport = () => {
|
40 | var _a;
|
41 | const canvas = document.createElement("canvas");
|
42 | return !!((_a = canvas.getContext) == null ? void 0 : _a.call(canvas, "2d"));
|
43 | };
|
44 | var 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 | });
|