javascript基础学习系列二百九十四:绘制图像

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.example.com 的页面上绘制的是 来自 www.wrox.com 的图像,则上下文就是“脏的”,获取数据时会抛出错误。

阴影

2D 上下文可以根据以下属性的值自动为已有形状或路径生成阴影。
 shadowColor:CSS 颜色值,表示要绘制的阴影颜色,默认为黑色。
 shadowOffsetX:阴影相对于形状或路径的 x 坐标的偏移量,默认为 0。
 shadowOffsetY:阴影相对于形状或路径的 y 坐标的偏移量,默认为 0。
 shadowBlur:像素,表示阴影的模糊量。默认值为 0,表示不模糊。
这些属性都可以通过 context 对象读写。只要在绘制图形或路径前给这些属性设置好适当的值,
阴影就会自动生成。比如:

   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);
// 绘制蓝色矩形 26 context.fillStyle = "rgba(0,0,255,1)";
context.fillRect(30, 30, 50, 50);

这里两个矩形使用了相同的阴影样式,得到了如图 18-10 所示的结果。

渐变通过 CanvasGradient 的实例表示,在 2D 上下文中创建和修改都非常简单。要创建一个新的 线性渐变,可以调用上下文的 createLinearGradient()方法。这个方法接收 4 个参数:起点 x 坐标、 起点 y 坐标、终点 x 坐标和终点 y 坐标。调用之后,该方法会以指定大小创建一个新的 CanvasGradient 对象并返回实例。
有了 gradient 对象后,接下来要使用 addColorStop()方法为渐变指定色标。这个方法接收两 个参数:色标位置和 CSS 颜色字符串。色标位置通过 0~1 范围内的值表示,0 是第一种颜色,1 是最后 一种颜色。比如:

   let gradient = context.createLinearGradient(30, 30, 70, 70);
    gradient.addColorStop(0, "white");
    gradient.addColorStop(1, "black");

这个gradient对象现在表示的就是在画布上从(30, 30)到(70, 70)绘制一个渐变。渐变的起点颜色 为白色,终点颜色为黑色。可以把这个对象赋给 fillStyle 或 strokeStyle 属性,从而以渐变填充 或描画绘制的图形:

// 绘制红色矩形
context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); // 绘制渐变矩形
context.fillStyle = gradient; context.fillRect(30, 30, 50, 50);

为了让渐变覆盖整个矩形,而不只是其中一部分,两者的坐标必须搭配合适。以上代码将得到如图 18-11 所示的结果。
如果矩形没有绘制到渐变的范围内,则只会显示部分渐变。比如:

   context.fillStyle = gradient;
    context.fillRect(50, 50, 50, 50);

以上代码执行之后绘制的矩形只有左上角有一部分白色。这是因为矩形的起点在渐变的中间,此时 颜色的过渡几乎要完成了。结果矩形大部分地方是黑色的,因为渐变不会重复。保持渐变与形状的一致 非常重要,有时候可能需要写个函数计算相应的坐标。比如:

function createRectLinearGradient(context, x, y, width, height) { return context.createLinearGradient(x, y, x+width, y+height);
}

径向渐变(或放射性渐变)要使用 createRadialGradient()方法来创建。这个方法接收 6 个参 数,分别对应两个圆形圆心的坐标和半径。前 3 个参数指定起点圆形中心的 x、y 坐标和半径,后 3 个参 20 数指定终点圆形中心的 x、y 坐标和半径。在创建径向渐变时,可以把两个圆形想象成一个圆柱体的两 个圆形表面。把一个表面定义得小一点,另一个定义得大一点,就会得到一个圆锥体。然后,通过移动 两个圆形的圆心,就可以旋转这个圆锥体。
要创建起点圆心在形状中心并向外扩散的径向渐变,需要将两个圆形设置为同心圆。比如,要在前 面例子中矩形的中心创建径向渐变,则渐变的两个圆形的圆心都必须设置为(55, 55)。这是因为矩形的起 点是(30, 30),终点是(80, 80)。代码如下:
这个函数会基于起点的 x、y 坐标和传入的宽度、高度创建渐变对象,之后调用 fillRect()方法 时可以使用相同的值:

let gradient = createRectLinearGradient(context, 30, 30, 50, 50); gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
// 绘制渐变矩形
context.fillStyle = gradient; context.fillRect(30, 30, 50, 50);

计算坐标是使用画布时重要而复杂的问题。使用类似 createRectLinearGradient()这样的辅助 函数能让计算坐标简单一些。

 let gradient = context.createRadialGradient(55, 55, 10, 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);

运行以上代码会得到如图 18-12 所示的效果。
因为创建起来要复杂一些,所以径向渐变比较难处理。不过,通常情况下,起点和终点的圆形都是 同心圆,只要定义好圆心坐标,剩下的就是调整各自半径的问题了。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值