1、Canvas基础
1) canvas类似于img标签(行内块),但是不能在css里设置宽高。
它使用自身的width和height属性。但可以用css写其它东西
2) 页面中引入Canvas的方法
<canvas id="canvas" width="500" height="500">
您的浏览器不支持canvas,请升级最新版
</canvas>
3) 基本的canvas的操作方法
1> 获取元素 var canvas = document.getElementById("canvas");
2> 获取上下文对象(画笔) var ctx = canvas.getContext("2d");
console.log(ctx);//CanvasRenderingContext2D对象
3> 基本的绘制步骤
1.开始绘制 ctx.beginPath();
2.绘制起点 ,通常只写一次 ctx.moveTo(x,y);
3.绘制后续的点 ,可写多次 ctx.lineTo(x,y);
4.结束绘制/关闭路径,会把终点 和 起点 链接起来,进行绘制
当需要终点 和 起点链接起来的时候才使用,需要才写
ctx.closePath();
5.画(填) 先设置 后画 填充 注意先后顺序
绘制的线和填充的内容会发生覆盖的情况,没有优先级,
由代码的书写顺序绝对(后面的会覆盖前面的设置)
ctx.stroke();//画
ctx.fill();//填 如果填的时候,没有ctx.closePath() 则会由起点填充到终点
2、Canvas画直线
1)填充
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(400,400);
ctx.lineTo(100,400);
ctx.closePath();
ctx.fillStyle = "green";//换填充的颜色
ctx.globalAlpha = 0.5; //全局透明度
ctx.fill();
2)描边
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(400,400);
ctx.closePath();
ctx.strokeStyle = "red" //设置画线颜色
ctx.lineWidth = 10; //设置线宽 里外同时扩散
ctx.stroke();//画
3)其它属性
ctx.lineWidth 线宽
lineCap = "round"; 线末尾的形状 不需要ctx.closePath()
lineJoin = "round"; 两条边交汇时,创建圆角边,需要ctx.closePath()
3、Canvas画矩形
1)画矩形:
fillRect(x,y,width,height) 按照矩形填充
strokeRect(x,y,width,height) 按照矩形画线
2)示例:
//矩形
// ctx.beginPath();
// ctx.strokeStyle = "blue";
// ctx.strokeRect(0,400,100,50);
// ctx.stroke();
//正方形
// ctx.beginPath();
// ctx.fillStyle = "pink";
// ctx.fillRect(0,0,100,100);
// ctx.fill();
//画多个图形
// for(var i = 0; i < 500; i+=10){
// var x = 10,y = 10,w=50,h=50;
// ctx.strokeStyle = randomColor();
// ctx.strokeRect(x+i,y+i,w,h);
// }
4、Canvas画文字
1)画文字
空心 ctx.strokeText(text,x,y,maxWidth?);
实心 ctx.fillText(text,x,y,maxWidth?);
参数1:要显示的文本信息
参数2,3文字在画布上显示的位置
参数4:可选参数,设置文本的最大显示宽度,文本不会超出该宽度
2)文字的对齐方式
ctx.textAlign("left/center/right"); 水平方向
ctx.textBaseline("top/middle/bottom/baseline"); 垂直方向
3)字体大小和样式
ctx.font = "50px 宋体";
5、Canvas画圆
1)绘制圆形 ctx.arc(x,y,r,start,end,dir);
//参数1:圆心的x
//参数2:圆心的y
//参数3:圆的半径
//参数4:起始点的位置,根据右侧和设置的弧度找到起点
//参数5:终点的位置,根据右侧和设置的弧度找到终点
//参数6:绘制的方向 true代表逆时针,false代表顺时针
2)绘制同心圆 半径由大到小 让小得覆盖大的
for(var i = 250; i > 20; i-=20){
ctx.beginPath();
ctx.strokeStyle = randomColor();
// ctx.fillStyle = randomColor();
ctx.arc(250,250,i,0,Math.PI*2,false);
ctx.stroke();
// ctx.fill();
}
3)绘制笑脸的几种方法
1>一般常规画法
ctx.arc(250,250,200,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(200,200,30,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(300,200,30,0,Math.PI*2,false);
ctx.stroke();
ctx.beginPath();
ctx.arc(250,270,100,0,Math.PI,false);
ctx.closePath();
ctx.stroke();
2>封装函数思想
function draw(x,y,r,start,end,dir){
ctx.beginPath();
ctx.arc(x,y,r,start,end,dir);
ctx.closePath();
ctx.stroke();
}
//调用函数
draw(250,250,200,0,Math.PI*2,false);
draw(200,200,30,0,Math.PI*2,false);
draw(300,200,30,0,Math.PI*2,false);
draw(250,270,100,0,Math.PI,false);
3>面向对象思想 初级 和封装函数没什么不同
var smileArr = [
{x:250,y:250,r:200,end:Math.PI*2},
{x:200,y:200,r:30,end:Math.PI*2},
{x:300,y:200,r:30,end:Math.PI*2},
{x:250,y:270,r:100,end:Math.PI}
];
for(var i = 0; i < smileArr.length; i++){
ctx.beginPath();
ctx.arc(smileArr[i].x,smileArr[i].y,smileArr[i].r,0,smileArr[i].end,false);
ctx.closePath();
ctx.stroke();
}
4>面向对象思想 中级
function Area(x,y,r,start,end,dir){
this.x=x;
this.y=y;
this.r=r;
this.start=start;
this.end=end;
this.dir=dir;
}
//添加原型方法
Area.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
ctx.closePath();
ctx.stroke();
}
//创建实例化对象
var bigCircle = new Area(250,250,200,0,Math.PI*2,false);
var leftEyes = new Area(200,200,30,0,Math.PI*2,false);
var rightEyes = new Area(300,200,30,0,Math.PI*2,false);
var mouth = new Area(250,270,100,0,Math.PI,false);
//调用原型的方法
bigCircle.draw();
leftEyes.draw();
rightEyes.draw();
mouth.draw();
5>面向对象思想 高级
function Area(x,y,r,start,end,dir){
this.x=x;
this.y=y;
this.r=r;
this.start=start;
this.end=end;
this.dir=dir;
}
Area.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
ctx.closePath();
ctx.stroke();
}
// 数据
var smileArr = [
{x:250,y:250,r:200,end:Math.PI*2},
{x:200,y:200,r:30,end:Math.PI*2},
{x:300,y:200,r:30,end:Math.PI*2},
{x:250,y:270,r:100,end:Math.PI}
];
for(var item of smileArr){
var obj = new Area(item.x,item.y,item.r,0,item.end,false);
obj.draw();
}
6、Canvas画曲线
1)画曲线
ctx.quadraticCurveTo(x2,y2,x3,y3);//二次贝塞尔曲线 一对基准点 一对终点
ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);//三次贝塞尔曲线 两对基准点 一对终点
2)示例
1> 二次贝塞尔曲线
ctx.moveTo(0,0);//绘制起点
ctx.quadraticCurveTo(250,500,500,0);
ctx.stroke();
ctx.moveTo(0,0);//绘制起点
ctx.quadraticCurveTo(500,250,0,500);
ctx.stroke();
ctx.moveTo(0,500);
ctx.quadraticCurveTo(250,0,500,500);
ctx.stroke();
// ctx.beginPath();
ctx.moveTo(500,0);
ctx.quadraticCurveTo(0,250,500,500);
ctx.stroke();
// ctx.fill();
2> 三次贝塞尔曲线
ctx.beginPath();
ctx.strokeStyle="orange";
ctx.moveTo(0,0);//绘制起点
ctx.bezierCurveTo(500,0,0,500,500,500);
ctx.stroke();
//这里上下两条线是重合的
// ctx.beginPath();
// ctx.strokeStyle="purple";
// ctx.moveTo(500,500);//绘制起点
// ctx.bezierCurveTo(0,500,500,0,0,0);
// ctx.stroke();
//----------------------------------------
ctx.beginPath();
ctx.strokeStyle="red";
ctx.moveTo(500,0);//绘制起点
ctx.bezierCurveTo(0,0,500,500,0,500);
ctx.stroke();
//这里上下两条线是重合的
// ctx.beginPath();
// ctx.strokeStyle="hotpink";
// ctx.moveTo(0,500);//绘制起点
// ctx.bezierCurveTo(500,500,0,0,500,0);
// ctx.stroke();
//--------------------------------
ctx.beginPath();
ctx.strokeStyle="green";
ctx.moveTo(0,500);//绘制起点
ctx.bezierCurveTo(0,0,500,500,500,0);
ctx.stroke();
//这里上下两条线是重合的
// ctx.beginPath();
// ctx.strokeStyle="pink";
// ctx.moveTo(500,0);//绘制起点
// ctx.bezierCurveTo(500,500,0,0,0,500);
// ctx.stroke();
//--------------------------------
ctx.beginPath();
ctx.strokeStyle="blue";
ctx.moveTo(500,500);//绘制起点
ctx.bezierCurveTo(500,0,0,500,0,0);
ctx.stroke();
//这里上下两条线是重合的
// ctx.beginPath();
// ctx.strokeStyle="red";
// ctx.moveTo(0,0);//绘制起点
// ctx.bezierCurveTo(0,500,500,0,500,500);
// ctx.stroke();
3)用二次贝塞尔曲线可以大致实现三次贝塞尔曲线的效果
例如:
//三次
ctx.beginPath();
ctx.strokeStyle="pink";
ctx.moveTo(500,0);//绘制起点
ctx.bezierCurveTo(500,500,0,0,0,500);
ctx.stroke();
//二次
ctx.moveTo(500,0);
ctx.quadraticCurveTo(500,250,250,250);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(250,250);
ctx.quadraticCurveTo(0,250,0,500);
ctx.stroke();
4)利用Canvas曲线的画法,可以画出肯定不合常规的图形
例如:心、不规则三角形、太极等
//画心
ctx.fillStyle="red";
ctx.moveTo(250,200);
ctx.quadraticCurveTo(0,50,250,450);
ctx.fill();
ctx.beginPath();
ctx.moveTo(250,200);
ctx.quadraticCurveTo(500,50,250,450);
ctx.fill();
7、Canvas画图片
1)画图片 ctx.drawImage(img,x,y,w,h,dx,dy,dw,dh);
img为要画的图片
img后紧邻的四个值是在canvas中的位置,以及显示图片的宽高
最后面四个值是寻找的图片中具体想显示的区域
2)示例
如果想把图片画到canvas中,需要先创建image对象
var img = new Image();
img.src = "。。。。。";
img.onload = function(){
//必须等图片加载完成再去绘制
ctx.drawImage(img,100,100,200,200,100,100,100,100);
//清除画布 四个参数:x,y,w,h
ctx.clearRect(250,250,200,200);//用户清除画布中已有的内容
// ctx.clearRect(0,0,500,500); //清除整个画布的内容
}
8、Canvas形变
1)平移 ctx.translate(x,y); 改变的是坐标系,不改变已经绘制好了的内容
2)缩放 ctx.scale(0.5,0.5); 位置以及原图大小都会改变,缩放时密度变大,缝隙变小
3)旋转 ctx.rotate(deg); 围绕画轴起点旋转,是整个画布的旋转
4)示例:
//绘制表盘
ctx.translate(250,250);
for(var i = 0; i < 12; i++){
ctx.rotate(Math.PI/6);
ctx.beginPath();
ctx.moveTo(0,-200);
ctx.lineTo(0,-150);
ctx.closePath();
ctx.lineWidth = 10;
ctx.stroke();
}
9、Canvas阴影
ctx.shadowColor = "red"; 阴影颜色
ctx.shadowOffsetX = 10; 阴影X轴偏移量
ctx.shadowOffsetY = 10; 阴影y轴偏移量
ctx.shadowBlur = 10; 阴影的模糊程度
10、Canvas动画
原理: 搽除-绘制-搽除-绘制-搽除-绘制-。。。
使用setInterval();
setTimeout()实现setInterval()
requestAnimationFrame(); 帧动画
11、注意:
1)多个图形之间有连线时,是因为画笔没有抬起,解决方法是写上ctx.beginPath();
2)fill和stroke同时使用时会有覆盖效果,注意先后顺序
而且每个相对应的设置,都有先设置,再进行描边或者填充,
不然