历时一周开发了一个简单的canvas实现的画板功能,这是在vue+elementui项目里开发的,支持画笔、橡皮擦、回退、清除、保存图片、切换颜色、设置宽度等。先看最终效果:

1.我们先创建一个canvas元素

<div class="canvas"><canvas ref="canvas" id="canvas"></canvas>
</div>

2.初始化画布

initCanvas() {let that = this;// 获取canvas元素this.canvas = this.$refs.canvas;// 指定了画布上绘制的类型为2dthis.ctx = this.canvas.getContext('2d');// 获取画布相对于视窗的位置集合let rect = this.canvas.getBoundingClientRect();let initX = rect.x;let initY = rect.y;this.pageWidth = document.documentElement.clientWidth - rect.x - 50;this.pageHeight = document.documentElement.clientHeight - rect.y - 50;this.canvas.width = this.pageWidth;this.canvas.height = this.pageHeight;
}

3.画笔功能
我们给一个画笔button,点击时isPainting为true,active表示正在使用的按钮index

<el-button :type=buttonType(0)icon="iconfont icon-pen" round@click="painting">
</el-button>
painting() {this.isPainting = true;this.active = 0;
},
buttonType(param) {if (param === this.active) {return "primary"}
}

我们需要监听鼠标onmousedownonmousemoveonmouseup事件
onmousedown时,paint属性为true,记录鼠标按下的坐标为lastPoint,moveTo移动到目标坐标,lineTo将两个坐标之间连起来
onmousemove时,设置paint属性为false,表示一次绘画结束

// 鼠标按下事件this.canvas.onmousedown = function (e) {that.paint = this.isPainting;// e是浏览器坐标系上的点,必须减去canvas的原点坐标,才是准确的画布上的坐标let x = e.clientX - initX;let y = e.clientY - initY;that.lastPoint = {x: x, y: y};};// 鼠标移动事件this.canvas.onmousemove = function (e) {if (that.paint) {let x = e.clientX - initX;let y = e.clientY - initY;that.newPoint = {x: x, y: y};that.drawLine();that.lastPoint = that.newPoint;}};// 鼠标松开事件this.canvas.onmouseup = function () {that.paint = false;};drawLine() {this.ctx.lineWidth = 1;this.ctx.lineCap = "round";this.ctx.lineJoin = "round";this.ctx.moveTo(this.lastPoint.x, this.lastPoint.y);this.ctx.lineTo(this.newPoint.x, this.newPoint.y);this.ctx.stroke();
},

4.橡皮擦功能
加入eraser按钮

<el-button :type="buttonType(1)"icon="iconfont icon-eraser"@click="eraser">
</el-button>

点击eraser时,isPainting为false,clear属性为true,clearRect清除区域

this.canvas.onmousedown = function (e) {that.paint = that.isPainting;that.clear = !that.isPainting;let x = e.clientX - initX;let y = e.clientY - initY;that.lastPoint = {x: x, y: y};
};
this.canvas.onmousemove = function (e) {if (that.clear) {let x = e.clientX - initX;let y = e.clientY - initY;that.ctx.save();that.ctx.clearRect(x, y, 10,10);that.ctx.restore();}
};

5.撤回
撤回功能的思路是通过getImageData()复制画布上指定矩形的像素数据,将每次操作的像素保存在history数组中。当点击撤回按钮时,通过putImageData()将数组末尾的像素数据放回画布

this.canvas.onmouseup = function () {let image = that.ctx.getImageData(0, 0, that.pageWidth, that.pageHeight);that.history.push(image);
};
lastStep() {this.history.pop();this.ctx.putImageData(this.history[this.history.length - 1], 0, 0);this.active = 2;
},

6.清空画布
context.clearRect(x,y,width,height);

参数 描述
x 要清除的矩形左上角的 x 坐标
y 要清除的矩形左上角的 y 坐标
width 要清除的矩形的宽度,以像素计
height 要清除的矩形的高度,以像素计
clearAll() {this.paint = this.clear = this.isPainting = false;this.ctx.clearRect(0, 0, this.pageWidth, this.pageHeight);this.history.length = 1;this.active = 3;
}

7.设置线条宽度
我们加入lineWidth属性,初始值为1,加入一个slider组件双向绑定lineWidth,你也可以用其他更改数值的组件

<el-slider v-model="lineWidth":min="1":max="50">
</el-slider>

画线时,只需要设置画布内容的lineWidth即可
this.ctx.lineWidth = this.lineWidth;
使用橡皮擦时,设置清空矩形的宽高为lineWidth
that.ctx.clearRect(x, y, that.lineWidth, that.lineWidth);
8.切换画笔颜色
初始化一个颜色数组colorArr,给定color和style,click颜色时设置画布内容的strokeStyle
colorSize方法设置按钮的大小

<el-button v-for="(item, index) in colorArr":size="colorSize(index)":style="item.style" circle@click="checkColor(index)">
</el-button>
checkColor(param) {this.ctx.strokeStyle = this.colorArr[param].color;this.colorActive = param;
},
colorSize(param) {if (param === this.colorActive) {return "default"} else {return "medium"}
},

直接修改strokeStyle,虽然画笔的颜色改了,但之前的线条颜色也一起发生了变化,所以我们需要在每次绘制时闭合路径

this.canvas.onmousedown = function (e) {that.ctx.beginPath();
};
this.canvas.onmouseup = function () {that.ctx.closePath();
};

9.保存画布
toDataURL()方法把画布里的图案转变成base64编码格式的png,然后返回 Data URL数据。
创建一个a标签,设置a的href、download和target

<el-button :type="buttonType(4)"icon="iconfont icon-save"round @click="save">
</el-button>
save() {this.active = 4;this.paint = this.clear = this.isPainting = false;let imgUrl = this.canvas.toDataURL("image/png");let saveImg = document.createElement("a");document.body.appendChild(saveImg);saveImg.href = imgUrl;saveImg.download = "canvas" + (new Date).getTime();saveImg.target = "_blank";saveImg.click();
},

基本功能已经全部实现啦,后续可以优化样式、添加更多画笔效果,加入拖拽功能、画矩形圆形等功能~

canvas实现绘画板相关推荐

  1. canvas 实现绘画板

    canvas 实现绘画板 起始:使用HTML5的canvas特性,在Vue+element项目中,结合JS实现你画我猜小游戏绘画板,也可以满足订单在确认时候签名的需求.保存了鼠标的轨迹,还有绘画圆形. ...

  2. 手把手教你实现一个canvas智绘画板

    手把手教你实现一个canvas智绘画板 下载地址 前言 本文主要介绍: 项目介绍 项目效果展示 一步步实现项目效果 踩坑 一.项目介绍 名称: 智绘画板 技术栈: HTML5,CSS3,JavaScr ...

  3. 基于HTML5 画布功能canvas的绘画板:画线、画圆、画矩形、橡皮、改变线条

    写在前面 试看链接: https://yyywwwqqq.coding.me/draw 项目下载地址:https://coding.net/u/yyywwwqqq/p/draw 希望您能点个fork ...

  4. tkinter Canvas 实现 鼠标手绘画板 功能

    下面代码简单实现了手绘画板功能,其实也是Canvas的教程,后面都给加了注释. 这里通过列表来存储笔画,实现撤销恢复功能,右键有菜单. import tkinter as tk from tkinte ...

  5. 利用Python GUI写一个简单的绘画板

    先说废话,再上代码 这个绘画板主要运用了Python自带的标准GUI库Tkinter,包含了画笔颜色选择,背景布颜色选择,橡皮擦,清屏,保存图片等功能. from tkinter import * f ...

  6. android 绘画开源,Android 开源可缩放平移的绘画板

    ScaleSketchPadDemo 此项目包含两个模块 app1 为普通绘画板 app2 为可所发的绘画板 方便各位Android 开发者理解和使用 用法: clone or download 项目 ...

  7. 用BufferedImage和Graphics实现简单鼠标手绘画板(Java)

    实现效果: 1.用鼠标在画板上拖拽实现画线条: 2.右击鼠标点击指定的颜色可切换画笔颜色,再次拖拽实现画线条: 代码实现: import javax.swing.*; import java.awt. ...

  8. Android实现的写字板(绘画板)

    Android实现的写字板(绘画板) 前言: 通过Android实现绘画板的功能,能够在应用中进行绘画(写字)操作,完成绘画(写字)后,可以将我们自己绘制的图画(字体)进行保存,同时也能清空画板上的内 ...

  9. OpenGL ES之深入解析如何实现“手写绘画板”

    一.设置绘画板 ① 设置画板视图 设置绘画板位置.大小.背景 CGFloat ratio = self.view.frame.size.height / self.view.frame.size.wi ...

最新文章

  1. android textview 设置字体,Android TextView设置字体风格
  2. java无向图代码实例_Java 图示例 · JavaTutorialNetwork 中文系列教程 · 看云
  3. maven初学者(一)
  4. Eclipse中各种文件【默认编码格式设置】,防止乱码等问题
  5. JZOJ 5167. 【NOIP2017模拟6.26】下蛋爷
  6. 二十七、深入==与equals的区别(下篇)
  7. python将一个列表里面的某类元素取出来_03|Python列表常见操作
  8. java中如何实现变量可配置_Java基础-如何配置环境变量
  9. 理解Spring框架中Bean的作用域
  10. 让NUnit轻松支持.NET 2.0
  11. 关于ElasticSearch整合SpringBoot
  12. Vue全局API总结
  13. ITU-T G.1080 IPTV的体验质量(QoE)要求 (Quality of experience requirements for IPTV services)
  14. 计算机主机技术标准规范,B级机房技术规范要求
  15. VUE 动态三级路由界面不显示
  16. 远方测试软件,远方测试仪操作指导书
  17. 品搜妞——百度、谷狗、搜狗的女人三围
  18. 微信小程序——打开地图 选择位置 完整功能实现代码(定位,检索周边,可移动选点,可搜索,腾讯地图API)
  19. 天宇优配|钠电池汽车要来了,续航达500公里!持续高成长股揭秘
  20. Linux下使用uinput创建虚拟设备(Ubuntu20.04.2)

热门文章

  1. Codeforces 584 A.Olesya and Rodion
  2. linux重启docker镜像没了,解决docker run 或者 docker restart 启动镜像就自动退出
  3. HDU1713 相遇周期(数学)
  4. KVM 虚拟机 配置 NAT 连接方式上网
  5. 云海麒麟计算机系统有限公司,北京云海麒麟容错服务器厂商
  6. 笔记本更换网络连接,MAC地址改变!
  7. 联想企业网盘,为什么让500强企业情有独钟?
  8. 被VMP蹂躏了。。。
  9. 菜鸟网html dom对象,JavaScript学习指南
  10. 【MM小贴士】SAP工序外协初探