JS高级程序设计(18)

动画与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。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值