From 4805c7ee3587d5941179e43d8bd53c472a2424af Mon Sep 17 00:00:00 2001 From: shawko Date: Tue, 12 May 2026 15:26:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=BB=E6=9D=BF?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignaturePad/index.vue | 33 ++++++++- src/components/question/answer/HandDrawn.vue | 36 ++++----- src/page/subject/doWork/index.vue | 22 +++++- src/stores/global.ts | 20 +++-- src/utils/android.ts | 2 +- src/utils/cosUpload.ts | 78 +++++++++++++++++--- 6 files changed, 146 insertions(+), 45 deletions(-) diff --git a/src/components/SignaturePad/index.vue b/src/components/SignaturePad/index.vue index 5abd7d7..a0e024b 100644 --- a/src/components/SignaturePad/index.vue +++ b/src/components/SignaturePad/index.vue @@ -94,6 +94,17 @@ function handleSave() { } } +function dataUrlToBlob(dataUrl: string) { + const [header, body = ''] = dataUrl.split(',') + const mime = header.match(/data:(.*?);base64/)?.[1] || 'image/jpeg' + const binary = atob(body) + const bytes = new Uint8Array(binary.length) + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i) + } + return new Blob([bytes], { type: mime }) +} + function handleSaveAsync(): Promise<{ blob: Blob | null; data: string | null }> { return new Promise(resolve => { if (signaturePad.isEmpty() && !hasBackground) { @@ -102,7 +113,17 @@ function handleSaveAsync(): Promise<{ blob: Blob | null; data: string | null }> } const canvas = canvasRef.value as HTMLCanvasElement const pointData = JSON.stringify(signaturePad.toData()) - canvas.toBlob(blob => resolve({ blob, data: pointData }), 'image/jpeg', 0.85) + const resolveWithFallback = (blob: Blob | null) => { + resolve({ + blob: blob || dataUrlToBlob(canvas.toDataURL('image/jpeg', 0.85)), + data: pointData, + }) + } + if (typeof canvas.toBlob === 'function') { + canvas.toBlob(resolveWithFallback, 'image/jpeg', 0.85) + } else { + resolveWithFallback(null) + } }) } @@ -174,7 +195,8 @@ onMounted(() => { canvasRef.value.height = canvasPanelRef.value.clientHeight signaturePad = new SignaturePad(canvasRef.value, { backgroundColor: props.bg, - throttle: 0, + throttle: 16, + minDistance: 1, }) fillCanvasBackground() } @@ -203,9 +225,16 @@ defineExpose({ .signature-pad { width: 100%; height: 100%; + touch-action: none; + user-select: none; .canvas-panel { width: 100%; height: 100%; + touch-action: none; + canvas { + display: block; + touch-action: none; + } } } diff --git a/src/components/question/answer/HandDrawn.vue b/src/components/question/answer/HandDrawn.vue index d346316..37091da 100644 --- a/src/components/question/answer/HandDrawn.vue +++ b/src/components/question/answer/HandDrawn.vue @@ -1,6 +1,5 @@