语义化标签
canvas
canvas标签
<canvas id="canvas">你的浏览器不支持canvas!</canvas>
获取canvas容器
var can = document.getElementById(‘canvas’);
获取容器的宽和高度
var canWid = can.width; //canvas 的宽度
var canHei = can.height; //canvas 的高度
创建一个画布
var ctx = can.getContext('2d');
设置画布宽度
ctx.lineWidth = 2; //线条宽度
边框矩形,默认1px 黑色
ctx.strokeRect(x, y, width, height);
<!--x, y是横纵坐标,原点在canvas的左上角-->
清除指定的矩形区域,变为透明
++设置fillStyle属性可以是CSS颜色,渐变,或图案。fillStyle 默认设置是#000000(黑色)++
ctx.clearRect(x, y, width, height);
<!--x, y是横纵坐标,原点在canvas的左上角;
绘制动态效果时,常用来清除整个画布-->
绘制线条
moveTo(x,y) 定义线条开始坐标
lineTo(x,y) 定义线条结束坐标
绘制线条我们必须使用到 "ink" 的方法,就像stroke()
<!--路径(线)的起点-->
ctx.moveTo(0,0);
<!--线的终点-->
ctx.lineTo(200,100);
ctx.stroke();
线段端点显示的样式
ctx.lineCap = 'butt(默认)'、'round(圆弧)'、'square(方形)'
两线段连接处所显示的样式
ctx.lineJoin = 'miter(默认)'、round(圆角)、`bevel(横线)`
虚线
ctx.setLineDash([4, 2]) //设置虚线,参数为数组,第一个值为实现宽度,第二个值为空白的宽度
ctx.lineDashOffset = 0; //虚线起始偏移量
例如
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var offset = 0;
function draw() {
offset++;
if (offset > 16) {
offset = 0;
}
ctx.clearRect(0,0, can.width, can.height);
ctx.setLineDash([6, 2]);
ctx.lineDashOffset = -offset;
ctx.strokeRect(10,10, 100, 100);
}
setInterval(draw, 20);
绘制圆形
arc(x,y,r,start,stop)
绘制圆形时使用了 "ink" 的方法, 比如
stroke() 【通过线条绘制轮廓(边框)】或者 fill()【通过路径填充区域(实心)】
<!--beginPath是绘制新图形的开始-->
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
//通过线条绘制轮廓(边框)
ctx.stroke();
绘制弧线
//当前端点、(x1,y1)和(x2,y2)这三个点连成的弧线,r是半径
ctx.arcTo(x1, y1, x2, y2, r);
//闭合路径,不是必须的,如果线的终点跟起点一样,会自动闭合。
ctx.closePath()
住:
1.fill()和stroke()函数表示绘图结束。如果要继续绘制,需要重新新建路径(beginPath())。
2.如果lineTo()最后的路径没有封闭,fill()函数会自动封闭路径,而stroke()函数不会。
绘制三角形
ctx.beginPath();
ctx.moveTo(75, 50); //路径起点
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill(); //自动将路径闭合,并默认填充黑色。
填充颜色
ctx.fillStyle="#FF0000";
填充矩形
ctx.fillRect(x, y, width, height);
<!--x, y是横纵坐标,原点在canvas的左上角-->
canvas 绘制文本
font - 定义字体
fillText(text,x,y) —— 在 canvas 上绘制实心的文本
strokeText(text,x,y) —— 在 canvas 上绘制空心的文本
ctx.shadowOffsetX = 2; //X轴阴影距离,负值表示往上,正值表示往下
ctx.shadowOffsetY = 2; //Y轴阴影距离,负值表示往左,正值表示往右
ctx.shadowBlur = 2; //阴影的模糊程度
ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; //阴影颜色
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);
<!--ctx.strokeText("Hello World",10,50);-->
还有以下一些属性
ctx.font = '20px Times New Roman';
ctx.textAlign = 'center'; //start, end, left, right or center
ctx.textBaseline = 'middle' //top, hanging, middle, alphabetic, ideographic, bottom
ctx.direction = 'inherit' //ltr, rtl, inherit
渐变
- createLinearGradient(x,y,x1,y1) - 线性渐变
// 创建渐变
var grd=ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
- createRadialGradient(x,y,r,x1,y1,r1) - 径向渐变
// 创建渐变
var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
图像
drawImage(image,x,y)
var img=document.getElementById("scream");
ctx.drawImage(img, 0, 0[,w, h]); //w、h指定图片的宽高,则会同比例缩放
变形
状态
save()用来保存当前状态,restore()用来恢复刚才保存的状态。他们都可以多次调用。
ctx.fillStyle = 'black';
ctx.fillRect(20, 20, 150, 150);
ctx.save(); //保存当前状态
ctx.fillStyle= '#fff';
ctx.fillRect(45, 45, 100, 100);
ctx.restore(); //恢复到刚才保存的状态
ctx.fillRect(70, 70, 50, 50);
位移(translate)
ctx.translate(x, y); //更改canvas的原点
var ctx = document.getElementById('canvas').getContext('2d');
for(var i = 1; i< 4; i++) {
ctx.save(); //使用save方法保存状态,让每次位移时都针对(0,0)移动。
ctx.translate(100*i, 0);
ctx.fillRect(0, 50, 50, 50);
ctx.restore();
}
旋转
ctx.rotate(Math.PI * 2) //参照原点顺时针旋转360度
ctx.translate(75,75); //把原点移动到(75, 75);
for (var i=1; i<6; i++){ // 从里到外一共6圈
ctx.save();
ctx.fillStyle = 'rgb('+(50*i)+','+(255-50*i)+',255)';
for (var j=0; j<i*6; j++){ // 每一圈有i*6个圆点
ctx.rotate(Math.PI*2/(i*6));
ctx.beginPath();
ctx.arc(0,i*12.5,5,0,Math.PI*2,true); //false = 顺时针,true = 逆时针。
ctx.fill();
}
ctx.restore();
}
缩放
ctx.scale(x, y); //基于原点缩放,x、y是两个轴的缩放倍数
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'red';
ctx.scale(0.8, 1.2);
ctx.beginPath();
ctx.arc(75, 75, 60, 0, Math.PI * 2);
ctx.fill();
动画
- setInterval(myFun, 10);
意思是隔一毫秒执行一个myFun函数,但是这样就有一个问题了,比如我myFun函数里面绘制的东西比较耗时,而10ms之内还没有完全绘制出来,但是这段代码强制1ms之后又开始绘制下一帧了,所以就会出现丢帧的问题;反之,如果时间设置太长,就会出现画面不流畅、视觉卡顿的问题.
- requestAnimationFrame(myFun);
根据一定的时间间隔,会自动执行myFun函数来进行绘制。这个”一定的时间间隔”就是根据浏览器的性能或者网速快慢来决定了,总之,它会保证你绘制完这一帧,才会绘制下一帧,保证性能的同时,也保证动画的流畅。