canvas旋转图形,默认是以原点为中心进行旋转的。那如果按任意点如何旋转呢?看下图所示:

我们想按图中的黑色点进行旋转,我们可以将这个动作进行拆解:
1)将图形拉回到原点;
假设图形平移了c,那么拉回原点的操作就是平移-c,我们假设这个动作是T(-c)
2)沿原点进行旋转α角度;
我们假设这个动作为R(α)
3)将图形返回原来的位置;
前面我们将图形平移了-c,这时再平移c返回到原来的位置,我们假设这个动作为T(c)
这样,我们就可以将任意点旋转的复合矩阵,分解为三步操作:

从而可以得出如下性质:

矩阵分解是很好用的技巧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="500" height="500" style="border:1px dashed gray;">
</canvas>
<button id="btn">矩阵分解</button>
</body>
</html>
<script>
var cnv = document.getElementById('canvas');
var cxt = cnv.getContext('2d');
var alpha =Math.PI / 10;//旋转弧度
var c = 30;//平移长度
cxt.fillStyle = 'blue';
cxt.fillRect(30, 30, 50, 50);
document.getElementById('btn').onclick = function () {
cxt.clearRect(0, 0, cnv.width, cnv.height);//清除画布
cxt.transform(1,0,0,1,-c,-c);//平移-c到原点
cxt.transform(Math.cos(alpha), Math.sin(alpha), -Math.sin(alpha), Math.cos(alpha), 0, 0); //旋转角度
cxt.transform(1,0,0,1,c,c);//平移c到原来位置
cxt.fillStyle = 'blue';
cxt.fillRect(30, 30, 50, 50);//画出图形
}
</script>
网友评论