fix[design]: 修复签名异常

- 签名题目在特定情况下会出现边框溢出的问题, 现在将边框的宽度设定为 window.innerWidth * 0.8
This commit is contained in:
Huangzhe
2025-03-25 09:30:59 +08:00
parent aca8699778
commit 40519243b8

View File

@@ -17,7 +17,7 @@ const errorMessage = defineModel<string>('errorMessage', { default: '' });
const isPreview = defineModel('isPreview', { default: false }); const isPreview = defineModel('isPreview', { default: false });
const signatureCanvas = useTemplateRef('signatureCanvas'); const signatureCanvas = useTemplateRef('signatureCanvas');
const canvasWidth = ref(100); const canvasWidth = ref(window.innerWidth * 0.8);
const canvasHeight = computed(() => canvasWidth.value / 1); const canvasHeight = computed(() => canvasWidth.value / 1);
const isEraser = ref(false); const isEraser = ref(false);
@@ -62,15 +62,13 @@ const togglePen = () => {
setPenStyle(); setPenStyle();
}; };
const route = useRoute() const route = useRoute();
onMounted(() => { onMounted(() => {
// 设置页面刷新标记 // 设置页面刷新标记
sessionStorage.setItem('is_page_refresh', '1'); sessionStorage.setItem('is_page_refresh', '1');
if (!signatureCanvas.value) return; if (!signatureCanvas.value) return;
// 将 canvas 宽度和窗口的宽度保持一致
canvasWidth.value = window.innerWidth - 60;
// 获取 canvas 上下文 // 获取 canvas 上下文
ctx = signatureCanvas.value.getContext('2d')!; ctx = signatureCanvas.value.getContext('2d')!;
@@ -196,7 +194,7 @@ let aIndex = 1;
/** /**
* 上传文件 * 上传文件
*/ */
async function handleUploadImg () { async function handleUploadImg() {
// const file = new File([saveCanvas('blob')!], 'sign.png', { type: 'image/png' }); // const file = new File([saveCanvas('blob')!], 'sign.png', { type: 'image/png' });
// const res = await CommonApi.cosUpload(file); // const res = await CommonApi.cosUpload(file);
// console.log(`sign upload url`, res); // console.log(`sign upload url`, res);
@@ -219,7 +217,7 @@ async function handleUploadImg () {
* 当组件注销时需要保存状态存到本地indexDB ,然后等待下次组件加载时恢复 * 当组件注销时需要保存状态存到本地indexDB ,然后等待下次组件加载时恢复
* 但在页面刷新时不保存 * 但在页面刷新时不保存
*/ */
function saveCanvasState () { function saveCanvasState() {
if (!ctx || !signatureCanvas.value) return; if (!ctx || !signatureCanvas.value) return;
const imageData = ctx.getImageData(0, 0, canvasWidth.value, canvasHeight.value); const imageData = ctx.getImageData(0, 0, canvasWidth.value, canvasHeight.value);
undoStack.value.push(imageData); undoStack.value.push(imageData);
@@ -278,7 +276,10 @@ function saveCanvasState () {
const tx = db.transaction('canvasState', 'readwrite'); const tx = db.transaction('canvasState', 'readwrite');
const store = tx.objectStore('canvasState'); const store = tx.objectStore('canvasState');
// 只存储 base64 字符串,而不是 ImageData 对象 // 只存储 base64 字符串,而不是 ImageData 对象
store.put({ canvasDataUrl, currentStep: currentStep.value }, element.value.id || 'default_id'); store.put(
{ canvasDataUrl, currentStep: currentStep.value },
element.value.id || 'default_id'
);
tx.oncomplete = () => { tx.oncomplete = () => {
db.close(); db.close();
}; };
@@ -290,13 +291,13 @@ function saveCanvasState () {
onUnmounted(() => { onUnmounted(() => {
// 当组件注销时,保存状态 // 当组件注销时,保存状态
saveCanvasState(); saveCanvasState();
}) });
/** /**
* 恢复canvas 状态 * 恢复canvas 状态
* 当组件加载时需要从localStorage恢复状态 * 当组件加载时需要从localStorage恢复状态
*/ */
function restoreCanvasState () { function restoreCanvasState() {
// 没有 indexDB, 不恢复 // 没有 indexDB, 不恢复
if (!window.indexedDB) return; if (!window.indexedDB) return;
if (!ctx || !signatureCanvas.value) return; if (!ctx || !signatureCanvas.value) return;
@@ -352,12 +353,12 @@ function restoreCanvasState () {
onMounted(() => { onMounted(() => {
// 当组件加载时,恢复状态 // 当组件加载时,恢复状态
restoreCanvasState(); restoreCanvasState();
}) });
/** /**
* 清除画布状态 * 清除画布状态
*/ */
function clearCanvasState () { function clearCanvasState() {
if (window.indexedDB) { if (window.indexedDB) {
try { try {
const request = window.indexedDB.open('canvasState', 1); const request = window.indexedDB.open('canvasState', 1);
@@ -386,23 +387,44 @@ window.addEventListener('beforeunload', () => {
</script> </script>
<template> <template>
<van-field :label="element.stem" :required="element.config.is_required === 1" label-align="top" :border="false" <van-field
readonly> :label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
:border="false"
readonly
>
<template #left-icon> {{ isPreview ? element.title : index + 1 }}. </template> <template #left-icon> {{ isPreview ? element.title : index + 1 }}. </template>
<template #label> <template #label>
<contenteditable v-model="element.stem" className="contenteditable-label" :active="active" @blur="emitValue" <contenteditable
:errorMessage="errorMessage"></contenteditable> v-model="element.stem"
className="contenteditable-label"
:active="active"
@blur="emitValue"
:errorMessage="errorMessage"
></contenteditable>
</template> </template>
<template #input> <template #input>
<div class="sign-question"> <div class="sign-question">
<canvas ref="signatureCanvas" :width="canvasWidth" :height="canvasHeight" <canvas
style="border: 1px dashed #ccc; border-radius: 4px"> ref="signatureCanvas"
:width="canvasWidth"
:height="canvasHeight"
style="border: 1px dashed #ccc; border-radius: 4px"
>
</canvas> </canvas>
<div class="sign-text" :class="{ show: true }"> <div class="sign-text" :class="{ show: true }">
<span class="icon mobilefont mobilefont-qingkong" title="清空" @click="clearCanvas"></span> <span
class="icon mobilefont mobilefont-qingkong"
title="清空"
@click="clearCanvas"
></span>
<span class="icon mobilefont mobilefont-chexiao" @click="undo"></span> <span class="icon mobilefont mobilefont-chexiao" @click="undo"></span>
<span class="icon mobilefont" :class="isEraser ? 'mobilefont-huabi' : 'mobilefont-rubber'" <span
@click="togglePen"></span> class="icon mobilefont"
:class="isEraser ? 'mobilefont-huabi' : 'mobilefont-rubber'"
@click="togglePen"
></span>
<span class="icon mobilefont mobilefont-shangchuan" @click="handleUploadImg"></span> <span class="icon mobilefont mobilefont-shangchuan" @click="handleUploadImg"></span>
</div> </div>
<div class="sign-tips">请在空白区域书写您的签名</div> <div class="sign-tips">请在空白区域书写您的签名</div>