当前位置:   article > 正文

VUE实现电子签名_vue电子签名

vue电子签名

 啥也不说了直接上代码

  1. <template>
  2. <div>
  3. <div class="block-panel">
  4. <canvas ref="canvas" class="canvas" @mousedown="beginningDraw"
  5. @mouseup="endingDraw"@mouseleave="drawLeave" @mousemove="drawing"
  6. v-show="!isSaved"></canvas>
  7. <div class="picture" v-show="isSaved">
  8. <img :src="picture" alt="签名异常">
  9. </div>
  10. <div class="btns-box">
  11. <div style="text-align: center">
  12. <el-button type="plain" @click="canvasUndo">撤销</el-button>
  13. <el-button type="plain" @click="canvasRedo">反撤销</el-button>
  14. </div>
  15. <div style="text-align: center">
  16. <el-button type="primary" @click="canvasClear">清空</el-button>
  17. <el-button type="primary" @click="signAgain">重新签</el-button>
  18. <el-button type="primary" @click="saveAsImg">保存</el-button>
  19. </div>
  20. </div>
  21. </div>
  22. </div>
  23. </template>
  1. import axios from "axios"
  2. export default {
  3. data(){
  4. return{
  5. // 图片路径
  6. picture: '',
  7. // 画布
  8. emptyCanvas: '',
  9. // 画布操作记录
  10. step: -1,
  11. canvas: '',
  12. // 画布操作历史
  13. canvasHistory: [],
  14. // 画布参数
  15. obj: {},
  16. // 是否已保存生成图片
  17. isSaved: false
  18. }
  19. },
  20. mounted(){
  21. this.init()
  22. this.canvasInit()
  23. },
  24. methods: {
  25. /**
  26. * 初始化画布数据
  27. */
  28. init(){
  29. this.canvas = this.$refs.canvas
  30. this.obj = {
  31. canvas: this.canvas,
  32. context: this.canvas.getContext("2d"),
  33. isWrite: false, //是否开始
  34. lastWriteTime: -1,
  35. lastWriteSpeed: 0,
  36. lastWriteWidth: 0,
  37. canvasWidth: 800, // canvas宽
  38. canvasHeight: 400, // canvase高
  39. bgColor: '#fff', // 背景色
  40. borderWidth: 2, // 网格线宽度
  41. borderColor: "#fff", //网格颜色
  42. lastPoint: {}, //
  43. writeWidth: 2, //基础轨迹宽度
  44. maxWriteWidth: 30, // 写字模式最大线宽
  45. minWriteWidth: 1, // 写字模式最小线宽
  46. writeColor: '#000', // 轨迹颜色
  47. isWriteName: true // 签名模式
  48. }
  49. },
  50. /**
  51. * 设置画布线条宽度
  52. */
  53. setLineWidth(){
  54. let nowTime = new Date().getTime();
  55. let diffTime = nowTime - this.obj.lastWriteTime;
  56. this.obj.lastWriteTime = nowTime;
  57. let returnNum = this.obj.minWriteWidth + (this.obj.maxWriteWidth - this.obj.minWriteWidth) * diffTime / 30;
  58. if(returnNum < this.obj.minWriteWidth) {
  59. returnNum = this.obj.minWriteWidth;
  60. } else if(returnNum > this.obj.maxWriteWidth) {
  61. returnNum = this.obj.maxWriteWidth;
  62. }
  63. returnNum = returnNum.toFixed(2);
  64. //写字模式和签名模式
  65. if(this.obj.isWriteName){
  66. this.obj.context.lineWidth = this.obj.writeWidth;
  67. }else{
  68. this.obj.context.lineWidth = this.obj.lastWriteWidth = this.obj.lastWriteWidth / 4 * 3 + returnNum / 4;
  69. }
  70. },
  71. /**
  72. * 画布中书写
  73. */
  74. writing(point){
  75. this.obj.context.beginPath();
  76. this.obj.context.moveTo(this.obj.lastPoint.x, this.obj.lastPoint.y);
  77. this.obj.context.lineTo(point.x, point.y);
  78. this.setLineWidth();
  79. this.obj.context.stroke();
  80. this.obj.lastPoint = point;
  81. this.obj.context.closePath();
  82. },
  83. /**
  84. * 书写样式
  85. */
  86. writeContextStyle() {
  87. this.obj.context.beginPath();
  88. this.obj.context.strokeStyle = this.obj.writeColor;
  89. this.obj.context.lineCap = 'round';
  90. this.obj.context.lineJoin = "round";
  91. },
  92. /**
  93. * 开始书写
  94. */
  95. writeBegin(point) {
  96. this.obj.isWrite = true;
  97. this.obj.lastWriteTime = new Date().getTime();
  98. this.obj.lastPoint = point;
  99. this.writeContextStyle();
  100. },
  101. /**
  102. * 结束书写
  103. */
  104. writeEnd(type = 0) {
  105. //新增记录
  106. if (type == 1) {
  107. this.step++;
  108. if (this.step < this.canvasHistory.length) {
  109. this.canvasHistory.length = this.step; // 截断数组
  110. }
  111. this.canvasHistory.push(this.canvas.toDataURL("image/png")); // 添加新的绘制到历史记录
  112. console.log(this.step);
  113. }
  114. //end
  115. this.obj.isWrite = false;
  116. },
  117. /**
  118. * 清空画板
  119. */
  120. canvasClear() {
  121. this.obj.context.strokeStyle = '#fff';
  122. this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
  123. this.step = -1
  124. this.canvasHistory = []
  125. if(!this.obj.isWriteName) {
  126. this.obj.context.beginPath();
  127. var size = this.obj.borderWidth / 2;
  128. //画外面的框
  129. this.obj.context.moveTo(size, size);
  130. this.obj.context.lineTo(this.obj.canvasWidth - size, size);
  131. this.obj.context.lineTo(this.obj.canvasWidth - size, this.obj.canvasHeight - size);
  132. this.obj.context.lineTo(size, this.obj.canvasHeight - size);
  133. this.obj.context.closePath();
  134. this.obj.context.lineWidth = this.obj.borderWidth;
  135. this.obj.context.strokeStyle = this.obj.borderColor;
  136. this.obj.context.stroke();
  137. //画里面的框
  138. this.obj.context.moveTo(0, 0);
  139. this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight);
  140. this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight / 2);
  141. this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight / 2);
  142. this.obj.context.lineTo(0, this.obj.canvasHeight / 2);
  143. this.obj.context.lineTo(0, this.obj.canvasHeight);
  144. this.obj.context.lineTo(this.obj.canvasWidth, 0);
  145. this.obj.context.lineTo(this.obj.canvasWidth / 2, 0);
  146. this.obj.context.lineTo(this.obj.canvasWidth / 2, this.obj.canvasHeight);
  147. this.obj.context.stroke();
  148. }
  149. },
  150. /**
  151. * 保存图片 格式base64
  152. */
  153. saveAsImg() {
  154. // 将cavase生成base64文件
  155. let imageSrc = this.canvas.toDataURL("image/png");
  156. if(imageSrc == this.emptyCanvas) {
  157. alert('请先书写')
  158. } else {
  159. this.isSaved = true
  160. // console.log('提交的内容===>', imageSrc)
  161. // 将base64转成file格式
  162. let blob = this.dataURLtoBlob(imageSrc);
  163. let file = this.blobToFile(blob, "imgName");
  164. // 将blob图片转化路径图片
  165. this.picture = window.URL.createObjectURL(file)
  166. console.log('this.picture', this.picture)
  167. let formData = new FormData()
  168. formData.append('file', this.picture)
  169. axios({
  170. method: 'post',
  171. url: '/user/12345',
  172. data: formData
  173. })
  174. }
  175. },
  176. /**
  177. * 初始化画布并备份
  178. */
  179. canvasInit() {
  180. this.canvas.width = this.obj.canvasWidth;
  181. this.canvas.height = this.obj.canvasHeight;
  182. this.emptyCanvas = this.canvas.toDataURL("image/png");
  183. },
  184. /**
  185. * 撤销
  186. */
  187. canvasUndo() {
  188. console.log(this.step)
  189. if (this.step >= 0) {
  190. this.step--;
  191. this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
  192. if (this.step < 0) {
  193. return false
  194. }
  195. let canvasPic = new Image();
  196. canvasPic.src = this.canvasHistory[this.step];
  197. canvasPic.addEventListener('load', () => {
  198. this.obj.context.drawImage(canvasPic, 0, 0);
  199. });
  200. } else {
  201. console.log('不能再继续撤销了');
  202. }
  203. },
  204. /**
  205. * 反撤销
  206. */
  207. canvasRedo() {
  208. if (this.step < this.canvasHistory.length - 1) {
  209. this.step++;
  210. let canvasPic = new Image();
  211. canvasPic.src = this.canvasHistory[this.step];
  212. canvasPic.addEventListener('load', () => {
  213. this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
  214. this.obj.context.drawImage(canvasPic, 0, 0);
  215. });
  216. } else {
  217. console.log('已经是最新的记录了');
  218. }
  219. },
  220. setWidth(){
  221. //宽度铺满
  222. width = document.body.clientWidth;
  223. console.log(width);
  224. this.obj.canvasWidth =width;
  225. },
  226. beginningDraw(e){
  227. let point = {
  228. x: e.offsetX || e.clientX,
  229. y: e.offsetY || e.clientY
  230. };
  231. this.writeBegin(point);
  232. },
  233. endingDraw(e){
  234. let point = {
  235. x: e.offsetX,
  236. y: e.offsetY
  237. };
  238. this.writeEnd(1);
  239. },
  240. drawLeave(e){
  241. let point = {
  242. x: e.offsetX,
  243. y: e.offsetY
  244. };
  245. this.writeEnd();
  246. },
  247. drawing(e){
  248. if(this.obj.isWrite) {
  249. let point = {
  250. x: e.offsetX,
  251. y: e.offsetY
  252. };
  253. this.writing(point);
  254. }
  255. },
  256. signAgain(){
  257. this.isSaved = false
  258. this.picture = ''
  259. this.canvasClear()
  260. },
  261. dataURLtoBlob(dataurl){
  262. let arr = dataurl.split(','),
  263. mime = arr[0].match(/:(.*?);/)[1],
  264. bstr = atob(arr[1]),
  265. n = bstr.length,
  266. u8arr = new Uint8Array(n);
  267. while(n--) {
  268. u8arr[n] = bstr.charCodeAt(n);
  269. }
  270. return new Blob([u8arr], {
  271. type: mime
  272. });
  273. },
  274. blobToFile(theBlob, fileName) {
  275. theBlob.lastModifiedDate = new Date().toLocaleDateString();
  276. theBlob.name = fileName;
  277. return theBlob;
  278. }
  279. }
  280. }
  1. .block-panel {
  2. display: flex;
  3. align-items: center;
  4. justify-content: space-between;
  5. &>.canvas {
  6. border: 1px solid #303133;
  7. }
  8. &>.picture{
  9. width: 800px;
  10. height: 400px;
  11. }
  12. &>.btns-box {
  13. padding-right: 20px;
  14. &>div{
  15. margin-bottom: 10px;
  16. }
  17. }
  18. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/893591
推荐阅读
相关标签
  

闽ICP备14008679号