js 动画与Canvas 图形

《JavaScript高级程序设计》读书笔记

requestAnimationFrame

 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。

cancelAnimationFrame 取消重绘任务

let requestID = window.requestAnimationFrame(() => {
    console.log('Repaint!');
});
window.cancelAnimationFrame(requestID);

节流

let enabled = true;
function expensiveOperation() {
    console.log('Invoked at', Date.now());
}
window.addEventListener('scroll', () => {
    if (enabled) {
        enabled = false;
        window.requestAnimationFrame(expensiveOperation);
        window.setTimeout(() => enabled = true, 50);
    }
});

画布功能

坐标原点在左上角

  • getContext() 方法获取对绘图上下文的引用
  • toDataURL() 导出<canvas> 元素上的图像,接受一个参数:要生成图像的MIME类型
  • fillStyle:填充
  • strokeStyle:描边

1. 绘制矩形

这3个方法都接收 4 个参数:矩形 x 坐标、矩形 y 坐标、矩形宽度和矩形高度。单位:像素。

  • fillRect() 方法用于以指定颜色在画布上绘制并填充矩形。填充的颜色使用 fillStyle 属性指定
  • strokeRect() 方法使用通过 strokeStyle 属性指定的颜色绘制矩形轮廓
  • clearRect() 方法擦除画布中某个区域
let drawing = document.getElementById("drawing");
  if(drawing.getContext){
    let context = drawing.getContext("2d");
    context.fillStyle = '#0000ff';
    context.fillRect(10, 10, 50, 50);
    context.fillStyle = 'rgba(0,0,255,0.5)';
    context.fillRect(80, 10, 10, 50);

    context.strokeStyle = "red";
    context.strokeRect(10, 10, 50, 50);
    
    context.clearRect(40, 40, 10, 10);

    let imgUrl = drawing.toDataURL("image/png");
    let image = document.createElement("img");
    image.src = imgUrl;
    document.body.appendChild(image);
  }

2. 绘制路径

首先调用 beginPath()方法表示要开始绘制新路径。然后调用下列方法绘制路径:

  • arc(x, y, radius, startAngle, endAngle, counterclockwise):以坐标(x, y)为圆心,以 radius 为半径绘制一条弧线,起始角度为 startAngle,结束角度为 endAngle。counterclockwise 表示是否逆时针计算起始角度和结束角度(默认为顺时针)。
  • arcTo(x1, y1, x2, y2, radius):以给定半径 radius,经由(x1, y1)绘制一条从上一点到(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)。
  • quadraticCurveTo(cx, cy, x, y):以(cx, cy)为控制点,绘制一条从上一点到(x, y)的弧线(二次贝塞尔曲线)。
  • rect(x, y, width, height):以给定宽度和高度在坐标点(x, y)绘制一个矩形。这个方法与 strokeRect()和 fillRect()的区别在于,它创建的是一条路径,而不是独立的图形

创建路径之后,可以使用closePath() 方法绘制一条返回起点的线。如果路径完成,则可以指定 fillStyle 属性并调用 fill()方法来填充路径,也可以指定 strokeStyle 属性并调用stroke()方法来描画路径,还可以调用 clip()方法基于已有路径创建一个新剪切区域。

isPointInPath(x, y) 方法用于确定指定的点是否在路径上,可以在关闭路径前随时调用

 let drawing = document.getElementById("drawing");
  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(100, 15);

    context.moveTo(100, 100);
    context.lineTo(35, 100);
    context.stroke();
  }

3. 绘制文本

接收 4 个参数:要绘制的字符串、 x 坐标、 y 坐标和可选的最大像素宽度

  • fillText()
  • strokeText()

这两个方法最终绘制的结果都取决于以下 3 个属性:

  • font:以 CSS 语法指定的字体样式、大小、字体族等,比如"10px Arial"。
  • textAlign:指定文本的对齐方式,包括"start"、 "end"、 "left"、 "right"和"center"。推荐使用"start"和"end"。
  • textBaseLine:指定文本的基线,包括"top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom"。

measureText(str):检查字体宽度

let drawing = document.getElementById("drawing");
if(drawing.getContext){
  let context = drawing.getContext("2d");
  context.font = "bold 14px Arial";
  context.textAlign = "center";
  context.fillStyle = "red";
  context.fillText("Hello", 100, 20);
  console.log(context.measureText("Hello"))
}

4. 变换

  • 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):  替换绘图的当前转换矩阵。
  • setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):将当前转换重置为单位矩阵。然后运行 transform()。

5. 绘制图像

drawImage() 提供 9 个参数:要绘制的图像、源图像 x 坐标、源图像 y 坐标、源图像宽度、源图像高度、目标区域 x 坐标、目标区域 y 坐标、目标区域宽度和目标区域高度。

context.drawImage(image, 50, 10, 20, 30);

6. 阴影

  • shadowColor: CSS 颜色值,表示要绘制的阴影颜色,默认为黑色。
  • shadowOffsetX:阴影相对于形状或路径的 x 坐标的偏移量,默认为 0。
  • shadowOffsetY:阴影相对于形状或路径的 y 坐标的偏移量,默认为 0。
  • shadowBlur:像素,表示阴影的模糊量。默认值为 0,表示不模糊。

7. 渐变

  • createLinearGradient()方法:创建线性渐变,接收 4 个参数:起点 x 坐标、起点 y 坐标、终点 x 坐标和终点 y 坐标。创建一个新的 CanvasGradient对象并返回实例
  • createRadialGradient()方法:径向渐变(或放射性渐变),接收 6 个参数:渐变的开始圆的 x 坐标、渐变的开始圆的 y 坐标、开始圆的半径、渐变的结束圆的 x 坐标、渐变的结束圆的 y 坐标、结束圆的半径
  • addColorStop()方法:渐变指定色标,接收两个参数:色标位置和 CSS 颜色字符串
let gradient = context.createLinearGradient(30, 30, 70, 70);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");

 8. 图案

  • createPattern()方法并传入两个参数:一个 HTML <img>元素和一个表示该如何重复图像的字符串("repeat"、 "repeat-x"、 "repeat-y"和"no-repeat")。
let image = document.images[0],
pattern = context.createPattern(image, "repeat");

9. 图像数据

  • getImageData()方法获取原始图像数据。这个方法接收 4 个参数:开始复制的左上角位置的x 坐标和y 坐标,要取得区域的宽度和高度。返回的对象是一个 ImageData 的实例,包含 3 个属性: width、 height 和 data(图像的原始像素信息的数组)。
  • putImageData()方法:把图像数据再绘制到画布上
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(10,10,50,50);
function copy(){
	var imgData=ctx.getImageData(10,10,50,50);
	ctx.putImageData(imgData,10,70);
}

10. 合成

  • globalAlpha:设置或返回绘图的当前 alpha 或透明值。context.globalAlpha = 0.5
  • globalCompositeOperation:设置或返回新图像如何绘制到已有的图像上。context.globalCompositeOperation="destination-over";
    • source-over:默认值,新图形绘制在原有图形上面。
    • source-in:新图形只绘制出与原有图形重叠的部分,画布上其余部分全部透明。
    • source-out:新图形只绘制出不与原有图形重叠的部分,画布上其余部分全部透明。
    • source-atop:新图形只绘制出与原有图形重叠的部分,原有图形不受影响。
    • destination-over: 新图形绘制在原有图形下面,重叠部分只有原图形透明像素下的部分可见。
    • destination-in:新图形绘制在原有图形下面,画布上只剩下二者重叠的部分,其余部分完全透明。
    • destination-out:新图形与原有图形重叠的部分完全透明,原图形其余部分不受影响。
    • destination-atop:新图形绘制在原有图形下面,原有图形与新图形不重叠的部分完全透明。
    • lighter:新图形与原有图形重叠部分的像素值相加,使该部分变亮。
    • copy:新图形将擦除并完全取代原有图形。
    • xor:新图形与原有图形重叠部分的像素执行“异或”计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天巨兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值