• canvas的transform有三个属性:translate、scale和rotate,没有skew
  • 和transform的执行顺序一样,这个也是后写的属性先执行,也就是从后往前执行

canvas的transform的一个实例:旋转矩形

canvas的transform.gif

  • 首先canvas画布的旋转中心在左上角,所以我们需要把矩形的旋转中心和左上角重合,比如原来矩形的坐标是x:300,y:200,矩形宽高是w:200,h:150,那么我们需要把矩形中心画到画布左上角:x:-w/2=-100,y:-h/2=75,然后在移动画布到原来的坐标x:300+100=300,200+75=275,注意这里要先旋转画布,在移动画布,但是写的时候先写移动,在写旋转。
  • 同样的,在画出来之前需要先全部清掉。然后重画,然后在清掉,在重画,这样不停的重复,因为角度在不断的变化,所以最后就会有动画的效果了
  • 还有一点在清掉重画之前我们需要保存上一次的绘画状态,然后在这次绘画状态之上在画下一步,不然的话,循环就是不停的在一个地方重画。

代码贴上去,原理是这样,但是说实话,这段代码我没怎么看懂( ̄_ ̄|||)
就是 obj.save()obj.resatore() 这个地方,哪位大神可以解释下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background: gray;
            text-align: center;
        }
    </style>
    <script>
        window.onload = function () {
            let c1 = document.getElementsByTagName('canvas')[0];
            let gd = c1.getContext('2d');
            function d2a(n) {//角度转弧度
                return n * Math.PI / 180;
            }
            function a2d(n) {//弧度转角度
                return n * 180 / Math.PI;
            }
            let r=0;

            requestAnimationFrame(next);

            function next() {
                
                gd.clearRect(0, 0, c1.width, c1.height);

                gd.save();//保存当前的画布状态
                gd.translate(500, 275);
                gd.rotate(d2a(r++));
                gd.strokeStyle='orange';
                gd.strokeRect(-100, -75, 200, 150);
                gd.restore();//恢复上一次保存的画布状态

                requestAnimationFrame(next);
            }
        }
    </script>
</head>
<body>
    <canvas width="800" height="600" style="background:white;"></canvas>
</body>
</html>

下面这个是可以转多个矩形的:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background: gray;
            text-align: center;
        }
    </style>
    <script>
        window.onload = function () {
            let c1 = document.getElementsByTagName('canvas')[0];
            let gd = c1.getContext('2d');

            function d2a(n) {//角度转弧度
                return n * Math.PI / 180;
            }
            function a2d(n) {//弧度转角度
                return n * 180 / Math.PI;
            }

            let datas = [
                { x: 300, y: 300, w: 200, h: 100, s: 1 },
                { x: 200, y: 100, w: 100, h: 50, s: 1 },
                { x: 250, y: 50, w: 50, h: 100, s: 5 }
            ];//矩形数据,s表示speed,旋转速度


            requestAnimationFrame(next);
            let r=0;
            function next() {
                gd.clearRect(0, 0, c1.width, c1.height);//清除画布
                
                datas.forEach(data => {
                    
                    gd.save();//保存当前的画布状态

                    gd.translate(data.x, data.y);
                    gd.rotate(d2a(r++*data.s/10));//旋转速度在这里调
                    gd.strokeStyle = 'orange';
                    gd.strokeRect(-data.w / 2, -data.h / 2, data.w, data.h);
                    gd.restore();//恢复上一次保存的画布状态

                });
                requestAnimationFrame(next);
            }

        }
    </script>
</head>
<body>
    <canvas width="800" height="600" style="background:white;"></canvas>
</body>
</html>

canvas多个物体旋转.gif


逸轩
8 声望1 粉丝

我也想成为大佬啊