简介:
canvas是html5最重要的元素,提供了一个画布的功能,有强大的图形处理能力
canvas标签添加
要使用canvas,首先要在body中添加上canvas标签
canvas标签是一块默认300*150大小的画布
画布宽高设置:
使用canvas标签的属性,width及height直接在行间设置
此处注意:不要用css样式去改画布大小,这个会导致画布中的图像被拉伸
<canvas id="canvas1" width="800" height="500"></canvas>
画布css样式
画布的其他css样式可以正常设置
canvas标签中的内容
canvas标签中的内容是(包括标签)只有在不支持此效果的低版本浏览器中才会显示的;在高版本浏览器中不会显示出来
<canvas id="canvas1" width="800" height="500">
只是一个canvas标签,然而你看不到
</canvas>
获取canvas标签及上下文
canvas标签使用js正常dom节点的获取方法获取
var canvas = document.getElementById('canvas1');
上下文是记录canvas执行命令语句的地方,获取如下,后面的参数现在只有2d可选
var context = canvas.getContext('2d');
canvas坐标系
左上角是00点,x轴正方向向右,y轴正方向向下
样式设置
边框设置:context.strokeStyle
填充设置:context.fillStyle
线宽设置:context.lineWidth
context.strokeStyle = "red";
context.lineWidth = 2;
context.fillStyle = 'yellow';
绘制图形
绘制命令
- 边框式绘制:
context.stroke();
- 填充式绘制:
context.fill();
新建路径beginPath()
这个方法代表重新开始一段路径,也可以理解为新建一个图层
这个的方法之后执行的绘制动作,不会执行到这个方法之前的命令
context.beginPath();
绘制直线:
- 设置画笔开始位置:
context.moveTo(x,y)
- 设置画笔结束位置:
context.lineTo(x,y)
- 线段两边圆角:
context.lineCap = "round"
context.strokeStyle = "red";
context.lineWidth = 2;
context.moveTo(100,100);
context.lineTo(500,100);
context.stroke();
绘制三角:方法就是绘制3条直线
绘制多条连续线段时,不必每次重新定义起始点
画笔会停在上一段线段的终点,并默认为下一次绘制的起始点
context.strokeStyle = "red";
context.lineWidth = 2;
context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.lineTo(10,10);
context.stroke();
注意,此处用绘制直线的方法,进行图形的绘制时;直线封闭处会出现瑕疵,不会完全闭合
闭合方法:context.closePath()
加上上面的闭合命令后,闭合处的瑕疵就会被修复
这个方法会自动将起点与末点相连,所以不必再将路径回到起始点
context.strokeStyle = "red";
context.lineWidth = 2;
context.beginPath();
context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.closePath(); //封闭路径后最后一个点就不用定义了
context.stroke();
绘制矩形
定义矩形:context.rect(x,y,w,h);
- x:起始位置x坐标(矩形左上角)
- y:起始位置y坐标(矩形左上角)
- w:矩形宽
- h:矩形高
直接绘制:省去了定义矩形的步骤,按照定义的样式直接填充或描边
context.fillRect(x,y,w,h)
context.strokeRect(x,y,w,h)
橡皮擦功能:clearRect(x,y,w,h)
- 擦除矩形范围之内的内容
- 常用来擦除整个画布以实现动画效果
图形绘制方式
边框式绘制:
context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();
填充式绘制:
context.fillStyle = 'yellow';
context.rect(150,150,200,100);
context.fill();
填充+描边同时使用注意:
这两个效果同时使用时,先后顺序的不同会导致效果的差异
一般是在填充后再去描边,如下效果
context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.fill();
context.stroke();
如果是描边后再填充的话,填充效果会遮挡一半的边框
//线宽被遮挡一半
context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();
context.fill();
绘制弧形
常用方法:context.arc(x,y,r,θ1,θ2,boolean)
- x:中心点x坐标
- y:中心点y坐标
- r:圆半径
- θ1:起始角度
- θ2:结束角度
- 布尔值:false逆时针(默认),true顺时针
//画弧线
context.strokeStyle = "red";
context.lineWidth = 2;
context.arc(300,100,100,0,Math.PI/2,true)
context.stroke();
//画圆
context.beginPath();
context.arc(300,200,100,0,Math.PI*2,true)
context.stroke();
绘制文字
设置文字样式:context.font = 'italic size family'
- italic:斜体
- size:字体大小
- family:字体
设置文字内容:context.strokeText("text",x,y)
- "text":中文字内容
- x:起始x坐标
- y:起始y坐标
context.lineWidth = 1;
context.strokeStyle = "green";
context.font = "italic 150px arial"
context.strokeText("我是文字",50,200);
渐变样式
线性渐变:createLinearGradient(x1,y1,x2,y2)
- x1/y1:渐变起始位置坐标
- x2/y2:渐变结束位置坐标
径向渐变:createRadiusGradient(x1,y1,r1,x2,y2,r2)
- x1/y1:渐变起始圆的圆心位置坐标
- r1:渐变起始圆半径
- x2/y2:渐变结束圆的圆心位置坐标
- r2:渐变结束圆半径
渐变颜色设置:addColorStop(%,"color");
- %:渐变进度,用[0,1]之间的数字表示
- "color":每个渐变阶段的颜色
var linearGradient = context.createLinearGradient(100,300,800,500);
linearGradient.addColorStop(0,"red");
linearGradient.addColorStop(0.4,"yellow");
linearGradient.addColorStop(0.8,"green");
linearGradient.addColorStop(1,"blue");
context.fillStyle = linearGradient;
context.font = "italic 150px arial"
context.fillText("我是文字",50,200);
绘制阴影
阴影颜色:shadowColor = "color";
阴影模糊度:shadowblur = number;
阴影偏移X:shadowOffsetX = number;
阴影偏移Y:shadowOffsetY = number;
context.shadowColor = "black";
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 5;
context.strokeRect(100,100,100,100);
坐标变换
相关例子可以看我的另一篇博客canvas钟表效果
坐标系平移:translate(x,y)
- 即是将坐标系的00点变换到(x,y)位置
坐标系旋转:rotate(θ)
- 将坐标系旋转θ度
- θ > 0时顺时针旋转,θ < 0时逆时针旋转
坐标系缩放:scale(x,y)
- 将坐标系x方向放大x倍
- 将坐标系y方向放大y倍
注意:因为坐标系在经过变换之后,之后重新绘制的图形都会以这个新的坐标系为参考;所以在绘制的时候会非常的麻烦
解决方案如下:
save()
:保存当前坐标系
restore()
:读取保存的坐标系
- 每次在进行坐标系变换之前,先使用
save()
将原始坐标系保存下来 - 在进行变换之后,再使用
restore()
将坐标系恢复为初始坐标系 - 每个
restore()
对应相应的一个save()
,所以在全局中保存一次随后无限restore()
的做法是无效的
绘制贝塞尔曲线/二次曲线
相关例子可以看我另一篇博客canvas随拖动变化的贝塞尔曲线
先用moveTo(x,y)设置起始点坐标
贝塞尔曲线:bezierCurveTo(cpx1,cpy1,cpx2,cpy2,dx,dy)
- cpx1/xpy1:控制点1坐标
- cpx2/xpy2:控制点2坐标
- dx/dy:终点坐标
二次曲线quadraticCurveTo(cpx,cpy,dx,dy)
- cpx/xpy:控制点坐标
- dx/dy:终点坐标
context.beginPath();
context.moveTo(300,100);
//贝塞尔曲线
context.bezierCurveTo(200,100,300,300,200,300);
context.stroke()
//二次曲线
context.moveTo(300,300);
context.quadraticCurveTo(400,150,500,300);
context.stroke();