{"version":3,"file":"signature.vue.mjs","sources":["../../../../../../packages/components/signature/src/signature.vue"],"sourcesContent":["<template>\r\n  <div\r\n    :class=\"[\r\n      bem.b(),\r\n      disabled ? bem.is('disabled') : '',\r\n      hiddenBorder ? bem.is('hidden-border') : '',\r\n    ]\"\r\n    :style=\"{ width: props.width + 'px', height: props.height + 'px' }\"\r\n  >\r\n    <canvas ref=\"canvas\"></canvas>\r\n\r\n    <!-- 未签名时的占位符 -->\r\n    <div\r\n      v-if=\"!signatureExists && props.placeholder\"\r\n      :class=\"bem.e('placeholder')\"\r\n    >\r\n      <p>{{ props.placeholder }}</p>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup>\r\nimport { createNamespace } from '@ll-plus/utils'\r\nimport { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'\r\n\r\nimport SignaturePad from 'signature_pad'\r\n\r\nimport { signatureProps } from './signature'\r\n\r\ndefineOptions({ name: 'LlSignature' })\r\n\r\nconst bem = createNamespace('signaturer')\r\n\r\nconst props = defineProps(signatureProps)\r\n\r\nconst canvas = ref(null)\r\nconst signaturePad = ref(null)\r\n\r\nconst signatureExists = ref(false) // 当前画布上是否有签名存在\r\n\r\n// 监听宽高变化，重新初始化画布\r\nwatch(\r\n  () => [props.width, props.height],\r\n  () => {\r\n    nextTick(() => {\r\n      resizeCanvas()\r\n    })\r\n  }\r\n)\r\n\r\n// 监听线条样式变化\r\nwatch(\r\n  () => [props.lineWidth, props.strokeStyle],\r\n  () => {\r\n    if (signaturePad.value) {\r\n      signaturePad.value.minWidth = props.lineWidth\r\n      signaturePad.value.maxWidth = props.lineWidth * 2\r\n      signaturePad.value.penColor = props.strokeStyle\r\n    }\r\n  }\r\n)\r\n\r\n// 监听禁用状态变化\r\nwatch(\r\n  () => props.disabled,\r\n  (newVal) => {\r\n    if (newVal) {\r\n      disableSignaturePad()\r\n    } else {\r\n      enableSignaturePad()\r\n    }\r\n  }\r\n)\r\n\r\n// 初始化签名板\r\nconst initSignaturePad = () => {\r\n  if (!canvas.value) return\r\n\r\n  signaturePad.value = new SignaturePad(canvas.value, {\r\n    minWidth: props.lineWidth,\r\n    maxWidth: props.lineWidth * 2,\r\n    penColor: props.strokeStyle,\r\n    backgroundColor: 'rgb(255, 255, 255)',\r\n    throttle: 8, // 节流控制，优化性能\r\n    velocityFilterWeight: 0.8, // 速度过滤权重\r\n  })\r\n\r\n  // 设置画布尺寸\r\n  resizeCanvas()\r\n\r\n  // 监听签名开始事件\r\n  signaturePad.value.addEventListener('beginStroke', () => {\r\n    signatureExists.value = true\r\n  })\r\n\r\n  // 如果初始状态为禁用，则应用禁用逻辑\r\n  if (props.disabled) {\r\n    disableSignaturePad()\r\n  }\r\n}\r\n\r\n// 调整画布大小\r\nconst resizeCanvas = () => {\r\n  if (!canvas.value || !signaturePad.value) return\r\n\r\n  const ratio = Math.max(window.devicePixelRatio || 1, 1)\r\n\r\n  // 设置画布尺寸\r\n  canvas.value.width = props.width * ratio\r\n  canvas.value.height = props.height * ratio\r\n\r\n  // 设置CSS尺寸\r\n  canvas.value.style.width = `${props.width}px`\r\n  canvas.value.style.height = `${props.height}px`\r\n\r\n  // 缩放上下文\r\n  const ctx = canvas.value.getContext('2d')\r\n  ctx.scale(ratio, ratio)\r\n\r\n  // 清除并重新绘制签名\r\n  signaturePad.value.clear()\r\n}\r\n\r\n// 禁用签名板\r\nconst disableSignaturePad = () => {\r\n  if (signaturePad.value) {\r\n    // 移除所有事件监听\r\n    signaturePad.value.off()\r\n    // 设置画布为只读状态\r\n    canvas.value.style.pointerEvents = 'none'\r\n  }\r\n}\r\n\r\n// 启用签名板\r\nconst enableSignaturePad = () => {\r\n  if (signaturePad.value) {\r\n    // 重新附加事件监听\r\n    signaturePad.value.on()\r\n    // 恢复画布交互\r\n    canvas.value.style.pointerEvents = 'auto'\r\n\r\n    // 重新添加签名开始事件监听\r\n    signaturePad.value.addEventListener('beginStroke', () => {\r\n      signatureExists.value = true\r\n    })\r\n  }\r\n}\r\n\r\n// 清空签名\r\nconst clearSignature = () => {\r\n  if (signaturePad.value) {\r\n    signaturePad.value.clear()\r\n    signatureExists.value = false\r\n  }\r\n}\r\n\r\n// 保存签名为PNG\r\nconst saveSignature = () => {\r\n  if (!signatureExists.value || !signaturePad.value || props.disabled)\r\n    return null\r\n\r\n  const dataURL = signaturePad.value.toDataURL('image/png')\r\n  return dataURL\r\n}\r\n\r\n// 暴露方法给父组件\r\ndefineExpose({\r\n  saveSignature,\r\n  clearSignature,\r\n  enableSignaturePad,\r\n  disableSignaturePad,\r\n})\r\n\r\nonMounted(() => {\r\n  initSignaturePad()\r\n  window.addEventListener('resize', resizeCanvas)\r\n})\r\n\r\nonUnmounted(() => {\r\n  window.removeEventListener('resize', resizeCanvas)\r\n  if (signaturePad.value) {\r\n    signaturePad.value.off()\r\n  }\r\n})\r\n</script>\r\n"],"names":[],"mappings":"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"}