前言
本文主要讲解HTML5中Canvas里面元素因为scale, skew, rotate等作用后导致了元素本身的尺寸和位置的变化,这在很多Canvas元素绘制场景是比较常见的。
1、Canvas中元素坐标变换
1.1、Canvas中元素偏移
假如任何一个元素在Canvas中的定位可以使用originX, originY来指定,而originX又进一步分为left, center, right,而originY又分为top, center, bottom。那么其左上角,右上角,左下角,右下角分别使用一个Map来指定位置:

这个Map里面使用了0.5为基本单位,是因为我们默认是以元素本身的中心来定位的,即originX, originY都为center的时候通过Map可以保证得到的值为0。
那么假如元素上的某一个点(originY, originY可能不是center)需要移动到中心点(即originX, originY都为center),那么其需要移动的距离怎么算?

看看translateToGivenOrigin的方法逻辑?

在这个方法里面首先将元素的fromOriginX , fromOriginY, toOriginX, toOriginY转化为相对于中心点的偏移。这个偏移很显然是相对于元素的尺寸来说的,所以下面转化为计算元素的尺寸信息。
1.2、Canvas中元素尺寸计算
接下来需要计算的是元素的具体尺寸信息,即_getTransformedDimensions方法的代码逻辑:

下面是上图中的_getNonTransformedDimensions方法的代码:
_getNonTransformedDimensions = () => { var strokeWidth = this.strokeWidth, w = this.width + strokeWidth, h = this.height + strokeWidth; return { x: w, y: h }; }
而_finalizeDiemensions的代码逻辑如下:
_finalizeDiemensions = (width, height) => { return this.strokeUniform ? { x: width + this.strokeWidth, y: height + this.strokeWidth } : { x: width, y: height }; }
在上图中重要的方法是_calcDimensionsTransformMatrix:

这个方法根据元素当前的skewX, skewY, scaleX, scaleY来计算变换矩形,得到这个矩阵后就可将四个顶点的坐标进行转换:

四个顶点转换后就可计算其组成的矩形区域,就是上面的makeBoundingBoxFromPoints方法:

至此四个顶点围成的区域计算好了。
1.3、图解矩阵变换后区域
假如一开始的矩形区域状态如下:

那么经过skew, scale, rotate后围成的区域如下:

也就是外层矩形围成的区域了, 可以从makeBoundingBoxFromPoints方法的计算逻辑明显看出来:

2、本文总结
本文主要讲解了Canvas中元素因scale, skew , rotate等矩阵变换后导致其尺寸,坐标的变化,这在很多绘图场景是比较常见的,比如Fabric.js。通过本文,对于后续Canvas制图中遇到的问题能够有一个基本的思路。我们下期再见~
