canvas 变形记——移动、旋转、缩放、变形

canvas 有几个变形形式:移动、旋转、缩放、变形。在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。又,如果你是在一个循环中做位移但没有保存和恢复 canvas 的状态,很可能到最后会发现怎么有些东西不见了,那是因为它很可能已经超出 canvas 范围以外了。

1、移动 Translate

translate用来移动 canvas 和它的原点到一个不同的位置。
translate(x, y) translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量。

看个例子
这里写图片描述
这个例子显示了一些移动 canvas 原点的好处。我创建了一个 drawSpirograph 方法用来绘制螺旋(spirograph)图案,那是围绕原点绘制出来的。如果不使用 translate 方法,那么只能看见其中的四分之一。translate 同时让我可以任意放置这些图案,而不需要在 spirograph 方法中手工调整坐标值,既好理解也方便使用。

我在 draw 方法中调用 drawSpirograph 方法 9 次,用了 2 层循环。每一次循环,先移动 canvas ,画螺旋图案,然后恢复早原始状态。

<canvas id="canvas" width=400 height=400></canvas>
<script type="text/javascript">
    function draw() {
        var ctx = document.getElementById('canvas').getContext('2d');
        ctx.fillRect(0,0,300,300);
        for (var i=0;i<3;i++) {
            for (var j=0;j<3;j++) {
                ctx.save();
                ctx.strokeStyle = "#9CFF00";
                ctx.translate(50+j*100,50+i*100);
                drawSpirograph(ctx,20*(j+2)/(j+1),-8*(i+3)/(i+1),10);
                ctx.restore();
            }
        }
    }
    function drawSpirograph(ctx,R,r,O){
        var x1 = R-O;
        var y1 = 0;
        var i    = 1;
        ctx.beginPath();
        ctx.moveTo(x1,y1);
        do {
            if (i>20000) break;
            var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72))
            var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72))
            ctx.lineTo(x2,y2);
            x1 = x2;
            y1 = y2;
            i++;
        } while (x2 != R-O && y2 != 0 );
        ctx.stroke();
    }
    draw();
</script>

!!!表示不明白drawSpirograph里是怎样实现的,数学没学好。

2、旋转 Rotating

rotate 方法,它用于以原点为中心旋转 canvas。

rotate(angle)
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

看个例子
这里写图片描述

<canvas id="canvas" width=400 height=400></canvas>
<script type="text/javascript">
    function draw() {
        var ctx = document.getElementById('canvas').getContext('2d');
        ctx.translate(75,75);  //移动远点到(75,75)处

        for (var i=1;i<6;i++){ //里往外画5圈圆
            ctx.save(); //先保存状态
            ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)'; //圆的颜色

            //下面实现效果是:通过旋转画板,在x轴上画圆。这样的好处是方便计算,所有圆在x轴上实现,通过旋转画板来画所有圆。
            for (var j=0;j<i*6;j++){
                ctx.rotate(Math.PI*2/(i*6)); //顺时针旋转Math.PI*2/(i*6)度
                ctx.beginPath();
                ctx.arc(0,i*12.5,5,0,Math.PI*2,true); //在(0,12.5*i)处画圆,半径为5px,画360度。
                ctx.fill();
            }

            ctx.restore(); //还原到保存前的状态
        }
    }
    draw();
</script>

3、缩放 Scaling

scaling 用来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。
scale(x, y)
scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
默认情况下,canvas 的 1 单位就是 1 个像素。举例说,如果我们设置缩放因子是 0.5,1 个单位就变成对应 0.5 个像素,这样绘制出来的形状就会是原先的一半。同理,设置为 2.0 时,1 个单位就对应变成了 2 像素,绘制的结果就是图形放大了 2 倍。

4、变形 Transforms

transforms 直接对变形矩阵作修改。

transform(m11, m12, m21, m22, dx, dy) 这个方法必须将当前的变形矩阵乘上下面的矩阵:

m11 m21 dx
m12 m22 dy
0   0   1

这个方法必须重置当前的变形矩阵为单位矩阵,然后以相同的参数调用 transform 方法。如果任意一个参数是无限大,那么变形矩阵也必须被标记为无限大,否则会抛出异常。

看个例子
这里写图片描述

    <canvas id="canvas" width=400 height=400></canvas>
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");

            var sin = Math.sin(Math.PI/6);
            var cos = Math.cos(Math.PI/6);
            ctx.translate(100, 100);
            var c = 0;
            for (var i=0; i <= 12; i++) {
                c = Math.floor(255 / 12 * i);
                ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
                ctx.fillRect(0, 0, 100, 10);
                ctx.transform(cos, sin, -sin, cos, 0, 0);
            }
        }
        draw();
    </script>

transform 没看明白, 有待研究。

参考文献:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Transformations

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CanvasHTML5新增的一个用于绘制图形的标签,可以通过JavaScript来控制Canvas进行图形的绘制。在进行Canvas绘制时,可以通过调整画布的位置、大小和旋转角度等属性,来控制绘制出来的图形的位置和形态。 下面我们就来介绍一下Canvas画布的移动缩放旋转: 1. 画布移动 画布移动可以通过Canvas提供的translate方法来实现。translate方法接收两个参数,分别表示x轴和y轴方向上的偏移量。偏移量为正值表示向右或向下移动,为负值表示向左或向上移动。 例如,我们可以通过下面的代码将画布向右移动50个像素,向下移动100个像素: ``` context.translate(50, 100); ``` 2. 画布缩放 画布缩放可以通过Canvas提供的scale方法来实现。scale方法接收两个参数,分别表示x轴和y轴方向上的缩放比例。缩放比例为大于1的值表示放大,小于1的值表示缩小。 例如,我们可以通过下面的代码将画布在x轴和y轴方向上都放大2倍: ``` context.scale(2, 2); ``` 3. 画布旋转 画布旋转可以通过Canvas提供的rotate方法来实现。rotate方法接收一个参数,表示旋转的角度,单位为弧度。 例如,我们可以通过下面的代码将画布旋转45度: ``` context.rotate(Math.PI / 4); ``` 需要注意的是,Canvas绘图的坐标系原默认在画布的左上角,而移动缩放旋转操作都是相对于原进行的。因此,在进行这些操作时,需要先将画布的原移动到需要的位置,再进行操作。例如,如果需要将画布向右移动50个像素,需要先将原移动到(50,0)的位置,再进行移动操作: ``` context.translate(50, 0); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值