javascript基础学习系列四百六十八:2D绘制图像

把原点移动到(100, 100),也就是表盘的中心后,要绘制表针只需简单的数学计算即可。这是因为所 有计算都是基于(0, 0),而不是(100, 100)了。当然,也可以使用 rotate()方法来转动表针:

let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas> 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.translate(100, 100);
// 旋转表针 context.rotate(1);
// 绘制分针 context.moveTo(0, 0); context.lineTo(0, -85);
// 绘制时针 context.moveTo(0, 0); context.lineTo(-65, 0);
// 描画路径 context.stroke();

     }

因为原点已经移动到表盘中心,所以旋转就是以该点为圆心的。这相当于把表针一头固定在表盘中 心,然后向右拨了一个弧度。结果所有这些变换,包括 fillStyle 和 strokeStyle 属性,会一直保留在上下文中,直到再次修改 它们。虽然没有办法明确地将所有值都重置为默认值,但有两个方法可以帮我们跟踪变化。如果想着什 么时候再回到当前的属性和变换状态,可以调用 save()方法。调用这个方法后,所有这一时刻的设置 会被放到一个暂存栈中。保存之后,可以继续修改上下文。而在需要恢复之前的上下文时,可以调用 28

restore()方法。这个方法会从暂存栈中取出并恢复之前保存的设置。多次调用 save()方法可以在暂 存栈中存储多套设置,然后通过 restore()可以系统地恢复。下面来看一个例子:

context.fillStyle = "#ff0000";
context.save();
context.fillStyle = "#00ff00";
context.translate(100, 100);
context.save();
context.fillStyle = "#0000ff";
context.fillRect(0, 0, 100, 200);
context.restore();
context.fillRect(10, 10, 100, 200);
context.restore();
context.fillRect(0, 0, 100, 200);
// 在(100, 100)绘制蓝色矩形
// 在(100, 100)绘制绿色矩形
// 在(0, 0)绘制红色矩形

以上代码先将 fillStyle 设置为红色,然后调用 save()。接着,将 fillStyle 修改为绿色,坐 标移动到(100, 100),并再次调用save(),保存设置。随后,将fillStyle属性设置为蓝色并绘制一 个矩形。因为此时坐标被移动了,所以绘制矩形的坐标实际上是(100, 100)。在调用 restore()之后, fillStyle 恢复为绿色,因此这一次绘制的矩形是绿色的。而绘制矩形的坐标是(110, 110),因为变换 仍在起作用。再次调用 restore()之后,变换被移除,fillStyle 也恢复为红色。绘制最后一个矩形 的坐标变成了(0, 0)。
注意,save()方法只保存应用到绘图上下文的设置和变换,不保存绘图上下文的内容。

绘制图像

2D 绘图上下文内置支持操作图像。如果想把现有图像绘制到画布上,可以使用 drawImage()方法。 这个方法可以接收 3 组不同的参数,并产生不同的结果。最简单的调用是传入一个 HTML 的元素, 以及表示绘制目标的 x 和 y 坐标,结果是把图像绘制到指定位置。比如:

   let image = document.images[0];
    context.drawImage(image, 10, 10);

以上代码获取了文本中的第一个图像,然后在画布上的坐标(10, 10)处将它绘制了出来。绘制出来的 图像与原来的图像一样大。如果想改变所绘制图像的大小,可以再传入另外两个参数:目标宽度和目标 高度。这里的缩放只影响绘制的图像,不影响上下文的变换矩阵。比如下面的例子:

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

执行之后,图像会缩放到 20 像素宽、30 像素高。
还可以只把图像绘制到上下文中的一个区域。此时,需要给 drawImage()提供 9 个参数:要绘制 的图像、源图像 x 坐标、源图像 y 坐标、源图像宽度、源图像高度、目标区域 x 坐标、目标区域 y 坐标、 目标区域宽度和目标区域高度。这个重载后的 drawImage()方法可以实现最大限度的控制,比如:

   context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60);

最终,原始图像中只有一部分会绘制到画布上。这一部分从(0, 10)开始,50 像素宽、50 像素高。而 绘制到画布上时,会从(0, 100)开始,变成 40 像素宽、60 像素高。

第一个参数除了可以是 HTML 的元素,还可以是另一个元素,这样就会把另一个 画布的内容绘制到当前画布上。
结合其他一些方法,drawImage()方法可以方便地实现常见的图像操作。操作的结果可以使用 toDataURL()方法获取。不过有一种情况例外:如果绘制的图像来自其他域而非当前页面,则不能获取 其数据。此时,调用 toDataURL()将抛出错误。比如,如果来自 www.xxx.com 的页面上绘制的是 来自 www.xxx.com 的图像,则上下文就是“脏的”,获取数据时会抛出错误。

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值