<template><div class="signature"><!-- 签名 --><div class="canvas"><canvasid="myCanvas"ref="canvas"width="600"height="600"@touchstart="touchStart"@touchmove="touchMove"@touchend="touchEnd"@mousedown="mouseDown"@mousemove="mouseMove"@mouseup="mouseUp">您的浏览器不支持 HTML5 canvas 标签。</canvas></div><divclass="save-btn"@click.stop.prevent="commit">提交签名</div><divclass="back-btn"@click.stop.prevent="routeGo"><i class="icon"></i><span class="label">返回</span></div><divclass="clear-btn"@click.stop.prevent="clear"><i class="icon"></i><span class="label">清空</span></div></div>
</template><script>
export default {data () {return {// canvasWidth: window.innerWidth,// canvasHeight: window.innerHeight,canvasImg: '', // 签名图片地址ctx: null,stage_info: [], // 移动端按下点到屏幕的偏差isDown: false,points: [],startX: 0, // 起始点x坐标startY: 0 // 起始点y坐标}},mounted () {this.init()},methods: {// 初始化画板init () {const canvas = this.$refs.canvasthis.ctx = canvas.getContext('2d')this.ctx.strokeStyle = '#000'this.stage_info = canvas.getBoundingClientRect()},// pcmouseDown (ev) {const e = ev || evente.preventDefault()this.isDown = trueconst obj = {x: e.offsetX,y: e.offsetY}this.startX = obj.xthis.startY = obj.ythis.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.points.push(obj)},mouseMove (ev) {const e = ev || evente.preventDefault()if (this.isDown) {const obj = {x: e.offsetX,y: e.offsetY}this.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.startY = obj.ythis.startX = obj.xthis.points.push(obj)}},mouseUp (ev) {const e = ev || evente.preventDefault()const obj = {x: ev.offsetX,y: ev.offsetY}this.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.points.push(obj)this.points.push({x: -1,y: -1})this.isDown = false},// mobiletouchStart (ev) {const e = ev || evente.preventDefault()if (e.touches.length === 1) {const obj = {x: e.targetTouches[0].clientX - this.stage_info.left,y: e.targetTouches[0].clientY - this.stage_info.top}this.startX = obj.xthis.startY = obj.ythis.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.points.push(obj)}},touchMove (ev) {const e = ev || evente.preventDefault()if (e.touches.length === 1) {const obj = {x: e.targetTouches[0].clientX - this.stage_info.left,y: e.targetTouches[0].clientY - this.stage_info.top}this.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.startX = obj.xthis.startY = obj.ythis.points.push(obj)}},touchEnd (ev) {const e = ev || evente.preventDefault()if (e.touches.length === 1) {const obj = {x: e.targetTouches[0].clientX - this.stage_info.left,y: e.targetTouches[0].clientY - this.stage_info.top}this.startX = obj.xthis.startY = obj.ythis.ctx.beginPath()this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(obj.x, obj.y)this.ctx.stroke()this.ctx.closePath()this.points.push(obj)}},// 返回routeGo () {this.$router.go(-1)},clear () {this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)this.points = []},commit () {this.canvasImg = this.$refs.canvas.toDataURL()console.log(this.canvasImg)}}
}
</script><style lang="less">.signature {/*min-height: 100vh;*/background: #fff;position: relative;.canvas {font-size: 0;}.save-btn {position: absolute;bottom: 0;left: 50%;z-index: 9;margin-top: -20px;/*transform: rotate(90deg);*/transform-origin: center center;font-size: 18px;color: #fcfcfc;line-height: 25px;padding: 8px 43px;background: linear-gradient(90deg,rgba(57, 115, 230, 1) 0%,rgba(57, 115, 230, 1) 100%);border-radius: 2px;}.back-btn {position: absolute;top: 20px;left: 50px;z-index: 9;transform-origin: left top;display: flex;flex-direction: column;.icon {display: inline-block;width: 42px;height: 42px;/*background: url("../../assets/images/signature_back.png") no-repeat center*//*center;*/background-size: contain;}.label {font-size: 16px;color: #d8d8d8;text-align: center;}}.clear-btn {position: absolute;top: 20px;right: 50px;z-index: 9;transform-origin: left top;display: flex;flex-direction: column;.icon {display: inline-block;width: 42px;height: 42px;/*background: url("../../assets/images/signature_clear.png") no-repeat*//*center center;*/background-size: contain;}.label {font-size: 16px;color: #d8d8d8;text-align: center;}}}
</style>

canvas实现手写板(vue)相关推荐

  1. 移动端html5手写板,Vue+canvas实现移动端手写板步骤详解

    这次给大家带来Vue+canvas实现移动端手写板步骤详解,Vue+canvas实现移动端手写板的注意事项有哪些,下面就是实战案例,一起来看一下. 清除 保存 Canvas画板 var draw; v ...

  2. 移动端html5手写板,Vue利用canvas实现移动端手写板的方法

    清除 保存 Canvas画板 var draw; var preHandler = function(e){e.preventDefault();} class Draw { constructor( ...

  3. android canvas 手写,自定义view—Canvas实现手写板和涂鸦功能

    学习导航 第一节:http://blog..net/bobo8945510/article/details/53197727 -自定义View-自定义属性及引用 第二节:http://blog..ne ...

  4. 前端利用canvas实现手写板

    <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" ...

  5. 用canvas实现一个vue弹幕组件

    看B站时,对弹幕的实现产生了兴趣,一开始想到用css3动画去实现,后来感觉这样性能不是很好,查了下资料,发现可以用canvas实现,于是就摸索着写了一个简单的弹幕. 弹幕功能 支持动态添加弹幕 弹幕不 ...

  6. VUE项目开发,使用canvas实现图片签名编辑手写板功能

    vue项目使用canvas实现手写板功能 完整的效果图如下: 直接上代码,下面代码可以当做组件直接引用,根据自己的需求传对应的图片即可,操作图标需要自己替换,保存功能也需要自己实现. CanvasDi ...

  7. vue canvas动效组件插件库制作

    vue-canvas-effect canvas动画合集Vue组件 ? online demo | ? English document 内容 [浏览器兼容] [安装] [使用] [ES6] [按需加 ...

  8. 2018.7月Vue优质开源项目清单

    2018.7月Vue优质开源项目清单 SmallRuralDog/electron-vue-music stars:325 forks:51 项目描述:基于 electron-vue 开发的音乐播放器 ...

  9. vue为什么要求组件模板只能有一个根元素

    查看全文 http://www.taodudu.cc/news/show-805357.html 相关文章: 微信小程序一定要用https的理由,小程序使用HTTPS链接分析 微信小程序登录 getU ...

最新文章

  1. python语言程序设计2019版第二章课后答案-python语言程序设计基础课后答案第二章...
  2. php zval_copy_static_var(),zval _ 引用计数 _ 变量分离 _ 写时拷贝
  3. CentOS7 SSH相关
  4. 小程序开发(11)-之支付封装
  5. 微软官方解读 Win11 操作系统
  6. oracle重建索引对空间的使用,分析oracle索引空间使用情况,以及索引是否需要重建...
  7. Ubuntu16.04安装VSCode
  8. 我的世界服务器物品图标闪,我的世界用资源包修改闪烁标的方法分享
  9. 1000瓶药水,其中1瓶有毒,最少要几只老鼠?
  10. Codeigniter 升级
  11. 一次装系统惨痛的翻车经历
  12. linux swap不可用,linux 禁用 swap
  13. 微信小程序 如何实现列表
  14. Mysteel解读:2022年1-10月份马铃薯淀粉进口数据分析
  15. LeetCode 21-30 题
  16. 大数据-Hadoop-云服务器的搭建
  17. 才发现网易相册已于2019年5月8号停止运营,如何导出相册照片:http://photo.163.com/transfer/html/login , 使用相册帐号登录,提供真实姓名、手机号码
  18. MES管理系统质量管理模块,在造纸行业中的应用
  19. 厚积薄发打卡Day75 :【MSUP】Java语言特性与设计模式(上)
  20. Revit:Revit无法正常运行外部程序“tangentUIApp”解决办法

热门文章

  1. abap发送邮件函数
  2. cefsharp加入flash插件
  3. Linux/Deepin全流程安装指南:双显卡-Prime-docker-Nvidia_docker-ROS-日常应用
  4. PC_指令流水线/时空图
  5. 20多岁女人14件事决定一生
  6. 软件本地化/国际化解决方案 - 多语种代码生成工具
  7. php 单例模式的类,PHP设计模式之单例模式
  8. mysql 入门命令
  9. Spring源码深度解析(郝佳)-学习-源码解析-factory-method
  10. 如何手动启动消防广播_奥瑞那消防主机手册 如何手动启动消防广播