canvas
画板,比较简易,目前还有很多bug
1、手机端上下会晃动
2、下载按钮微信上没法用
3、下载后背景色是透明
4、切换成橡皮擦后,需要先点铅笔才能绘画,不能直接点颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
ul,ol{list-style:none;}
*{margin: 0;padding: 0;}
body{overflow: hidden;}
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.canvas{
background: white;
display: block;
position:fixed;
top:0;
left:0;
}
#actions{
position: fixed;
top: 0;
left:5px;
}
#actions svg{
width: 1.5em;
height: 2em;
transition: all 0.3s;
margin: 10px;
}
#actions .action{
fill:red;
transform: scale(1.2);
}
.colors{
position: fixed;
top:41px;
left:12px;
}
.color{
transform: scale(1.2);
}
.colors > li{
width:20px;
height:20px;
margin:10px 0;
border-radius: 50%;
}
.colors > li.black{
background: black;
}
.colors > li.red{
background: red;
}
.colors > li.green{
background: green;
}
.colors > li.blue{
background: blue;
}
</style>
</head>
<body>
<canvas id="xxx" class="canvas"></canvas>
<div id="actions">
<svg id="pen" class="icon action" aria-hidden="true">
<use xlink:href="#icon-pen"></use>
</svg>
<svg id="eraser" class="icon" aria-hidden="true">
<use xlink:href="#icon-eraser"></use>
</svg>
<svg id="clear" class="icon" aria-hidden="true">
<use xlink:href="#icon-custom-clear"></use>
</svg>
<svg id="download" class="icon" aria-hidden="true">
<use xlink:href="#icon-download1"></use>
</svg>
<!--<button id="eraser">橡皮擦</button>-->
<!--<button id="brush">画笔</button>-->
</div>
<ol class="colors">
<li id="black" class="black color"></li>
<li id="red" class="red"></li>
<li id="green" class="green"></li>
<li id="blue" class="blue"></li>
</ol>
<!--<div id="canvas"></div>-->
<script src="//at.alicdn.com/t/font_663139_nbdaue5y67gmn29.js"></script>
<script src="js/canvas3.js"></script>
</body>
</html>
JS代码
<script>
var yyy = document.getElementById('xxx');
var ctx = yyy.getContext("2d");
autoCanvasSize(yyy);
listenToUser(yyy);
//是否使用橡皮擦
var eraserEnable = false;
eraser.onclick = function () {
eraserEnable = true;
eraser.classList.add('action');
pen.classList.remove('action');
};
pen.onclick = function () {
eraserEnable = false;
pen.classList.add('action');
eraser.classList.remove('action');
};
red.onclick = function () {
ctx.fillStyle = "red";
ctx.strokeStyle = "red";
red.classList.add('color');
green.classList.remove('color');
blue.classList.remove('color');
black.classList.remove('color');
};
green.onclick = function () {
ctx.fillStyle = "green";
ctx.strokeStyle = "green";
green.classList.add('color');
red.classList.remove('color');
blue.classList.remove('color');
black.classList.remove('color');
};
blue.onclick = function () {
ctx.fillStyle = "blue";
ctx.strokeStyle = "blue";
blue.classList.add('color');
red.classList.remove('color');
green.classList.remove('color');
black.classList.remove('color');
};
black.onclick = function () {
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
black.classList.add('color');
red.classList.remove('color');
blue.classList.remove('color');
green.classList.remove('color');
};
clear.onclick = function () {
ctx.clearRect(0,0,yyy.width,yyy.height);
};
download.onclick = function () {
var url = yyy.toDataURL("image/png");
var a = document.createElement('a');
document.body.appendChild(a);
a.href = url;
a.download = "我的画";
a.target = "_blank";
a.click();
};
//设置画板
function autoCanvasSize(canvas) {
function setCanvasSize(){
var pageWidth = document.documentElement.clientWidth; // 获取屏幕宽度
var pageHeight = document.documentElement.clientHeight; //获取屏幕高度
canvas.width = pageWidth; //画板宽等于屏幕宽度
canvas.height = pageHeight; //画板高等于屏幕高度
}
setCanvasSize();
window.onresize = function ( ){ //改变窗口大小
setCanvasSize();
};
}
//监听用户鼠标事件
function listenToUser(canvas) {
var painting = false;
var lastPoint = {};
if(document.body.ontouchstart !== undefined){
canvas.ontouchstart = function (aaa) {
console.log(aaa);
var x = aaa.touches[0].clientX; //console.log打印出aaa,找到里面的touches(多点触控),第一个用touches[0]
var y = aaa.touches[0].clientY;
painting = true;
if(eraserEnable){
ctx.clearRect(x-5,y-5,10,10);
}else{
lastPoint = {"x":x,"y":y}; //在每次动的时候把当前点和动的点连成一条线
drawCircle(x,y,4);
}
};
canvas.ontouchmove = function (aaa) {
var x = aaa.touches[0].clientX;
var y = aaa.touches[0].clientY;
var newPoint = {x:x,y:y};
if(!painting){return;}
if(eraserEnable){
ctx.clearRect(x-5,y-5,10,10);
}else{
drawCircle(x,y,4);
drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y,10);
lastPoint = newPoint; //实时更新上一个点的坐标,不然都和第一个点连接了
}
};
canvas.ontouchend = function () {
painting = false;
}
}else{
//鼠标按下
canvas.onmousedown = function (aaa) {
var x = aaa.clientX;
var y = aaa.clientY;
painting = true;
if(eraserEnable){
ctx.clearRect(x-5,y-5,10,10);
}else{
lastPoint = {"x":x,"y":y}; //在每次动的时候把当前点和动的点连成一条线
drawCircle(x,y,4);
}
};
//鼠标移动
canvas.onmousemove = function (aaa) {
var x = aaa.clientX;
var y = aaa.clientY;
var newPoint = {x:x,y:y};
if(!painting){return;}
if(eraserEnable){
ctx.clearRect(x-5,y-5,10,10);
}else{
drawCircle(x,y,4);
drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y,10);
lastPoint = newPoint; //实时更新上一个点的坐标,不然都和第一个点连接了
}
};
//松开鼠标
canvas.onmouseup = function () {
painting = false;
};
}
}
//画圆
function drawCircle(x,y,radius){
ctx.beginPath();
ctx.arc(x,y,radius,0,Math.PI*2);
ctx.fill()
}
//连线
function drawLine(x1,y1,x2,y2,lineWidth){
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineWidth = lineWidth;
ctx.lineTo(x2,y2);
ctx.stroke();
ctx.closePath();
}
</script>
总结:
1、按下鼠标和移动鼠标后它们中间会有空隙,解决方法:用线连接鼠标移动前后的两点。lasePoint
和newPoint
2、painting = false
监听用户是否在绘画。true
再绘画false
不在绘画。
3、eraserEnable = false;
监测用户是在使用橡皮檫,true
是在使用橡皮擦,停止使用铅笔。
4、判断用户是使用pc还是手机,需要监测是否有touch
事件,如果有,首先使用touch
事件;在pc端document.body.ontouchstart === undefined
,在移动端是null
,只要不等于undefined
就可以确定是移动端。
5、状态切换,不直接修改css里面内容,通过js切换class来实现状态切换。比如:上面橡皮擦和铅笔的切换。
6、使用x.className = 'active'
,class
会变为active
;使用x.classList.add('active')
,class
后面会增加一个属性值active
。
7、document.documentElement.clientWidth
的作用是获取document
宽度(也就是viewport
宽度)
8、移动端支持多点触控,所以要获取clientX
需要加上touches[0]
,表示touch
第一个值
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。