canvas实现画板

主要用到知识点:

  • 鼠标事件onmousedown() onmousemove() onmouseup() onmouseleave()
  • 事件委托
  • canvas的一些方法 如:绘制线条moveTo() lineTo() stroke() 撤销功能getImageData() putImageData()

实现的功能

  • 铅笔 橡皮擦 更换颜色 改变线条粗细 清屏 撤销 以及保存功能
  • 直接看效果

html:

   <div class="wraper">
<canvas class="canvas" width="1000" height="500"></canvas>
<ul class="btn-list">
<li><input type="color" class="colorBoard" value="#000000"></li>
<li><input type="button" class="clearBoard" value="清屏"></li>
<li><input type="button" class="pencil" value="铅笔"></li>
<li><input type="button" class="eraser" value="橡皮擦"></li>
<li><input type="button" class="repeal" value="撤销"></li>
<li><input type="button" class="save" value="保存"></li>
<li><input type="range" class="rangeBoard" value="1" min="1" max="30"></li>
</ul>
<span class="icon pencil-class"></span>
</div>

css:

    * {
margin: 0;
padding: 0;
list-style: none;
}
html,
body {
width: 100%;
height: 100%;
background: url('../img/bg_board.jpg') no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.wraper {
width: 1200px;
position: relative;
}
.wraper .canvas {
background: #fff;
border: 1px solid #ccc;
border-radius: 10px;
box-shadow: 10px 10px 12px rgba(0, 0, 0, 0.5);
}
.wraper .icon {
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
display: none;
z-index: 9998;
pointer-events: none;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.wraper .pencil-class {
background-image: url('../img/pencil.png');
}
.wraper .eraser-class {
background-image: url('../img/eraser.png');
}
.wraper .btn-list {
width: 1000px;
text-align: center;
margin-top: 10px;
}
.wraper .btn-list li {
display: inline-block;
margin: 10px;
}
.wraper .btn-list li input {
padding: 10px 15px;
background: yellow;
color: #000;
border-radius: 10px;
font-size: 15px;
cursor: pointer;
border: none;
outline: none;
border: 1px solid transparent;
}
.wraper .btn-list li input.rangeBoard {
vertical-align: middle;
}
.wraper .btn-list li input:hover {
border: 1px solid #ccc;
box-shadow: 0 10px 12px #ccc;
}

js:

    var canvasBoard ={
canvas:$('.canvas'),
ctx: $('.canvas').get()[0].getContext("2d"),
bool:true,
color:'#000000',//颜色
weight:'1',//粗细
arr:[],
init:function(){
this.drawBoard();
this.btnList();
},
drawBoard: function(){
let _this =this;
let ctx = _this.ctx;
let canvas = this.canvas;
canvas.mousedown(function(ev){
ev = ev || window.event;
_this.bool = true;
ctx.beginPath();
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.moveTo(ev.offsetX, ev.offsetY);
$('body').css('cursor','none');
$('.icon').css({
left: ev.offsetX,
top: ev.offsetY - 20,
display:'block'
})
canvas.mousemove(function(ev){
if(_this.bool){
ev = ev || window.event;
ctx.lineTo(ev.offsetX,ev.offsetY);
ctx.stroke();
}
$('.icon').css({
left: ev.offsetX,
top: ev.offsetY - 20,
display: 'block'
})
$('body').css('cursor', 'none');
})
canvas.mouseup(function(){
_this.bool = false;
ctx.closePath();
})
canvas.mouseleave(function () {
_this.bool = false;
ctx.closePath();
$('.icon').css({
display: 'none'
})
$('body').css('cursor', 'auto');
})
let imgData = ctx.getImageData(0, 0, canvas.get()[0].width, canvas.get()[0].height)
_this.arr.push(imgData);
})
},
btnList(){
var _this = this;
let ctx = _this.ctx;
$('.btn-list').on('click',function(ev){
ev = ev || window.event;
let canvasW = _this.canvas.get()[0].width;
let canvasH = _this.canvas.get()[0].height;
switch (ev.target.className){
case 'clearBoard':
ctx.clearRect(0, 0, canvasW, canvasH);
break;
case 'pencil':
_this.color = '#000000';
ctx.strokeStyle = _this.color;
_this.weight = '1';
ctx.lineWidth = _this.weight;
$('.colorBoard').val(_this.color);
$('.rangeBoard').val(_this.weight);
$('.icon').removeClass('eraser-class').addClass('pencil-class');
break;
case 'eraser':
_this.color = '#ffffff';
ctx.strokeStyle = _this.color;
_this.weight = '15';
ctx.lineWidth = _this.weight;
$('.colorBoard').val(_this.color);
$('.rangeBoard').val(_this.weight);
$('.icon').removeClass('pencil-class').addClass('eraser-class');
break;
case 'repeal':
if(_this.arr.length >0){
ctx.putImageData(_this.arr.pop(),0,0);
}
break;
case 'save':
let imgUrl = _this.canvas.get()[0].toDataURL("image/png");
let saveA = document.createElement("a");
document.body.appendChild(saveA);
saveA.href = imgUrl;
saveA.download = "mypic" + (new Date).getTime();
saveA.target = "_blank";
saveA.click();
break;
}
})
$('.colorBoard').change(function(){
_this.color = $(this).val();
_this.ctx.strokeStyle = _this.color;
if ($(this).val() != '#ffffff'){
$('.icon').removeClass('eraser-class').addClass('pencil-class');
}
})
$('.rangeBoard').change(function () {
_this.weight = $(this).val();
_this.ctx.lineWidth = _this.weight;
})
}
}
canvasBoard.init();

参考自:腾讯课堂渡一教育

canvas实现画板的更多相关文章

  1. 一款基于HTML5 Canvas的画板涂鸦动画

    今天给各网友分享一款基于HTML5 Canvas的画板涂鸦动画.记得之前我们分享过一款HTML5 Canvas画板工具,可以切换不同的笔刷,功能十分强大.本文今天要再来分享一款基于HTML5 Canv ...

  2. canvas小画板——(2)荧光笔效果

    我们在上一篇文章中讲了如何绘制平滑曲线 canvas小画板——(1)平滑曲线. 透明度实现荧光笔 现在我们需要加另外一种画笔效果,带透明度的荧光笔.那可能会觉得绘制画笔的时候加上透明度就可以了.我们来 ...

  3. canvas实现画板功能(渐变、动画、阴影...)

    刚刚在博客园落户了,希望能在这认识更多大神,希望能和大家交好朋友. 闲来无事,把以前用canvas写的画板代码改进了一番,用Html5提供的表单标签给其 加了一个选择颜色的功能,因此发现了该标签的一个 ...

  4. Android利用canvas画画板

    首先新建一个项目工程,建立文件,如下图所示

  5. 【分享】用Canvas实现画板功能

    前言 PC端测试:QQ浏览器全屏绘画完成.缩小时内容会被清空,切换背景颜色内容会被重置,其他暂无发现: 手机端测试:微信内置浏览器不通过:Safari 浏览器使用画笔时没固定页面会有抖动效果,使用橡皮 ...

  6. canvas简易画板。

    在学canvas的时候,想到可以做一个自己用来画画的简易画板,加上canvas的基础都已经学完,便尝试做了一个画板.如图 1.获取标签. var c=document.getElementById(' ...

  7. canvas简易画板

    代码展示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. canvas画画板,canvas画五角星,canvas制作钟表、Konva写钟表

    制作一个画画板,有清屏有橡皮擦有画笔可以换颜色 style样式 <head> <meta charset="UTF-8"> <title>画画板 ...

  9. html5 canvas 涂鸦画板

    html5 canvas 的涂鸦画板,可以加载图片进行涂鸦,也可以下载服务器使用的php上传的图片不能超过1M,只能是jpg或者png 格式的演示地址的服务器网速不怎么样,读取文件可能很慢,到达100 ...

随机推荐

  1. Oracle数据库逻辑迁移之数据泵的注意事项

    环境:数据迁移,版本 11.2.0.4 -> 12.2.0.1 思考: 对于DBA而言,常用物理方式的迁移,物理迁移的优势不必多说,使用这种方式不必担心对象前后不一致的情况,而这往往也解决了不懂 ...

  2. Reactor三种线程模型与Netty线程模型

    文中所讲基本都是以非阻塞IO.异步IO为基础.对于阻塞式IO,下面的编程模型几乎都不适用 Reactor三种线程模型 单线程模型 单个线程以非阻塞IO或事件IO处理所有IO事件,包括连接.读.写.异常 ...

  3. CSS学习笔记三:自定义单选框,复选框,开关

    一点一点学习CCS,这次学习了如何自定义单选框,复选框以及开关. 一.单选框 1.先写好body里面的样式,先写几个框 <body> <div class="radio-1 ...

  4. Java反射-修改private final成员变量值,你知道多少?

    大家都知道使用java反射可以在运行时动态改变对象的行为,甚至是private final的成员变量,但并不是所有情况下,都可以修改成员变量.今天就举几个小例子说明.  基本数据类型 String类型 ...

  5. PAT1034;Head of a Gang

    1034. Head of a Gang (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue One wa ...

  6. JAVA Set 交集,差集,并集

    /** * Created by yuhui on 2017/7/11 0011. */ import java.util.HashSet; import java.util.Set; public ...

  7. css的div垂直居中的方法,百分比div垂直居中

    前言 我们都知道,固定高宽的div在网页中垂直居中很简单,相信大家也很容易的写出来,但是不是固定高宽的div如何垂直居中呢?我们在网页布局,特别是手机等web端网页经常是不固定高宽的div,那么这些d ...

  8. spring MVC 管理HttpClient---实现在java中直接向Controller发送请求

    在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在java代码中直接向controller发送请求,这时可以使用HttpCilent实 ...

  9. scapyd部署出现的问题的解决方案

    使用scrapyd-deploy部署时,发现spiders为0的排查,首先用 scrapy list 看一下是否可以识别 windows下 scrapyd-deploy无后缀文件不能启动: 解决方案一 ...

  10. Go-技篇第二 命名规范

    优秀的命名 优秀的命名应当是一贯的.短小的.精确的.所谓一贯,就是说同一个意义在不同的环境下的命名应当一致,譬如依赖关系,不要在一个方法中命名为depend,另一个方法中命名为rely.所谓短小,不必 ...