uniApp利用canvas制作署名板

[复制链接]
发表于 2025-12-30 09:31:45 | 显示全部楼层 |阅读模式

插件市场大佬封装好的 组件 可以直接拿已往
  1. <template>
  2.   <view
  3.     class="whole canvas-autograph flexc"
  4.     @touchmove.prevent.stop
  5.     @wheel.prevent.stop
  6.     v-show="modelValue"
  7.   >
  8.     <canvas
  9.       class="scroll-view"
  10.       id="mycanvas"
  11.       canvas-id="mycanvas"
  12.       @touchstart="touchstart"
  13.       @touchmove="touchmove"
  14.       @touchend="touchend"
  15.     />
  16.     <view class="fun-box">
  17.       <view
  18.         class="fun-box-btn clear flex"
  19.         @click="clear"
  20.       >
  21.         <text>清空</text>
  22.       </view>
  23.       <view
  24.         class="fun-box-btn confirm flex"
  25.         @click="confirm"
  26.       >
  27.         <text>确认</text>
  28.       </view>
  29.       <view
  30.         class="fun-box-btn cancel flex"
  31.         @click="cancel"
  32.       >
  33.         <text>取消</text>
  34.       </view>
  35.     </view>
  36.   </view>
  37. </template>
  38. <script setup>
  39. /*
  40.                 使用如下
  41.                 <canvas-autograph v-model="isCanvas" @complete="complete"/>
  42.                
  43.                 // 打开、关闭
  44.                 let isCanvas = ref(false)
  45.                 // 确认事件
  46.                 const complete = e=>{
  47.                         console.log(e)
  48.                 }
  49.        
  50.         */
  51. import { ref, reactive, watch, getCurrentInstance } from 'vue'
  52. const hasSignature = ref(false) // 新增:记录是否签名
  53. const emits = defineEmits(['update:modelValue', 'complete'])
  54. const props = defineProps({
  55.   modelValue: Boolean
  56. })
  57. const _this = getCurrentInstance()
  58. watch(
  59.   () => props.modelValue,
  60.   (e) => {
  61.     // 这里可进行 tabbar 的 显示、隐藏  不要也可以
  62.     // 自己写
  63.   },
  64.   {
  65.     immediate: true // 是否默认执行一次  默认为false
  66.   }
  67. )
  68. let points = reactive([]) //路径点集合
  69. let canvaCtx = reactive(uni.createCanvasContext('mycanvas', _this)) //创建绘图对象
  70. //设置画笔样式
  71. canvaCtx.lineWidth = 4
  72. canvaCtx.lineCap = 'round'
  73. canvaCtx.lineJoin = 'round'
  74. //触摸开始,获取到起点
  75. const touchstart = (e) => {
  76.   hasSignature.value = true // 有触摸操作则认为有签名
  77.   let startX = e.changedTouches[0].x
  78.   let startY = e.changedTouches[0].y
  79.   let startPoint = { X: startX, Y: startY }
  80.   points.push(startPoint)
  81.   //每次触摸开始,开启新的路径
  82.   canvaCtx.beginPath()
  83. }
  84. //触摸移动,获取到路径点
  85. const touchmove = (e) => {
  86.   let moveX = e.changedTouches[0].x
  87.   let moveY = e.changedTouches[0].y
  88.   let movePoint = { X: moveX, Y: moveY }
  89.   points.push(movePoint) //存点
  90.   let len = points.length
  91.   if (len >= 2) {
  92.     draw()
  93.   }
  94. }
  95. //绘制路径
  96. const draw = () => {
  97.   let point1 = points[0]
  98.   let point2 = points[1]
  99.   points.shift()
  100.   canvaCtx.moveTo(point1.X, point1.Y)
  101.   canvaCtx.lineTo(point2.X, point2.Y)
  102.   canvaCtx.stroke()
  103.   canvaCtx.draw(true)
  104. }
  105. // 触摸结束,将未绘制的点清空防止对后续路径产生干扰
  106. const touchend = (e) => {
  107.   points = []
  108. }
  109. // 清空画布
  110. const clear = () => {
  111.   hasSignature.value = false // 清空时重置签名标志
  112.   return uni
  113.     .getSystemInfo()
  114.     .then((res) => {
  115.       canvaCtx.clearRect(0, 0, res.windowWidth, res.windowHeight)
  116.       canvaCtx.draw(true)
  117.       return res
  118.     })
  119.     .catch((err) => {
  120.       // console.log(err);
  121.     })
  122. }
  123. // 确认
  124. const confirm = () => {
  125.   if (!hasSignature.value) {
  126.     // 如果没有签名,提示用户
  127.     uni.showToast({
  128.       title: '请先签名',
  129.       icon: 'none',
  130.       duration: 2000
  131.     })
  132.     return
  133.   }
  134.   uni.canvasToTempFilePath({ canvasId: 'mycanvas' }, _this, _this.parent).then((res) => {
  135.     console.log(res.tempFilePath)
  136.     emits('complete', res.tempFilePath)
  137.     cancel()
  138.   })
  139. }
  140. // 取消
  141. const cancel = () => {
  142.   clear().then((res) => emits('update:modelValue', false))
  143. }
  144. </script>
  145. <style scoped lang="scss">
  146. .canvas-autograph {
  147.   position: fixed;
  148.   z-index: 99999;
  149.   width: 100vw;
  150.   height: 100vh;
  151.   top: 0;
  152.   left: 0;
  153.   .scroll-view {
  154.     width: 100%;
  155.     height: 100%;
  156.     background-color: #ffffff;
  157.   }
  158.   .fun-box {
  159.     position: absolute;
  160.     right: 0;
  161.     bottom: 10vh;
  162.     height: auto;
  163.     display: flex;
  164.     flex-direction: column;
  165.     .fun-box-btn {
  166.       width: 100rpx;
  167.       height: 160rpx;
  168.       color: #ffffff;
  169.       border-radius: 20rpx;
  170.       border: 1rpx solid #c0c0c0;
  171.       display: flex;
  172.       align-items: center;
  173.       justify-content: center;
  174.       margin-bottom: 20rpx;
  175.       margin-right: 10rpx;
  176.       text {
  177.         transform: rotate(90deg);
  178.       }
  179.     }
  180.     .clear {
  181.       color: #909399;
  182.       background-color: #f4f4f5;
  183.     }
  184.     .confirm {
  185.       background-color: #409eff;
  186.     }
  187.     .cancel {
  188.       background-color: #f67d7d;
  189.     }
  190.   }
  191. }
  192. </style>
复制代码
子组件利用
  1.     <miliu-autograph
  2.       v-model="isCanvas"
  3.       @complete="complete"
  4.     ></miliu-autograph>
  5. let isCanvas = ref(false)
  6. function toCanvas() {
  7.   isCanvas.value = true
  8. }
  9. // 确认事件
  10. const complete = (e) => {
  11.   console.log(e) // 返回本地生成的base图片路径
  12.   // 上传签名图片
  13.   uni.getImageInfo({
  14.     src: e,
  15.     success: function (res) {
  16.       // uni.uploadFile({
  17.       //   url: baseUrl + '/file/upload', //后端接口地址
  18.       //   name: 'file', //必填 , 此为类型名称
  19.       //   filePath: res.path, //电子签名图片路径
  20.       //   header: {
  21.       //     Authorization: 'Bearer ' + that.token
  22.       //   },
  23.       //   success: (res) => {
  24.       //     console.log(res, '签名信息 ------ res');
  25.       //     //上传成功后逻辑
  26.       //     uni.showToast({
  27.       //       title: '签名成功!'
  28.       //     });
  29.       //   },
  30.       //   fail: (err) => {
  31.       //     console.log(err);
  32.       //     uni.showToast({
  33.       //       title: '签名失败!'
  34.       //     });
  35.       //   }
  36.       // });
  37.     }
  38.   })
  39. }
复制代码
再具体的我就不形貌了 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表