不考虑代码质量的话,一般来说css3>canvas>纯js。
1. css3动画是独立与js线程的,js的运算操作不会阻塞css3的动画,所以在系统cpu占用率较高的时候,css3的动画性能要明显高于纯js的动画。
2. 纯js,请注意“纯”这个字,它的意思是js操作dom,而不是canvas。通过js操作dom实现的动画会引起浏览器的recalculate和layout,在移动设备上还会引起rasterize(栅格化),题主列出的三种动画比较,为什么说纯js的动画性能最低呢,原因就是纯js实现的动画不仅仅考验开发人员的js代码质量,而且随着动画复杂度的提高,被操作的dom数量的提高,相较于css3和canvas来说,纯js实现的动画性能越低。
3. canvas相对于纯js来说dom结构要简单很多,引起的recalculate和layout自然就少了很多,但canvas的动画仍然需要js代码驱动,占用js线程,所以,相较于css3来说,性能上仍然略逊一筹。
canvas 是画布, 也就是你可以动态更改图片的某一部分, 精确到 1 像素, div + css 的性能根本比不上 canvas, 你要去更改 div 的 style 才能出来效果, canvas 是浏览器的底层 api 帮你画, 不是一个等级
不管怎样,今天的主角是canvas,canvas画布提供的api内容还是挺丰富的。我们来慢慢学习:
//回绘制矩形
ctx.fillStyle = 'red'; //填充的样式
ctx.fillRect(10,10,100,100); //填充的形状是矩形
ctx.clearRect(15,15,50,50) ; //清除指定位置
ctx.strokeStyle = 'red'; //空心的矩形样式
ctx.strokeText('hello world',100,100); //绘制空心的矩形
// 判断某个点是不是在矩形内
ctx.rect(10,10,100,100);
alert(ctx.isPointInPath(10,10)); //isPointInPath某个点是不是在矩形内
//设置模糊效果
ctx.shadowBlur = 50; //模糊的程度
ctx.shadowColor = 'black'; //模糊的颜色
ctx.shadowOffsetX = 50; //水平方向偏移的位移
ctx.shadowOffsetX = 50; //垂直方向偏移的位移
ctx.shadowOffsetY = 50;
ctx.fillStyle = 'red'; //模糊矩形 填充的样式
ctx.fillRect(10,10,100,100) //填充的形状是矩形
ctx.font = '30px Microsoft YAHEI' ; //模糊字体效果
ctx.fillStyle = 'red';
ctx.fillText('hello',50,50);
//绘制线条
ctx.moveTo(0,0) //画线的起点位置坐标
ctx.lineTo(10,10); //画线的终点位置坐标
ctx.lineTo(100,50);
ctx.stroke(); // stroke() 方法来绘制线条
//线条接触端相撞
ctx.lineWidth = 10 //线条的宽度
ctx.lineCap = 'butt'; //默认。向线条的每个末端添加平直的边缘。
ctx.lineCap = 'round'; //加圆形线帽。
ctx.lineCap = 'square'; //加正方形线帽。
ctx.moveTo(10,10);
ctx.lineTo(100,10);
ctx.stroke();
//设置或返回两条线相交时,所创建的拐角类型。
ctx.lineWidth = 10;
ctx.lineJoin = 'round' //相交处是圆角
ctx.lineJoin = 'bevel' //相交处是斜角
ctx.lineJoin = 'miter' //相交处是默认直角
ctx.lineJoin="miter";
ctx.miterLimit=1; // 斜接长度指的是在两条线交汇处内角和外角之间的距离。不常用
ctx.moveTo(10,10);
ctx.lineTo(100,10);
ctx.lineTo(50,100);
ctx.closePath() ; //结束路径,从当前终点连接到起点
ctx.stroke();
//创建圆或部分圆
ctx.beginPath(); //开始画圆
ctx.arc(100,75,50,0,2*Math.PI); //设置圆的参数,圆心x坐标,y坐标,半径,起始弧度,结束弧度,逆时针还是顺时(可选)
ctx.arc(100,75,50,0,1*Math.PI); //设置圆的参数,圆心x坐标,y坐标,半径,起始弧度,结束弧度,逆时针还是顺时(可选)
ctx.stroke();
//创建两条直线的弧
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(100,50);
ctx.arcTo(150,50,150,150,50);
ctx.lineTo(150,150);
ctx.stroke();
//绘制文本
ctx.font="20px Microsoft YAHEI"; //定义字体和大小
ctx.fillText("省省回头车",50,50); //绘制实心字体
ctx.strokeText("省省回头车",50,50); //绘制空心字体
ctx.textAlign = 'center' //文本在指定位置的中间
ctx.textAlign = 'left' //文本在指定位置的左边
ctx.textAlign = 'right' //文本在指定位置的右边
ctx.textAlign = 'start' //文本在指定位置开始
ctx.textAlign = 'end' //文本在指定位置结束
ctx.fillText("textAlign=xxxx",100,100);
ctx.textBaseline="top"; //文本在指定位置
ctx.fillText("Top",5,100);
ctx.textBaseline="bottom";
ctx.fillText("Bottom",50,100);
ctx.textBaseline="middle";
ctx.fillText("Middle",120,100);
ctx.textBaseline="alphabetic";
ctx.fillText("Alphabetic",190,100);
ctx.textBaseline="hanging";
ctx.fillText("Hanging",290,100);
//计算文本的宽度
var text = "省省回头车"
ctx.fillText("width"+ctx.measureText(text).width,50,100);
//绘制渐变效果
var grd = ctx.createLinearGradient(0,0,200,0); //自定义样式grd,创建线性渐变
var grd=ctx.createRadialGradient(75,50,0,75,50,100); //创建径向渐变,参数(圆心x,圆心y,半径,结束圆的圆心的坐标x,y,结束圆的半径)
grd.addColorStop(0,'red'); //起始颜色 当我们使用渐变对象,必须使用两种或两种以上的停止颜色。
grd.addColorStop(0.5,'#fff'); //终点颜色 参数使用坐标来描述,可以是0-1
grd.addColorStop(1,'yellow'); //终点颜色 参数使用坐标来描述,可以是0-1
//绘制渐变矩形
ctx.fillStyle = grd; //用grd样式填充矩形
ctx.fillRect(10,0,150,100) //绘制矩形
//绘制渐变字体
ctx.font="30px Microsoft YAHEI"; //定义字体和大小
ctx.fillStyle=grd;
ctx.fillText("省省回头车",50,50); //绘制实心字体
ctx.strokeText("省省回头车",50,50); //绘制空心字体
//自定义模式
var pat = ctx.createPattern(img,'repeat');
var pat = ctx.createPattern(img,'repeat-x');
var pat = ctx.createPattern(img,'repeat-y');
var pat = ctx.createPattern(img,'no-repeat');
ctx.fillStyle=pat;
ctx.fillRect(10,10,150,150);
// 从原始画布中剪切任意形状和尺寸
ctx.rect(50,50,50,100);
ctx.stroke();
ctx.clip(); //实现剪切,超出以上矩形的位置的东西不显示
ctx.fillStyle = 'red';
ctx.fillRect(0,0,100,100)
//把图片放在canvas上
ctx.drawImage(img,0,0)
// 贝塞尔曲线
ctx.beginPath();
ctx.moveTo(100,100);
ctx.quadraticCurveTo(100,0,210,100); //二次贝塞尔曲线,一个控制点,一个终点
ctx.bezierCurveTo(150,150,200,50,250,100); //三次贝塞尔曲线,2个控制点,一个终点
ctx.stroke();
//sace进行缩放
ctx.scale(2,2) //如果您对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放。如果您 scale(2,2),那么绘图将定位于距离画布左上角两倍远的位置。
ctx.strokeRect(5,5,25,15);
//旋转当前绘制图形
ctx.rotate(10*Math.PI/180); //旋转的度数*Math.PI/180
ctx.strokeRect(50,50,100,50);
//translate()重新映射画布上的 (0,0) 位置。
ctx.fillRect(10,10,100,100);
ctx.translate(50,50)
ctx.fillRect(10,10,100,100);
//transform变换矩阵
ctx.fillStyle="yellow";
ctx.fillRect(0,0,250,100)
ctx.transform(1,0.5,-0.5,1,30,10); //参数分别是:水平缩放绘图,水平倾斜绘图,垂直倾斜绘图,垂直缩放绘图,水平移动绘图,垂直移动绘图
ctx.fillStyle="red";
ctx.fillRect(0,0,250,100);
ctx.transform(1,0.5,-0.5,1,30,10); //再次调用的时候会在上一个矩阵的基础上进行绘制
ctx.fillStyle="blue";
ctx.fillRect(0,0,250,100);
//setTransform变换矩阵 调用 setTransform会将上一个矩阵重置后再变换
ctx.fillStyle="yellow";
ctx.fillRect(0,0,250,100)
ctx.setTransform(1,0.5,-0.5,1,30,10); //参数分别是:水平缩放绘图,水平倾斜绘图,垂直倾斜绘图,垂直缩放绘图,水平移动绘图,垂直移动绘图
ctx.fillStyle="red";
ctx.fillRect(0,0,250,100);
ctx.setTransform(1,0.5,-0.5,1,30,10); //再次调用的时候会在上一个矩阵的基础上进行绘制
ctx.fillStyle="blue";
ctx.fillRect(0,0,250,100);
// ImageData
var imgData=ctx.createImageData(100,100); //创建新的空白 ImageData 对象
console.log(imgData.data.length);
for (var i=0;i { imgData.data[i+0]=0; imgData.data[i+1]=255; imgData.data[i+2]=0; imgData.data[i+3]=255; } ctx.putImageData(imgData,10,10); //使用 putImageData() 方法将图像数据拷贝回画布上 // globalAlpha透明度 ctx.globalAlpha=0.5; ctx.fillStyle = 'red'; ctx.fillRect(10,10,100,100) ; // globalCompositeOperation 属性设置或返回如何将一个源(新的)图像绘制到目标(已有的)的图像上。 // 源图像 = 您打算放置到画布上的绘图。 // 目标图像 = 您已经放置在画布上的绘图。 ctx.fillStyle="red"; ctx.fillRect(20,20,75,50); // 目标图像 ctx.globalCompositeOperation="source-over"; //源图像遮住目标图像。 ctx.globalCompositeOperation="source-atop"; //源图像遮住目标图像,超出的不可见 ctx.globalCompositeOperation="source-in"; //源图像遮住目标图像,目标图像不可见 ctx.globalCompositeOperation="source-out"; //源图像遮住目标图像,目标图像不可见,重叠的部分不可见 ctx.globalCompositeOperation="destination-over"; //目标图像遮住源图像, ctx.globalCompositeOperation="destination-atop"; //目标图像遮住源图像,目标图像不重叠的部分不可见 ctx.globalCompositeOperation="destination-out"; //目标图像遮住源图像,源图像不可见,目标图像重叠的部分不可见 ctx.globalCompositeOperation="lighter"; //重叠部分颜色叠加 ctx.globalCompositeOperation="copy"; //显示源图像。忽略目标图像。 ctx.globalCompositeOperation="xor"; //重叠部分颜色不可见 ctx.fillStyle="blue"; ctx.fillRect(50,50,75,50); // 源图像。