canvas画板总结
制作Canvas画板
画板预览
源码地址
canvas的使用查mdn文档就可以了
下面主要讲的是实现画板的思路,以及我的踩坑记录
先不用canvas标签
先用div,首先知道用户点了哪里
使用console.log调试
<div id="canvas"></div>
xxx.onClick = (e) => {console.log(e)//e.clientX//e.clientY
}
在点击的地方出现圆点
let div = document.createElement('div')
div.style.position = 'absolute'
div.style.left = e.clientX + 'px'
div.style.top = e.clientY + 'px'
div.style.border = '1px solid red'
div.style.weight = '5px'
div.style.height = '5px'
div.style.borderRadius = '50%'
div.style.backgroundColor = 'black'
xxx.appendChild(div)
把点连起来,点变成线
现在是直接操作dom(操作div的),性能差
改进:使用canvas。
<canvas id="canvas"></canvas>
canvas是inline元素
display: block;
再把宽高设置成页面这么大即可
var ctx = canvas.getContext("2d");ctx.fillStyle = "rgb(200,0,0)";ctx.fillRect (10, 10, 55, 50);
上面这个是canvas画出一个形状,前面两个参数是起始位置,后面两个是宽高
canvas的宽高是在一开始就确定的,
<canvas id="canvas" width="100" height="100"></canvas>
如果后面css还有宽高,就会覆盖这个宽高,但是就相当于缩放了,放大的话就会变模糊。所以最开始写宽高就会写好(用js获取用户屏幕的宽高)
var canvas = document.getElementById("canvas")
const mainWidth = parseInt(main.clientWidth * 0.95);
const mainHeight = parseInt(main.clientHeight );
canvas.width = `${mainWidth}`;
canvas.height = `${mainHeight}`;
canvas.style.width = `${mainWidth}px`;
canvas.style.height = `${mainHeight}px`;
注意:获取的是文档的宽高,获取body是不行的,因为body的高度是由内容撑起来的,没有内容,高度就没有
下面是做点击就打点的操作
canvas.onClick = (e) => {ctx.fillRect(e.clientX - 5, e.clientY - 5, 10, 10)
}
这个是canvas的api
变换鼠标事件
onClick->onmousemove
使用一个变量来看鼠标是否是按下,按下时鼠标移动就继续划线,鼠标松开时就不划线
let painting = falsecanvas.onmousedown = () => {painting = true
}
canvas.onmousemove = () => {painting = false
}
canvas.onClick = (e) => {if(painting === true) {ctx.fillRect(e.clientX - 5, e.clientY - 5, 10, 10)}
}
这样就实现了鼠标按下就画线,鼠标松开就停
画圆点
ctx.beginPath();
ctx.arc(50, 50, 50, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.arc(50, 50, 50, 0, 2 * Math.PI, false);
ctx.arc(e.clientX, e.clientY,10, 0, 2 * Math.PI, false);
前两个参数是起始位置,第三个是半径,后面两个是角度
ctx.fill()//实心,填充颜色
再把边框去掉
ctx.strokeStyle = 'none'
现在就可以慢速的画了,为什么是慢速呢,因为是拼凑的,画快了就断掉了,当速度快一点时,就变成点的形状了
怎么样支持手机,但是手机没有鼠标事件,所以就要判断是手机还是pc。
js detect touch support
var isTouchDevice = 'ontouchstart' in document.documentElement;
判断isTouchDevice
是true或者false,就能知道是手机还是pc
难点
这个在手机上是支持的,在电脑上是不支持的,就可以判断是手机还是电脑(搜了半天),(就是上面这个)
手机上ontouchstart
就是触屏事件,参数e里面就是有touches,里面包含了我们需要的x和y(位置)
手机上就没有按下,起来的事件,就直接是触摸事件
现在是点,把点变成线就可以了
在canvas里面搜直线,这个是三角形,也就是三个点,画直线的画就要两个点就够了,去掉第三个点即可
//描边三角形ctx.beginPath();ctx.moveTo(125, 125);ctx.lineTo(125, 45);ctx.lineTo(45, 125);ctx.closePath();ctx.stroke();//上面的就是三个点,然后把三个点连起来
两个点连上就变成直线了,记住上一个点,然后连起来就好起来了
记住上一次的点,然后把现在的点和上一次的点连起来,就可以了,第一个点没有上一个点,所以从第二个点开始。
把线变粗
ctx.lineWidth = 10
难点
画出来的线又很粗糙
解决:js canvas line join
把line和line之间的链接变成圆弧
ctx.lineCap = "round"
整个画板的实现过程
获取位置->打点->连线->断断续续->记住上一个点连起来->粗糙->变成圆弧就不粗糙了
使用了flex布局
使用正则表达式来替换颜色,把颜色转化为不同的格式
const color = getComputedStyle(e.target).backgroundColor;
获取当前的颜色
用了一个伪类来在显示的时候添加边框
颜色的部分使用了<input type="color"></input>
橡皮檫部分是使用了ctx.globalCompositeOperation = "destination-out";
去mdn上查就能查到这个属性的作用
铅笔是ctx.globalCompositeOperation = "source-over";
这两个相互切换是使用了classList
,首先给这个添加selected
这个类,加上标签,然后再用forEach和indexOf
来判断eraser和source-over
确定是铅笔还是橡皮
画布的高度
const mainWidth = parseInt(main.clientWidth * 0.95);
const mainHeight = parseInt(main.clientHeight );
canvas.width = `${mainWidth}`;
canvas.height = `${mainHeight}`;
canvas.style.width = `${mainWidth}px`;
canvas.style.height = `${mainHeight}px`;
鼠标绘图
main.addEventListener("mousedown", (e) => {painting = true;lastX = e.offsetX;lastY = e.offsetY;ctx.beginPath();ctx.arc(lastX, lastY, ctx.lineWidth / 2, 0, 2 * Math.PI);ctx.closePath();ctx.fill();
});
main.addEventListener("mousemove", (e) => {if (painting) {ctx.beginPath();ctx.moveTo(lastX, lastY);ctx.lineTo(e.offsetX, e.offsetY);ctx.closePath();ctx.stroke();lastX = e.offsetX;lastY = e.offsetY;}
});
main.addEventListener("mouseup", (e) => {painting = false;
});
// 鼠标移出画布停止绘画,防止再次进入产生连线
main.addEventListener("mouseout", (e) => {painting = false;
});
移动端绘图
// 触摸绘图
canvas.addEventListener("touchstart", (e) => {painting = true;lastX = e.touches[0].pageX - e.touches[0].target.offsetLeft;lastY = e.touches[0].pageY - e.touches[0].target.offsetTop;ctx.beginPath();ctx.arc(lastX, lastY, ctx.lineWidth / 2, 0, 2 * Math.PI);ctx.closePath();ctx.fill();
});
// 使用事件委托优化移动端绘图,在画布上触摸移动时阻止body默认事件(阻止浏览器的滑动)
document.body.addEventListener("touchmove",(e) => {if (painting && e.target.matches(`canvas`)) {e.preventDefault();ctx.beginPath();ctx.moveTo(lastX, lastY);ctx.lineTo(e.touches[0].pageX - e.touches[0].target.offsetLeft,e.touches[0].pageY - e.touches[0].target.offsetTop);ctx.closePath();ctx.stroke();lastX = e.touches[0].pageX - e.touches[0].target.offsetLeft;lastY = e.touches[0].pageY - e.touches[0].target.offsetTop;}},{ passive: false }
);
canvas.addEventListener("touchend", (e) => {painting = false;
});
// 触摸移出画布停止绘画,防止再次进入产生连线
canvas.addEventListener("touchcancel", (e) => {painting = false;
});
显示当前的颜色
currentColor.addEventListener("input", (e) => {ctx.strokeStyle = e.target.value;ctx.fillStyle = e.target.value;
});
thickness.addEventListener("input", (e) => {ctx.lineWidth = parseInt(e.target.value);
});
点击切换颜色
// 点击色块改变画笔颜色,将色块背景色赋值给 currentColor.value (RGB 转为 HEX )
brushColor.addEventListener("click", (e) => {if (e.target.matches("li")) {let color16 = "#";const color = getComputedStyle(e.target).backgroundColor;[...color.matchAll(/\d{1,3}/g)].forEach((item) => {const str = parseInt(item).toString(16);color16 += str.length === 2 ? str : "0" + str; // 确保六位数 HEX 颜色值});ctx.strokeStyle = color16;ctx.fillStyle = color16;currentColor.value = color16;}
});
画笔和橡皮的切换
// 点击图标切换铅笔橡皮,使用 globalCompositeOperation 设置绘图类型
type.addEventListener("click", (e) => {if (e.target.matches("img")) {const li = e.target.parentNode;type.childNodes.forEach((node) =>node.classList ? node.classList.remove("selected") : undefined);li.classList.add("selected");if (Array.from(li.classList).indexOf("eraser") >= 0) {text.textContent = "橡皮";ctx.globalCompositeOperation = "destination-out";} else {text.textContent = "铅笔";ctx.globalCompositeOperation = "source-over";}}
});
canvas画板总结相关推荐
- 使用signature在移动端做电子签名canvas画板随触摸滚屏的bug
在做移动端项目的时候,如果页面需要滚动,而页面上有signature实现的电子签名,就会发现手写的时候canvas画板会随着手指的滑动而滚动,导致不能正常签名. 解决办法:在canvas标签上注册一个 ...
- 实现一个canvas画板
<canvas>是HTML5新增的元素,可用于通过使用JavaScript中的脚本来绘制图形.例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染. --摘自MDN ...
- canvas画板涂鸦动画进度条动画
目录 什么是 canvas 画板涂鸦动画 进度条动画 写在最后 什么是 canvas canvas 是 HTML5 新定义的标签,通过使用脚本(通常是 JavaScript)绘制图形.允许脚本语言动态 ...
- 南宁小程序开发,挑战百日学习计划第47天(canvas画板工具1)
南宁小程序开发:www.nasiot.com canvas画板工具 ,一定要在canvas里面写width height 否则会导致画线被强制放大 <canvas id="c" ...
- 移动端canvas画板绘图工具
移动端canvas画板绘图工具 原生js canvas画板可在移动端使用,使用鼠标或者手指触屏绘画各种图形效果. 演示地址 下载地址
- canvas画板绘制多图和绘制文字及下载
** canvas画板绘制多图和绘制文字及下载 有要求需要做宣传图,加文字动态排版,以及,二维码排版,还要完成后下载的功能,然后研究了一下午,写了一个供大家学习 上效果图 上代码: <!DOCT ...
- html canvas生成图片,html5 canvas画板涂鸦生成图片代码
特效描述:html5 canvas 画板涂鸦 生成图片代码.html5画板涂鸦 代码结构 1. HTML代码 清 空 生成图片 var canvas,board,img; canvas = docum ...
- HTML5 canvas画板的制作
canvas画板的制作 今天看了一些canvas视频的教程,有制作画板的过程,但是我有给出他们的简洁版和使用版本,能让用户看出画直线的路径,也就是当你拉一条直线的时候就和绘图工具一样,都能很好使用 ...
- html5 canvas 画板 demo,html5 canvas 简单画板实现代码
canvas简单画板 #can{ width:600px; height:500px; border:1px solid #ccc; margin-top:0px; margin-left:20px; ...
最新文章
- 机器学习算法1_线性回归
- Diomidis Spinellis:有效的调试
- 【异常】 ‘ascii‘ codec can‘t decode byte 0xe8 in position 2: ordinal not in range(128)
- C++中指针*与指针引用*的区别说明
- python调用打印机驱动下载_selenium的Python使用(一)浏览器驱动的安装及使用
- webStorm activeCode
- 机器人出魔切还是三相_英雄联盟:辅助也要去上单,机器人布里茨玩法介绍
- android布局的属性,android
- 编程基础(三)——体系结构之三
- 小波包8层分解与重构MATLAB代码,谐波小波包分解与重构程序谁有呢?
- 剑指offer之编程是一种习惯
- 考研高危人群!你是否还在危险的边缘试探?
- 2015英语命题规律
- 名字中间一条线怎么弄_网名怎么加横线啊 网名中间加一条横线
- MPX + Vant Weapp 在微信小程序中实现Picker选择器
- 58 同城移动端 Passport SDK 的设计与技术细节
- python发送邮件封装
- 中小企业数字化转型的痛点分析
- Couldn‘t find ffmpeg or avconv - defaulting to ffmpeg, but may not work快速解决办法
- 【每日新闻】身份证照可“自拍”上传 解决又一民生痛点