canvas的旋转(rotate)是绕画布的左上角(0,0)开始旋转的,所以直接旋转无法得到想要的效果。
旋转的步骤:
1. 将(0, 0)偏移到物体的中心: ctx.translate(centerX, centerY);
2. 执行旋转: ctx.rotate(deg * Math.PI / 180)
3.偏移到物体中心负值: ctx.translate(-centerX, -centerY)
具体如下:
html:
javascript:
let cv = document.querySelector('.cv'),
ctx = cv.getContext('2d'),
/*
* @param Number sx 物体开始绘制的x点
* @param Number sy 物体开始绘制的y点
* @param Number width 物体开始绘制的宽
* @param Number height 物体开始绘制的高
*/
getCenter = (sx, sy, width, height) => { // 返回物体的中心点
return {
x: sx + (width / 2),
y: sy + (height / 2)
};
},
/*
* 绘制图形
*/
draw = () => {
let x = 50, // 矩形x起点
y = 50, // 矩形y起点
width = 50, // 矩形宽
height = 50,
deg = 45,
center = getCenter(x, y, width, height); // 中心
ctx.clearRect(0, 0, cv.width, cv.height);
// 绘制
ctx.save(); // 保存状态,以免影响其它物体
ctx.fillStyle = 'skyblue';
ctx.translate(center.x, center.y); // 将画布偏移到物体中心
ctx.rotate(deg * Math.PI / 180); // 旋转角度
ctx.translate(-center.x, -center.y); // 将画布偏移回来
ctx.beginPath(); // 开启路径
ctx.fillRect(x, y, width, height);
ctx.closePath(); // 关闭路径
ctx.stroke(); // 描边绘制
ctx.restore();// 恢复状态
};
// 画布大小
cv.width = 800;
cv.height = 500;
draw(); // 开始绘制缩放
完整代码:
1
2
3
4
5
6
7
8
9
10 let cv = document.querySelector('.cv'),
11 ctx = cv.getContext('2d'),
12 rects = [], // 保存矩形的数组
13 n = 50, // 矩形个数
14 width, height, center, rect,
15 /*
16 * @param Number sx 物体开始绘制的x点
17 * @param Number sy 物体开始绘制的y点
18 * @param Number width 物体开始绘制的宽
19 * @param Number height 物体开始绘制的高
20 */
21 getCenter = (sx, sy, width, height) => { // 返回物体的中心点
22 return {
23 x: sx + (width / 2),
24 y: sy + (height / 2)
25 };
26 },
27 /*
28 * 绘制图形
29 */
30 draw = () => {
31 ctx.clearRect(0, 0, cv.width, cv.height);
32
33 for (let i = 0; i < rects.length; i ++) {
34 rect = rects[i];
35 center = getCenter(rect.x, rect.y, rect.width, rect.height); // 获取矩形的中心
36
37 // 绘制
38 ctx.save(); // 保存状态,以免影响其它物体
39 ctx.fillStyle = rect.color;
40 ctx.translate(center.x, center.y); // 将画布偏移到物体中心
41 ctx.rotate(rect.deg * Math.PI / 180); // 旋转角度
42 ctx.translate(-center.x, -center.y); // 将画布偏移回来
43 ctx.beginPath(); // 开启路径
44 ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
45 ctx.closePath(); // 关闭路径
46 ctx.stroke(); // 描边绘制
47 ctx.restore();// 恢复状态
48
49 rect.deg += rect.v; // 增加角度
50 rect.v += rect.speed;
51
52 if (rect.v >= 180) { // 旋转180度后删除并重新生成
53 rects.splice(i, 1);
54 i --;
55 create();
56 }
57 }
58
59 requestAnimationFrame(draw);
60 },
61 /*
62 * 生成随机颜色
63 */
64 randColor = () => {
65 let r = Math.floor(Math.random() * 255),
66 g = Math.floor(Math.random() * 255),
67 b = Math.floor(Math.random() * 255);
68
69 return `rgb(${r},${g},${b})`;
70 },
71 /*
72 * 创建一个随机矩形
73 */
74 create = () => {
75 width = (Math.random() * 20) + 20;
76 height = (Math.random() * 20) + 20;
77
78 rects.push({
79 x: (Math.random() * (cv.width - (2 * width))) + (2 * width),
80 y: (Math.random() * (cv.height - (2 * height))) + (2 * height),
81 width, height,
82 color: randColor(),
83 deg: Math.random() * 360,
84 v: 0,
85 speed: Math.random()
86 });
87 };
88
89 for (let i = 0; i < n; i ++) {
90 create();
91 }
92
93 // 画布大小
94 cv.width = 800;
95 cv.height = 500;
96
97 window.requestAnimationFrame = window.requestAnimationFrame
98 || window.webkitRequestAnimationFrame
99 || window.oRequestAnimationFrame
100 || window.mozRequestAnimationFrame
101 || window.msRequestAnimationFrame
102 || function (callback) {
103 setTimeout(callback, 1000 / 60);
104 };
105
106 draw(); // 开始绘制缩放
107
108
109