容易被 drawImage 搞晕

Canvas 使用 drawImage 进行绘图,但是这个 API 并不是那么“好用”,我也踩了一些坑,今天彻底搞懂它。首先看下它的定义:

输入源定义:

type HTMLOrSVGImageElement = 
HTMLImageElement | 
SVGImageElement;


type CanvasImageSource =
 HTMLOrSVGImageElement | 
HTMLVideoElement | 
HTMLCanvasElement | 
ImageBitmap | 
OffscreenCanvas;

API 定义:

interface CanvasDrawImage {
    drawImage(image: CanvasImageSource, dx: number, dy: number): void;
    drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
    drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number,
     dx: number, dy: number, dw: number, dh: number): void;
}

CanvasImageSource 定义了 drawImage 能够绘制哪些内容。虽然这个 API 叫 drawImage,但是它不仅仅能够绘制 Image,还能够绘制视频、绘制其它 Canvas Element、离屏 Canvas、SVG image element,还可以使用 bitmap;

输入源可以是 HTML 中已经存在的 HTML 元素,也可以是通过 JS 加载的资源,比如下面的代码是通过 js 加载一张图片,然后把它绘制到画布上,代码中我修改了图片的原先宽度,进行了等比缩放:

// 等比缩放图片到某个宽度
const drawImageWithWidth = (ctx: CanvasRenderingContext2D, width: number) => {
    let img = new Image();
    img.src = 'zly.jpeg';
    img.onload = function () {
        /**
         * drawImage(image: CanvasImageSource, 
         * sx: number, sy: number, sw: number, sh: number, 
         * dx: number, dy: number, dw: number, dh: number): void;
         */
        let sw = img.width;
        let sh = img.height;
        let dw: number = width;
        let scale = dw / sw;
        ctx.drawImage(img, 20, 20, sw*scale, sh*scale);
    }
}

drawImage 最多可以有 9 个参数,看下 MDN 上的一张图:

包含不同的参数最终绘制的结果完全不同:

drawImage(image: CanvasImageSource, dx: number, dy: number): void;

表示把 image 直接绘制到 Canvas,dx、dy 指定 Image 在 Canvas 中的坐标,宽高使用 image 内容的宽高。

drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;

表示把 image 直接绘制到 Canvas,dx、dy 指定 Image 在 Canvas 中的坐标;dw、dh 指定要绘制的宽高,dw 和 dh 一般不会写死,因为会导致最终绘制的 Image 发现变形,通常会等比缩放。

drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;


这个 Api 就有意思了,我对它的理解是「从原 Image 中取一块区域绘制到 Canvas 上」,(sx,sy,sw、sh)表示原 Image 中的一块区域,sx、sy 表示从 Image 左上角开始的坐标;(dx,dy,dw、dh)表示在 Canvas 中的区域,dx、dy 表示画布的坐标;

这个 API 挺有意思,比如可以做图片的裁剪功能、图片拼接、图片复制等,总的来说图片的绘制基本都能搞定。哦,别忘了输入源不只是图片。下面是把一张大图进行裁剪:

具体代码可以看这里:

https://github.com/lefex/FE/tree/master/learn-canvas

长按关注

素燕《前端小课》

帮助 10W 人入门并进阶前端

官网:https://lefex.gitee.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值