canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

●save()与restore()

context对象提供了保存于恢复canvas的状态函数
1:save() :将当前canvas中的所有状态信息保存入堆
2:restore(): 该方法用于弹出并开始使用堆最上面保存的状态信息

●translate()平移
context.translate(x,y);
x: 将坐标原点向左或右移动多少个单位
y: 将坐标原点向下或上移动多少个单位

案例 1:观察原点的位置变化
canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

 <script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.fillRect(0,0,50,50);
    ctx.translate(200,200);
    ctx.fillStyle = 'blue';
    ctx.fillRect(-100,-100,80,80);// 从(100,100)开始绘制
    var ctx2 = canvas.getContext('2d');
    ctx2.fillStyle = 'red';
    ctx2.fillRect(0,0,80,80);// 坐标轴原点已经改变(200,200)
    
</script>

案例 2:绘制不同的花
canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例
canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

 <body>
    <select name="" id="draw">
        <option value="1">蓬莱菊花</option>
        <option value="2">令箭荷花</option>
    </select>
    <canvas width="200" height="200" id="canvas"></canvas>
    <input type="button" id="btn" value="绘制">
</body>
<script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var btn = document.getElementById('btn');
    var A;
    btn.onclick = btn_click;
    function btn_click() {
        var w = canvas.width;
        var h = canvas.height;
        var X0 = w / 2;
        var Y0 = h /2;
        var k = parseInt(document.getElementById('draw').value);// 默认为1
        // console.log(k);
        if(k == 2)
        {
            A = Y0*0.25;
        }
        else 
        {
            A = Y0*0.75;
        }
        ctx.save();// 保存当前绘制的状态
        ctx.clearRect(0,0,w,h);// 清除之前绘制的图形
        ctx.translate(X0,Y0);// 将坐标原点移到canvas中间
        ctx.beginPath();// 开始绘制
        for( var B = 0;B <= 6.28;B = B+0.01)
        {
            draw(B);
        }
        ctx.closePath();
        ctx.restore();// 恢复到保存前的状态
    } 
    function draw(B){
        var n = 10;
        var r,x,y ;
        switch(parseInt(document.getElementById('draw').value))
        {
            case 1:
            r = A * Math.sin(n*B);
            case 2:
            r = A * (Math.sin(n*B)+3*Math.sin(3*n*B));
        }
        x = r*Math.cos(B);
        y = r*Math.sin(B);
        ctx.fillStyle = 'green';
        ctx.strokeStyle = 'black';
        ctx.lineTo(-x,-y);
        ctx.fill();
        ctx.stroke();
    }
</script>

●scale()缩放
context.scale(x,y);
x:表示水平方向缩放的倍数;
y:表示垂直方向缩放的倍数。

案例
canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

<script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = "#fc0";
    ctx.linewidth = 1.5;
    ctx.fillRect(0,0,300,300);
    ctx.save();// 保存当前的状态
    ctx.translate(50,50);//平移原点坐标
    draw(ctx,22,6,5);
    ctx.translate(100,0);
    ctx.scale(0.75,0.75);// 缩放图形
    draw(ctx,22,6,5);
    ctx.translate(133.133,0);// 在上一个基础上平移
    ctx.scale(0.75,0.75);// 在上面的基础上缩小
    draw(ctx,22,6,5);    
    ctx.restore();
    function draw(ctx,R,r,O)
    {
        var x1 = R - O,y1 = 0,i = 1;
        ctx.beginPath();
        ctx.moveTo(x1,y1);
        do{
            if(i < 20000)
            {
                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();


    }
</script>

●rotate()旋转
rotate()方法用于将画布的x轴顺时针转动到与原x轴方向成angle角的位置,转动后x轴方向同时发生变化。

canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

<script>
    var ctx = document.getElementById('canvas1').getContext('2d');
    ctx.translate(160,160);// 平移
    ctx.fillStyle = 'rgba(200,54,54,0.5)';
    for(var i = 0;i < 15; i++)
    {
        ctx.scale(0.98,0.98);
        ctx.moveTo(0,0);// 移到原点
        ctx.lineTo(30,30);
        ctx.stroke();
        ctx.rotate(Math.PI/10);// 将画布的x轴旋转到与原X轴成18度,每循环一次旋转18度
        ctx.fillRect(0,0,100,50);
    }
</script>

●transform()矩阵变换
context.transform(ma1,ma2,mb1,mb2,dx,dy);
前4个参数:修改使用这个方法之后绘制图形时的计算方法,从而达到变形的目的;
dx/dy表示将坐标原点在x轴或y轴方向上移动;
各参数说明:水平缩放、水平倾斜、垂直倾斜、垂直缩放、水平移动、垂直移动
1:平移:使用transform(1,0,0,1,x,y)或者transform(0,1,1,0,x,y)代替translate(x,y);
2:缩放:使用transform(x,0,0,y,0,0)方法代替scale(x,y);
3:旋转: 使用transform(
Math.cos(angleMath.PI/180),
Math.sin(angle
Math.PI/180),
-Math.sin(angleMath.PI/180),
Math.cos(angle
Math.PI/180),
)

案例
canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例

<script>
    var ctx = document.getElementById('canvas').getContext('2d');
    ctx.fillStyle = '#eee';
    ctx.fillRect(0,0,750,600);
    var colors = ['#f00','#f90','#ff0','#090','#00f','#0051a1','#09f'];
    ctx.lineWidth = 10;
    ctx.transform(1,0,0,1,100,0);// 不缩放,不倾斜,将原点在x轴方向平移100px;
    for(var i = 0;i<colors.length;i++)
    {
        ctx.beginPath();
        ctx.transform(1,0,0.03,1,10,10);// 每次循环原点向右下移动10px,且倾斜0.03
        ctx.strokeStyle = colors[i];
        ctx.arc(150,200,150,0,2,true);
        ctx.stroke();
    }
</script>

●setTransform()矩阵变换

setTransform()方法将变换的矩阵进行重置,它把当前的变换矩阵重置为单位矩阵
context.setTransform(ma1,ma2,mb1,mb2,dx,dy)
各参数说明:水平旋转、水平倾斜、垂直倾斜、垂直缩放、水平移动、垂直移动