动画与Canvas图形
文章目录
一、使用requestAnimationFrame
1.requestAnimationFrame
requestAnimationFrame()方法接收一个参数,此参数是一个要在重回屏幕前调用的函数。这个函数就是修改DOM样式以反映下一次重绘有什么变化的地方。
代码如下(示例):
function updateProgress(){
var div=document.getElementById("status");
div.style.width=(parseInt(div.style.width,10)+5)+"%";
if(div.style.left!=100%){
requestAnimationFrame(updateProgress);
}
}
requestAnimationFrame(updateProgress);
2.cancelAnimationFrame
cancleAnimationFrame()取消重绘任务。
代码如下(示例):
let requestIP=window.requestAnimationFrame(()=>{
console.log('Repaint!');
});
window.cancleAnimationFrame(requestID);
二、基本的画布功能
getContext()方法可以获取对绘图上下的引用。对于平面图形,需要给这个方法传入参数“2d”,表示要获取2D上下文对象。
代码如下(示例):
let drawing=document.getElementById("drawing");
//确保浏览器支持<canvas>
if(drawing.getContext){
let context=drawing.getContext("2d");
//其他代码
}
toDataURL()方法可以导出<canvas>元素上的图像。这个方法接收一个参数:要生成图像的MIME类型(与用来创建图形的上下文无关)。
代码如下(示例):
let drawing=document.getElementById("drawing");
if(drawing.getContext){
//取得图形的数据URI
let imgURI=drawing.toDataURL("image/png");
//显示图片
let image=document.createElement("img");
image.src=imgURI;
document.body.appendChild(image);
}
三、2D绘图上下文
1.填充和描边
fillStyle()填充以指定样式(颜色、渐变或图像)自动填充形状,而strokeStyle描边只为图形边界着色。
2.绘制矩形
与绘制矩形相关的方法有三个:fillRect(),strokeRect(),clearRect()。这些方法都接收4个参数:矩形x坐标、矩形y坐标、矩形宽度和矩形高度。
代码如下(示例):
let drawing=document.getElementById("ex1");
if(drawing.getContext){
let context=drawing.getContext("2d");
//绘制红色矩形
context.fillStyle="#ff0000";
context.fillRect(10,10,50,50);
//绘制半透明蓝色矩形
context.fillStyle="rgba(0,0,255,0.5)";
context.fillRect(30,30,50,50);
}
代码如下(示例):
let draw=document.getElementById("draw");
if(draw.getContext){
let content=draw.getContext("2d");
content.strokeStyle="#ff0000";
content.strokeRect(10,10,50,50);
content.strokeStyle="rgba(0,0,255,0.5";
content.strokeRect(30,30,50,50);
}
代码如下(示例):
let drawing=document.getElementById("drawing");
if(drawing.getContext){
let context=drawing.getContext("2d");
context.fillStyle='#ff0000';
context.fillRect(10,10,50,50);
context.fillStyle="rgba(0,0,255,0.5";
context.fillRect(30,30,50,50);
context.clearRect(40,40,10,10);
}
3.绘制路径
2D绘图上下文支持很多在画布上绘制路径的方法。通过路径可以创建复杂的形状和线条。要绘制路径,必须先调用beginPath()方法以表示要开始绘制新路径。然后再调用下列方法来绘制路径。调用closePath()方法以结束绘制。
- arc(x,y,radius,startAngle,endAngle,counterclockwise):以坐标(x,y)为圆心,以radius为半径绘制一条弧线,起始角度为startAngle,结束角度为endAngle(都是弧度)。最后一个参数counterclockwise表示是否逆时针计算起始角度和结束角度。
- arcTo(x1,y1,x2,y2,radius):以给定半径radius,经由(x1,x2)绘制一条从上一点到(x2,y2)的弧线。
- bezierCurveTo(c1x,c1y,c2x,c2y,x,y):以(c1x,c1y)和(c2x,c2y)为控制点,绘制一条从上一点到(x,y)的弧线(三次贝塞尔曲线)。
- lineTo(x,y):绘制一条从上一点到(x,y)的直线。
- moveTo(x,y):不绘制线条,只把绘制光标移动到(x,y)。
- quardraticCurveTo(cx,cy,x,y):以(cx,cy)为控制点,绘制一条从上一点到(x,y)的弧线(二次贝塞尔曲线)。
- rect(x,y,width,height):以给定宽度和高度在坐标点(x,y)绘制一个矩形。这个方法与strokeRect()和fillRect()的区别在于,它创建的是一条路径,而不是独立的图形。
代码如下(示例):
let drawing=document.getElementById("drawing");
//在style里设置会导致伸缩
drawing.width=500;
drawing.height=500;
if(drawing.getContext){
let context=drawing.getContext("2d");
//创建路径
context.beginPath();
//绘制外圆
context.arc(100,100,99,0,2*Math.PI,false);
//绘制内圆
context.moveTo(194,100);
context.arc(100,100,94,0,2*Math.PI,false);
//绘制时针
context.moveTo(100,100);
context.lineTo(35,100);
//绘制分针
context.moveTo(100,100);
context.lineTo(100,15);
//描画路径
context.stroke();
}
4.绘制文本
2D绘图上下文还提供了绘制文本的方法,即fillText()和strokeText()。这两个方法都接收4个参数:要绘制的字符串、x坐标、y坐标和可选的最大像素宽度。这两个方法最终绘制的结果都取决于以下3个属性:
- font:以CSS语法指定的字体样式、大小、字体族等。
- textAlign:指定文本的对齐方式。
- textBaseLine:指定文本的基线。
代码如下(示例):
context.font="bold 14px Arial";
context.textAlign="center";
context.textBaseLine="middle";
context.fillText("12",100,20);
measureText()方法接收一个参数,即要绘制的文本,然后返回一个TextMetrics对象。这个返回的对象目前只有一个width属性。
5.变换
以下方法可以用于改变绘制上下文的变换矩阵:
- rotate(angle):围绕原点把图像选择angle弧度。
- scale(scaleX,scaleY):通过在x轴乘以scaleX、在y轴乘以scaleY来缩放图像。scaleX和scaleY的默认值是1.0。
- translate(x,y):把原点移动到(x,y)。执行这个操作后,坐标(0,0)就会变成(x,y)。
- transform(m1_1,m1_2,m2_1,m2_2,dx,dy):像下面这样通过矩阵乘法直接修改矩阵。
m1_1 m1_2 dx
m2_1 m2_2 dy
0 0 1
-setTransform(m1_1,m1_2,m2_1,m2_2,dx,dy):把矩阵重置为默认值,再以传入的参数调用transform()。
6.绘制图像
drawImage()方法可以把现有的图像绘制到画布上。这个方法接收3组不同的参数,并产生不同的结果。还可以给drawImage()提供9个参数:要绘制的图像、源图像x坐标、源图像y坐标、源图像宽度、源图像高度、目标区域x坐标、目标区域y坐标、目标区域宽度和目标区域高度。
代码如下(示例):
let image=document.image[0];
context.drawImage(image,10,10);
7.阴影
2D上下文可以根据以下属性的值自动为已有形状或路径生成阴影。
- shadowColor:CSS颜色值,表示要绘制的阴影颜色,默认为黑色。
- shadowOffsetX:阴影相对于形状或路径的x坐标的偏移量,默认为0。
- shadowOffsetY:阴影相对于形状或路径的y坐标的偏移量,默认为0。
- shadowBlur:像素,表示阴影的模糊量。默认值为0,表示不模糊。
代码如下(示例):
let context=drawing.getContext("2d");
//绘制阴影
context.shadowOffsetX=5;
context.shadowOffsetY=5;
context.shadowBlur=4;
context.shadowColor="rgba(0,0,0,0.5)";
//绘制红色矩形
context.fillStyle="#ff0000";
context.fillRect(10,10,50,50);
//绘制蓝色矩形
context.fillStyle="rgba(0,0,255,1)";
context.fillRect(30,30,50,50);
8.渐变
createLinearGradient()方法接收4个参数:起点x坐标、起点y坐标、终点x坐标、终点y坐标。addColorStop()方法为渐变指定色标。这个方法接收两个参数:色标位置和CSS颜色字符串。色标位置通过0-1范围内的值表示,0是第一种颜色,1是最后一种颜色。
代码如下(示例):
let drawing=document.getElementById("drawing");
let context=drawing.getContext("2d");
let gradient=context.createLinearGradient(30,30,70,30);
gradient.addColorStop(0,"lightpink");
gradient.addColorStop(1,"lightblue");
context.fillStyle='#ff0000';
context.fillRect(10,10,50,50);
context.fillStyle=gradient;
context.fillRect(30,30,50,50);
createRadialGradient()方法接收6个参数:前3个参数指定其电源线中心的x、y坐标和半径,后3个参数指定终点圆形中心的x、y坐标和半径。
代码如下(示例):
let drawing=document.getElementById("drawing");
let context=drawing.getContext("2d");
let gradient=context.createRadialGradient(55,55,5,55,55,30);
gradient.addColorStop(0,"white");
gradient.addColorStop(1,"black");
context.fillStyle='#ff0000';
context.fillRect(10,10,50,50);
context.fillStyle=gradient;
context.fillRect(30,30,50,50);
9.图案
图案是用于填充和描画图形的重复图像。createPattern()方法传入两个参数:一个HTML<img>元素和一个表示该如何重复图像的字符串。第二个参数的值与CSS的background-repeat属性是一样的。
代码如下(示例):
let image=document.image[0],
pattern=context.createPattern(image,"repeat");
//绘制矩形
context.fillStyle=pattern;
context.fillRect(10,10,150,150);
10.图像数据
getImageData()方法可以获取原始图像数据,这个方法接收4个参数:要取得数据中第一个像素的左上角坐标和要取得的像素高度和宽度。
11.合成
2D上下文中绘制的所有内容都会应用两个属性:alobalAlpha和globalComposition Operation。globalAlpha属性是一个范围在0~1的值,用于指定所有绘制内容的透明度。
globalCompositionOperation属性表示新绘制的形状热河与想下文中已有的形状融合。这个属性是一个字符串,可以取下列值。
- source-over:默认值,新图像绘制在原有图形上面。
- source-in:新图像只绘制出与原有图像重叠的部分,画布上其余部分全部透明。
- source-out:新图像只绘制出不与原有图像重叠的部分,画布上其余部分全部透明。
- source-atop:新图像只绘制出与原有图像重叠的部分,原有图形不受影响。
- destination-over:新图像绘制在原有图形下面,重叠部分只有原图形透明像素下的部分可见。
- destination-in:新图像绘制在原有图形下面,画布上只剩下二者重叠的部分,其余部分完全透明。
- destination-out:新图形与原有图形重叠的部分完全透明,原图形其余部分不受影响。
- destination-atop:新图形绘制在原有图形下面,原有图形与新图形不重叠的部分完全透明。
- lighter:新图形与原有图形重叠部分的像素值相加,使该部分变亮。
- copy:新图形将擦除并完全取代原有图形。
- xor:新图形与原有图形重叠部分的像素执行“异或”计算。
四、WebGL
1.WebGL基础
可以在调用getContext()取得WebGL上下文时指定一些选项。这些选项通过一个参数对象传入,选项就是参数对象的一个或多个属性。
- alpha:布尔值,表示是否为上下文创建透明通道缓冲区,默认为true。
- depth:布尔值,表示是否使用16位深缓冲区,默认为true。
- stencil:布尔值,表示是否使用8位模板缓冲区,默认为false。
- antialias:布尔值,表示是否使用默认机制执行抗锯齿操,默认为true。
- premultipliedAlpha:布尔值,表示绘图缓冲区是否预乘透明度值,默认为true。
- preserveDrawingBuffer:布尔值,表示绘图完成后是否保留绘图缓冲区,默认为false。