canvas的transform3

65次阅读

共计 2340 个字符,预计需要花费 6 分钟才能阅读完成。

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

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

  • 首先 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>

正文完
 0