赞
踩
<template> <h3>在线签名</h3> <div ref="mainboard" class="container"> <div class="mianboard" :style="{ width: data.size.width + 'px', height: data.size.height + 'px' }"> <!-- 主画板 --> <canvas id="main" :width="data.size.width" :height="data.size.height"></canvas> <!-- 签名绘制浮层画板 --> <div ref="floatboard" v-show="show" class="floatboard" :style="{ left: left + 'px', top: top + 'px' }" @mousedown="floatMouseDown"> <canvas id="float" width="200" height="80"></canvas> </div> <div class="sab"> <button @click="save">保存</button> <button @click="backInit">清除</button> </div> </div> <div class="signboard"> <!-- 签名画板 --> <canvas id="sign" width="600" height="400" @mousedown="signMousedown" @mousemove="signMousemove" @mouseup="signMouseup"></canvas> <div> <button @click="clearSign">清除</button> <button @click="sendSignToFloat">确认</button> </div> </div> </div> </template> <script setup> import { onMounted, ref } from 'vue'; /* 画板相关变量 */ // 全局变量 let float = null; let floatCtx = null; let sign = null; let signCtx = null; let main = null; let mainCtx = null; let left = ref(0); let top = ref(0) let show = ref(false) // 后端数据 const data = { baseUrl: 'http://localhost:8080/img/%E6%8A%A5%E9%94%80%E5%8D%95.cd8b07df.jpg', size: { width: 600, height: 400 } } /* 主画板和其相关变量 */ onMounted(() => { // 获取主画板并且初始化为canvas画布 main = document.getElementById('main'); mainCtx = main.getContext('2d'); // 绘制合同图片为背景 const img = new Image(); img.src = data.baseUrl; img.onload = function () { mainCtx.drawImage(img, 0, 0, data.size.width, data.size.height); } }) // 保存签名 function save() { mainCtx.drawImage(float, left.value, top.value, 200, 80); // 将画板内容转换为 base64数据 let base = main.toDataURL(); show.value = false; } // 清除签名 function backInit() { mainCtx.clearRect(0, 0, data.size.width, data.size.height) // 绘制合同图片为背景 const img = new Image(); img.src = data.baseUrl; img.onload = function () { mainCtx.drawImage(img, 0, 0, data.size.width, data.size.height); } show.value = false; left.value = 0; top.value = 0 } /* 签名版和其相关变量 */ let canSign = false; onMounted(() => { // 获取签名板并且初始化为canvas画布 sign = document.getElementById('sign'); signCtx = sign.getContext('2d'); }) // 监听鼠标按下事件 function signMousedown(e) { canSign = true; // 重新绘制 signCtx.beginPath() signCtx.moveTo(e.offsetX, e.offsetY); // 设置线条样式 signCtx.lineWidth = 5; signCtx.strokeStyle = "red"; } // 监听鼠标移动事件 function signMousemove(e) { if (canSign) { signCtx.lineTo(e.offsetX, e.offsetY); signCtx.stroke() } } // 监听鼠标松开事件 function signMouseup() { canSign = false } // 清除画板 function clearSign() { signCtx.clearRect(0, 0, sign.width, sign.height) } // 确认签名 function sendSignToFloat() { floatCtx.drawImage(sign, 0, 0, 200, 80); show.value = true } /* 签名悬浮板相关逻辑 */ onMounted(() => { // 获取悬浮板并且初始化为canvas画布 float = document.getElementById('float'); floatCtx = float.getContext('2d'); }) /* 拖拽相关代码 */ // 鼠标按下点和推拽元素的距离 let distanceX = 0; let distanceY = 0; let mainboard = ref() let floatboard = ref() function floatMouseDown(e) { /* pageX 是鼠标点距离屏幕X轴的距离 offsetLeft 是自身元素左边距和上一个定位元素的距离 */ distanceX = e.pageX - mainboard.value.offsetLeft - floatboard.value.offsetLeft; distanceY = e.pageY - mainboard.value.offsetTop - floatboard.value.offsetTop; function move(e) { left.value = e.pageX - mainboard.value.offsetLeft - distanceX; top.value = e.pageY - mainboard.value.offsetTop - distanceY } document.addEventListener('mousemove', move, false) document.addEventListener('mouseup', () => { // 移除监听事件 document.removeEventListener('mousemove', move) }, false) } </script> <style scoped> .container { display: flex; position: relative; } .mianboard { border: 1px solid; margin-right: 20px; } .floatboard { position: absolute; border: 1px solid } .sab{ margin-top: 10px; } .signboard { display: flex; flex-direction: column; height: 400px; border: 2px dashed #8e9bf1; } .signboard div { margin-top: 10px; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。