用canvas画一个的小画板(PC端移动端都能用)
前言
本篇的内容主要包括:
- canvas标签简介
- 画板的功能简介
- 画板的JS部分
(包括:1、获取画布 2、使画板全屏幕显示且自适应 3、如何绘制直线 4、绘画时的三种状态(鼠标点击、移动、离开)5、画笔功能(画笔颜色、画笔粗细) 6、橡皮擦功能 7、一键清除功能 8、一键下载功能) - 画板的HTML部分
- 画板的CSS部分
正文
1 canvas标签简介
<canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。 <canvas> 看起来和 <img> 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,<canvas> 标签只有两个属性—— width和height。这些都是可选的,并且同样利用 DOM properties 来设置。当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。该元素可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲。 //注意:canvas不能使用CSS来设置宽高
2 画板的功能简介
- 画板的主要功能有:1 画笔功能(多种画笔颜色、画笔粗细),2 橡皮擦功能 ,3 一键清除功能 , 4 一键保存功能。
- 画板效果如下图所示,
3 画板的JS部分
获取画布
//1 获取画布
var canvasname=document.getElementById("canvas");
if(canvasname.getContext){
var context=canvasname.getContext('2d');
}使画板全屏幕显示且自适应
//2 全屏幕画布,ps:最好不要用css,会出bug
setCanvasSize();
window.onresize=function(){
setCanvasSize();
}; //这句的用处是在用户拖动屏幕的时候,宽度会重新全屏幕。但是会有刚刚画的东西丢失的bug绘画时的三种状态(鼠标点击、移动、离开)
//3 特性检测,检测设备是否可触碰。
lisenToUser(canvas)
function lisenToUser(canvas){
//使用document.body.ontouchstart!==undefined或者in方法ontouchstart in document.body都行。
if(document.body.ontouchstart!==undefined){
lisenToTouch(canvas);
}else{
lisenToMouse(canvas);
}
} //监听触摸事件的函数
function lisenToTouch(canvas){
var lastPoint={x:undefined,y:undefined};
var usingBrush=false;
canvas.ontouchstart=function(aaa){
console.log(aaa) //打印出touchevent
var x=aaa.touches[].clientX; //因为clientX/clientY的在Touch event的touchs下面的0数组中,所以。。。
var y=aaa.touches[].clientY;
console.log(x,y) //打印出坐标
if(usingEraser){
context.clearRect(x-,y-,,) //橡皮擦功能
}else{
usingBrush=true;
lastPoint={"x":x,"y":y};
//drawCircle(x,y,3);
}
};
canvas.ontouchmove=function(aaa){
var x=aaa.touches[].clientX;
var y=aaa.touches[].clientY;
if(usingEraser){
context.clearRect(x-,y-,,)
}else{
if (usingBrush){
var newPoint={"x":x,"y":y};
//drawCircle(x,y,3);
drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y);
lastPoint=newPoint;
}
}
};
canvas.ontouchup=function(){
usingBrush=false;
usingEraser=false;
};
} //监听鼠标事件的函数
function lisenToMouse(canvas){
var lastPoint={x:undefined,y:undefined};
var usingBrush=false;
canvas.onmousedown=function(aaa){
var x=aaa.clientX;
var y=aaa.clientY;
if(usingEraser){
context.clearRect(x-,y-,,)
}else{
usingBrush=true;
lastPoint={"x":x,"y":y};
//drawCircle(x,y,3);
}
};
canvas.onmousemove=function(aaa){
var x=aaa.clientX;
var y=aaa.clientY;
if(usingEraser){
context.clearRect(x-,y-,,)
}else{
if (usingBrush){
var newPoint={"x":x,"y":y};
//drawCircle(x,y,3);
drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y);
lastPoint=newPoint;
}
}
};
canvas.onmouseup=function(){
usingBrush=false;
usingEraser=false;
};
}如何绘制直线
//画一个直线
function drawLine(x1,y1,x2,y2){
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.stroke(); //画直线不能用fill()
context.closePath();
context.lineWidth=lineWidth; //此处将线宽赋值给一个变量时为了使为了方便设置画笔宽度
} 一条直线的作用是生成画笔的功能。配合鼠标/触摸的点击和移动的坐标,每次鼠标移动时保存上次的坐标并将上次的坐标和移动到的新的坐标相连接,用户在使用鼠标/手机触摸在页面上移动时会随着用户的移动形成线条。画笔功能(画笔颜色、画笔粗细)
//4 画笔功能
brush.onclick=function(){
usingEraser=false; //如果用户在使用画笔,则关闭橡皮擦功能
}
//有颜色的画笔,添加几个有颜色的按钮
red.onclick=function(){
context.strokeStyle="red";
context.fillStyle="red";
}
yellow.onclick=function(){
context.strokeStyle="yellow";
context.fillStyle="yellow";
}
green.onclick=function(){
context.strokeStyle="green";
context.fillStyle="green";
}
blue.onclick=function(){
context.strokeStyle="blue";
context.fillStyle="blue";
}
//画笔的粗细
var lineWidth;
thin.onclick=function(){
lineWidth=;
}
thin2.onclick=function(){
lineWidth=;
}
thick.onclick=function(){
lineWidth=;
}
thick2.onclick=function(){
lineWidth=;
}橡皮擦功能
//5 橡皮擦功能
eraser.onclick=function(){
usingEraser=true;
} 实现橡皮擦的功能:在鼠标/触摸点击和移动的时候检测用户是否在使用eraser按钮,如果在使用,使用如下语句擦除所画内容:context.clearRect(x-10,y-10,20,20),如用户未使用橡皮擦,则执行画笔功能。一键清除功能
//6 一键清除
clear.onclick=function(){
context.clearRect(,,canvas.width,canvas.height); //清除整个画布的内容即可实现一键清除
}一键下载功能
//7 一键下载
download.onclick = function(){
var url = canvas.toDataURL('image/png');
var a = document.createElement('a');
document.body.appendChild(a);
a.href = url;
a.download = 'my pic';
a.target="_blank"
a.click();
eraser.classList.remove("activesvg")
brush.classList.remove("activesvg")
clear.classList.remove("activesvg")
download.classList.add("activesvg")
}
4 画板的HTML部分
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!--加上"user-scalable=no/"会使手机真正自适应,使页面到手机上时字体不会自动缩放。"device-width"设备宽度-->
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>myCanvas</title>
<link rel="stylesheet" href="./style.css">
<script src="//at.alicdn.com/t/font_650559_geuacjzbo98p8pvi.js"></script> </head>
<body>
<canvas id="canvas" width="300px" height="300px"></canvas>
<!--不要用css添加宽度高度样式,不要用css添加宽度高度样式,不要用css添加宽度高度样式重要的事情说三遍-->
<div class="actions" id="actions">
<svg class="icon" aria-hidden="true" id="brush">
<use xlink:href="#icon-pen"></use>
</svg>
<svg class="icon" aria-hidden="true" id="eraser">
<use xlink:href="#icon-eraser"></use>
</svg>
<svg class="icon" aria-hidden="true" id="clear">
<use xlink:href="#icon-clear"></use>
</svg>
<svg class="icon" aria-hidden="true" id="download">
<use xlink:href="#icon-download"></use>
</svg>
</div>
<div class="colors">
<ol>
<li id="red"></li>
<li id="yellow"></li>
<li id="green"></li>
<li id="blue"></li>
</ol>
</div>
<div class="sizes">
<ol>
<li id="thin"></li>
<li id="thin2"></li>
<li id="thick"></li>
<li id="thick2"></li>
</ol>
</div>
<script src="./main.js"></script>
</body>
</html>
5 画板的CSS部分
.icon {
width: 1em; height: 1em;
vertical-align: -.15em;
fill: currentColor;
overflow: hidden;
}
ol,li{
list-style: none; /*清除无序列表前面的点点*/
}
*{
margin: ;
padding: ; /*kill掉元素的外边距和内边距*/
}
body{
overflow: hidden; /*解决在手机上页面会滚动的bug*/
position: fixed;
top: ;
left: ;
}
#canvas{
background:rgb(, , );
display:block;
}
.actions{
position: fixed; /*使元素脱离文档流,自己重新定位*/
top:;
left:;
padding:20px; }
.actions svg{
width: .5em;
height: .5em;
transition: all .3s;
margin: 4px;
}
.colors{
position: fixed;
top: 70px;
left: 10px;
}
.colors ol li{
width: 20px;
height: 20px;
margin: 8px 6px;
border-radius: %; /*是元素变成一个圆*/
}
.colors ol li#red{
background: red;
}
.colors ol li#yellow{
background: yellow;
} .colors ol li#green{
background: green;
}
.colors ol li#blue{
background: blue;
}
.sizes{
position: fixed;
top: 70px;
right: 10px;
}
.sizes ol li{
margin: 20px 6px;
}
.sizes ol li#thin{
border-top: 2px solid black;
width: 16px;
height: ;
}
.sizes ol li#thin2{
border-top: 4px solid black;
width: 16px;
height: ;
}
.sizes ol li#thick{
border-top: 6px solid black;
width: 16px;
height: ;
}
.sizes ol li#thick2{
border-top: 8px solid black;
width: 16px;
height: ;
}
用canvas画一个的小画板(PC端移动端都能用)的更多相关文章
- 10分钟,利用canvas画一个小的loading界面
首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" styl ...
- 深夜,用canvas画一个时钟
深夜,用canvas画一个时钟 查看demo 这几天准备阿里巴巴的笔试,可以说已经是心力交瘁,自从阿里和蘑菇街的内推被刷掉之后,开始越来越怀疑起自己的能力来,虽然这点打击应该是微不足道的.毕竟校招在刚 ...
- 用Canvas画一个刮刮乐
Canvas 通过 JavaScript 来绘制 2D图形.Canvas 是逐像素进行渲染的.开发者可以通过javascript脚本实现任意绘图.Canvas元素是HTML5的一部分,允许脚本语言动态 ...
- 使用H5 canvas画一个坦克
具体步骤如下: 1. 首先做出绘图区,作为坦克的战场 <canvas id="floor" width="800px" height=&quo ...
- 利用canvas画一个实时时钟
先放一张效果图: 下面是源代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- 手对手的教你用canvas画一个简单的海报
啦啦啦,首先说下需求,产品想让用户在我们app内,分享一张图片到微信.qq等平台.图片中包含用户的姓名.头像.和带着自己信息的二维码.然后,如何生成这张海报呢~~~首先我们老大告诉我有一个插件叫htm ...
- 利用canvas写一个验证码小功能
刚刚开始接触canvas,写个验证码小功能练练手,实现效果图如下: 主要代码如下: html <!DOCTYPE html> <html lang="en"> ...
- 玩转html5(四)----使用canvas画一个时钟(可以动的哦!)
先给个效果图,我画的比较丑,大家可以自己美化一下, 直接上代码: <!DOCTYPE html> <meta charset="utf-8"> <ht ...
- canvas画一个时钟
效果图如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
随机推荐
- 继承TabActivity后不执行onBackPressed()里的方法
// 用下面这个函数拦截子Activity的返回操作 @Override public boolean dispatchKeyEvent(KeyEvent event) { ...
- MVC bundle配置文件模板
bundle文件放在应用根目录,命名为 bundle.config 内容模板 <?xml version="1.0" encoding="utf-8"? ...
- [转]C#多线程和线程池
鸣谢原文:http://www.cnblogs.com/wwj1992/p/5976096.html 1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程 ...
- iOS原生数据存储策略
一 @interface NSCache : NSObject Description A mutable collection you use to temporarily store transi ...
- bzoj 2648: SJY摆棋子 KDtree + 替罪羊式重构
KDtree真的很妙啊,真的是又好写,作用还多,以后还需更多学习呀. 对于这道题,我们求的是曼哈顿距离的最小值. 而维护的变量和以往是相同的,就是横纵坐标的最小值与最大值. 我们设为一个极为巧妙且玄学 ...
- 对于 wepy 不是内部或外部命令 -- 的解决办法
闲来没事继续研究自己之前一直未解决的问题, 就是自己笔记本安装wepy-cli,一直提示"wepy 不是内部或外部命令". 因为公司里面用的是这个框架, 想着自己在家没事的时候去 ...
- JS中的异步
Hello,日常更新的我“浪”回来了!!! JS中有三座高山:异步和单线程.作用域和闭包.原型原型链 今天“浪”的主题是JS中的异步和单线程的问题. 主要从这三个方面入手 一.什么是异步(与同步作比较 ...
- 模板 FFT 快速傅里叶变换
FFT模板,原理不难,优质讲解很多,但证明很难看太不懂 这模板题在bzoj竟然是土豪题,服了 #include <cmath> #include <cstdio> #inclu ...
- 2019-03-28 SQL Server Table
-- table 是实际表 view是虚表.你可以认为view是一个查询的结果 -- 声明@tbBonds table declare @tbBonds table(TrustBondId int n ...
- 小学生都能学会的python(字典{ })
小学生都能学会的python(字典{ }) 1. 什么是字典 dict. 以{}表示. 每一项用逗号隔开, 内部元素用key:value的形式来保存数据 {"jj":"林 ...