针对上一篇canvas画板的优化和封装
为了方便以后的使用我将canvas画板封装成了一个对象,使用的时候只需引入之后new成对象即可使用。并有清空画板、改变画笔颜色、粗细、历史上一笔、下一笔等功能
html
<template> <div class="canvas"> <div class="btnBox"> <div class="item"> <el-button @click="drawCanvas.resetCanvas()">清空canvas</el-button> </div> <div class="item"> <el-color-picker @change="drawCanvas.setColor(color)" v-model="color" /> </div> <div class="item"> <el-slider v-model="size" :max="15" :min="1" input-size="mini" @change="drawCanvas.setPenSize(size)" @input="drawCanvas.setPenSize(size)" show-input /> <div class="size" :style="{ width: size * 2 + 'px', height: size * 2 + 'px', background: color }"></div> </div> <div class="item"> <el-button @click="drawCanvas.init(list)">初始化</el-button> </div> <div class="item"> <el-button @click="front">前一笔</el-button> </div> <div class="item"> <el-button @click="after">后一笔</el-button> </div> </div> <canvas width="500" height="300" id="canvas" ref="canvas"></canvas> </div> </template> <script> import Draw from "../util/drawClass"; export default { name: "canvas", components: {}, data() { return { drawCanvas: null, color: "#409EFF", size: 2 }; }, mounted() { this.drawCanvas = new Draw("canvas", [], '#999999', this.color, this.size); //不能直接在data赋值响因为刚完成响应式转换还没有dom元素 }, computed: { list() { return this.$store.state.canvasList; } }, watch: { list(value) { console.log(value); } }, methods: { front() { const res = this.drawCanvas.front(); if (res.code === 404) this.$message.warning(res.msg); }, after() { const res = this.drawCanvas.after(); if (res.code === 404) this.$message.warning(res.msg); } } }; </script> <style> .btnBox { margin: 0 auto 20px auto; width: 300px; padding: 10px; box-sizing: border-box; .item{ width: 100%; display: flex; justify-content: center; align-items: center; .el-button{ width: 100% } .size{ margin: 0 10px; border-radius: 50%; } .el-slider{ flex: 1; .el-slider__runway.show-input{ margin-right: 110px; } .el-slider__input{ width: 95px } } } } </style>
封装的对象
import store from '../vuex_study_module/store' /** * canvas画板 * 兼容移动端touch事件 * ----------传入的参数----------- * @tag canvas的id * @historyList 历史纪录的点 * @background 背景色 * @color 画笔颜色 * @size 画笔大小 * ----------提供的方法----------- * @resetCanvas 清空canvas的方法 * @init 还原所有画笔的画布 options {[{size: String,color: Number,list: [[12,13],[14,15]]}]} * @after 后一步画布 * @front 前一步画布 * @getPointList 获取画笔记录 * @setColor 设置颜色 options String * @setPenSize 设置画笔的大小 options Number */ export default class Draw { constructor(tag, historyList, background, color, size) { this.canvas = document.getElementById(tag) this.ctx = this.canvas.getContext("2d") this.width = this.canvas.offsetWidth this.height = this.canvas.offsetHeight this.canvas.width = this.width this.canvas.height = this.height this.canvasOffsetTop = this.canvas.offsetTop//移动端canvas距离顶部的距离 this.canvasOffsetLeft = this.canvas.offsetLeft//移动端canvas距离左边的距离 this.startPosition = []//当前的点 this.isdraw = false//是否在作画 this.history = historyList ? historyList : []//所有的历史画笔集合 this.isInit = false//是否为初始化 this.currentPen = []//当前画笔 this.drawStep = 0//当前第几笔画 this.penSize = size//画笔大小 this.penColor = color//画笔颜色 this.backGround = background ? background : '#999999'//画布背景色 this.ctx.fillStyle = this.backGround this.ctx.lineWidth = size * 2 + 1//线的宽度 this.ctx.strokeStyle = color//点的颜色 this.ctx.fillRect(0, 0, this.width, this.height)//画布大小 this.canvas.addEventListener('touchmove', function (e) { //禁止页面滚动 e.preventDefault(); }, {passive: false}); //passive 参数不能省略,用来兼容ios和android this.canvas.removeEventListener('touchend', function (e) { //解除页面滚动 e.preventDefault(); }, {passive: false}); this.canvas.onmousedown = res => { //指针在canvas上点击 this.isdraw = true; this.startPosition[0] = res.offsetX; this.startPosition[1] = res.offsetY; this.drawLine(this.startPosition[0], this.startPosition[1]); } this.canvas.onmouseup = res => { //指针在canvas上放开 if (!this.isdraw) return; this.clear(); } this.canvas.onmouseout = res => { //指针移出canvas if (!this.isdraw) return; this.clear(); } this.canvas.onmousemove = res => { //指针在canvas移动 if (!this.isdraw) return; this.drawLine(res.offsetX, res.offsetY); } this.canvas.ontouchstart = res => { // 手指触摸开始 this.isdraw = true; this.startPosition[0] = res.changedTouches[0].pageX - this.canvasOffsetLeft; this.startPosition[1] = res.changedTouches[0].pageY - this.canvasOffsetTop; this.drawLine(this.startPosition[0], this.startPosition[1]); } this.canvas.ontouchmove = res => { //手指触摸移动 if (!this.isdraw) return; this.drawLine(res.changedTouches[0].pageX - this.canvasOffsetLeft, res.changedTouches[0].pageY - this.canvasOffsetTop); } this.canvas.ontouchend = res => { // 手指触摸结束 if (!this.isdraw) return; this.clear(); } } drawLine(X, Y) { //画图 if (!this.isdraw) return; this.ctx.beginPath();//画圆 this.ctx.arc(X, Y, this.penSize, 0, 2 * Math.PI) this.ctx.closePath(); this.ctx.fillStyle = this.penColor; this.ctx.fill(); this.ctx.beginPath()//画线 this.ctx.moveTo(this.startPosition[0], this.startPosition[1] + 0.5); this.ctx.lineTo(X, Y + 0.5); this.ctx.stroke(); this.ctx.save(); this.startPosition = [X, Y]; if (!this.isInit) this.currentPen.push(this.startPosition) } clear() { // 停止画笔 this.isdraw = false; this.startPosition = []; this.history.push({size: this.penSize,color: this.penColor,list: this.currentPen}); this.currentPen = []; this.drawStep = this.history.length - 1 store.commit('setPenList', this.history) } historyDrawPen(penList = []) { // 画历史画笔 this.history = penList this.isdraw = true this.isInit = true this.resetCanvas() for(let i = 0;i < penList.length;i++) { if (this.drawStep < i) break; if (penList[i].list.length == 0) { this.resetCanvas() } else { this.setColor(penList[i].color) this.setPenSize(penList[i].size) this.startPosition = [];//避免画笔的最后一点会和下一个画笔的前一点链接起来 for(let j = 0;j < penList[i].list.length;j++) { this.drawLine(penList[i].list[j][0], penList[i].list[j][1]) } } } this.isdraw = false this.isInit = false this.startPosition = [] } getHistoryPoint() { // 返回画笔记录 return this.history } setColor(color) { // 设置画笔的颜色 this.ctx.strokeStyle = color this.penColor = color } setPenSize(size) { // 设置画笔的粗细 this.penSize = size this.ctx.lineWidth = size * 2 + 1 } resetCanvas() { //清空canvas this.currentPen = []; this.ctx.fillStyle = this.backGround; this.ctx.fillRect(0, 0, this.width, this.height) if (this.isInit) return this.history.push({size: this.penSize,color: this.penColor,list: []}); this.drawStep = this.history.length - 1 store.commit('setPenList',this.history) } init(penList) { // 初始化画布 this.drawStep = penList ? penList.length - 1 : 0 this.historyDrawPen(penList) } after() { // 下一笔 if (this.drawStep >= this.history.length - 1) return {code: 404, msg: '没有下一个笔画了'} this.drawStep = this.drawStep + 1 this.historyDrawPen(this.history) return {code: 200, msg: '恢复下一笔'} } front() { // 上一笔 if (this.drawStep < 0) return {code: 404, msg: '没有前一个笔画了'} this.drawStep = this.drawStep - 1 this.historyDrawPen(this.history) return {code: 200, msg: '恢复前一笔'} } }
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦