canvas
默认是300x150大小,可以在标签上直接设置宽高
复制代码
js获取canvas画布
var canvas = document.getElementById("myCanvas");复制代码
定义画笔
var ctx = canvas.getContext("2d");//画3d传webgl复制代码
通常3d的动画才会开启CPU加速,所以2d的图片我们也可以设置,translateZ,或者rotate来欺骗浏览器,获取CPU加速
moveTo
ctx.moveTo(100, 100);复制代码
定位画笔的初始位置
lineTo
ctx.lineTo(200, 200);复制代码
直线
一个简单的三角形,推荐最后一步用closePath()
ctx.moveTo(100, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 300); ctx.lineWidth = 10;//线的中间是基准线 ctx.strokeStyle = "red"; ctx.closePath();复制代码
ctx.stroke();//描边复制代码
ctx.fill();//填充,收尾点连接,填充内部复制代码
画笔的方法就相当于构图,这两个方法才是将构图显示在画布上,而且所有的fill和stroke都是作用在所有的子路径上的,也就是说如果你没有开启一个新的路径(beginPath),那么相同的方法就会被覆盖
ctx.beginPath()
开启一个新的路径,最好每个canvas前都加这句
ctx.clearRect(0, 0, w, h);
清除画布,矩形形式
ctx.beginPath(); ctx.rect(100, 100, 200, 100);//矩形,左上角(100, 100)开始,左200,高100,还有strokeRect() 和 fillRect() 方法,//且这两个方法自带beginPath功能 ctx.stroke(); //清除画布 var h = canvas.height, w = canvas.width; ctx.clearRect(0, 0, w, h); //ctx.clearRect(100, 100, 80, 80);复制代码
一个方块下落的demo
function animate(y) { ctx.beginPath();//注意没有beginPath的时候,变成柱状了 ctx.rect(50, y, 50, 50); ctx.fill(); // ctx.fillRect(50, y, 50, 50); } var timer = setInterval(function () { ctx.clearRect(0, 0, w, h); animate(y); y += 10 if(y >= 460) { animate(450) clearInterval(timer); } }, 100)复制代码
注意如果你用rect的话,要小心如果没有beginPath的话,你将得到一个柱状的长方形,这是因为clearRect只会清除stroke/fill这种画在画布上的图片,而你画笔的轨迹是不会清除的,所以每一个定时器都会stroke,最后得到的就是一个大的长方形。此外,注意如果下一次小方块运动到画布外的时候,我采取的是直接定位的方式,直接定位到画布底端。
ctx.arc(圆心x,圆心y,r, 起始弧度,末端弧度,顺逆时针)
ctx.arc(50, 50, 40, Math.PI/180*0, Math.PI/180*270, 0);//圆心,半径,弧度,0顺1逆 ctx.stroke();//这是一个扇形 ctx.moveTo(100, 200); ctx.lineTo(200, 200); ctx.arc(100, 200, 100, Math.PI/180 * 0, Math.PI/180 * 300, 1); ctx.lineTo(100, 200); ctx.stroke() ctx.moveTo(100, 240) ctx.arcTo(350, 240, 350, 400, 50); ctx.stroke();复制代码
0度在数学上笛卡尔坐标系x的正半轴上,角度的大小是顺时针绕x轴一圈0~360,采用弧度制,所以Math.PI/180*X来写入想要的大小
贝塞尔曲线
ctx.moveTo(200, 200); ctx.quadraticCurveTo(300, 100, 500, 500); //二次贝塞尔曲线 ctx.bezierCurveTo(300, 100,400, 400, 500, 500); //三次贝塞尔曲线 ctx.stroke(); 复制代码
画布内坐标系的改变
默认是一左上角为(0,0)点,但我们也可以改变,例如:
ctx.translate(200, 200);//平移坐标系 ctx.scale(2, 0.5)//缩放X轴和Y轴ctx.rotate(Math.PI/180 * 30);//旋转整个画布,(0,0)为圆心,正为顺时针,负为逆时针 复制代码
有时根据需要我们要来回切换坐标系,save方法可以保存坐标系,restore可以回到save保存的坐标系(但只能同时保存一种坐标系,所以我们通常保存原始坐标系,为了方便我们切换),比如下面这个例子:
ctx.save();//保存当前视图状态,只能保存一种状态 ctx.rotate(Math.PI/180 * 30);//旋转整个画布,30rad ctx.rect(100, 100, 50, 50); ctx.restore();//回到save的状态 ctx.rect(400, 400, 50, 50); ctx.fill();复制代码