canvas绘图详解-07-图形变换和保存

1、图形变换和保存

之前五角星用rot,计算旋转角度可以进行图形旋转,改变半径大小可以设置五角星的大小,下面介绍自带的函数进行图形变化

这是一个画出一片星空的例子

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<canvas id="canvas" style="border:1px solid #aaa;display:block;margin:50px auto;">
    当前浏览器不支持canvas时,请更换浏览器
</canvas>

<script type="text/javascript">
    window.onload=function(){
        var canvas = document.getElementById('canvas');
        canvas.width = 800;
        canvas.height = 800;
        var context = canvas.getContext('2d');

        context.fillStyle = "black";
        context.fillRect( 0 , 0 , canvas.width , canvas.height );
        context.fillStyle = "yellow";
        context.lineJoin = "round";
        for( var i = 0 ; i < 200 ; i++){
            var r = Math.random() * 10 + 10;
            //不超过边界,为啥这么写。
            var x = Math.abs(Math.random() * canvas.width - 2*r) + r;
            var y = Math.abs(Math.random() * canvas.height - 2*r) + r;
            var a = Math.random() * 360;
            drawStar( context  , x ,y ,r , a );
        }
        
    }

    function drawStar( cxt ,  x , y , r  ,rot){
        cxt.save();
        
        cxt.translate(x,y);
        cxt.rotate(rot/180*Math.PI);
        cxt.scale(r,r);
        starPath(cxt);

        cxt.fillStyle = "#fb3";
        //使用scale会有副作用,很多属性也跟着变,所以有时候不得不放弃,此例子因为,星星默认定点是00,通过变换改变位置,所以没有影响
        // cxt.strokeStyle = "#fd5";
        // cxt.lineWidth = 3;
        // cxt.lineJoin = "round";
        cxt.fill();
        //没有描边但是你描边了会有bug,这个要是描边了就变成全黑了
        //cxt.stroke();

        cxt.restore();

    }
    function starPath( cxt ){
        cxt.beginPath();
        for( var i = 0 ; i < 5 ; i ++){
            cxt.lineTo(Math.cos((18+72*i)/180*Math.PI) ,- Math.sin((18+72*i )/180*Math.PI));
            cxt.lineTo(Math.cos((54+72*i)/180*Math.PI) * 0.5 ,- Math.sin((54+72*i )/180*Math.PI) * 0.5);
        }
        cxt.closePath();
    }

</script>

</body>
</html>
View Code

其中是对于绘图状态的保存和恢复 ,就是说你设置了很多状态属性,比如颜色啊,宽度啊,位移旋转缩放,然后你操作完了,你恢复一下设置前的绘图状态。

cxt.save()

cxt.restore()

图形变换

cxt.translate(x,y);//位移

cxt.translate(x,y)位移,比如你绘制完一个图形,原点坐标已经移动到(x,y)坐标了,你没有恢复绘图状态,你再画一个图,是以(x,y)为原点坐标计算的

图形变换是有一个累加的效果,一次变换是在之前的变换的基础上的。所以要用save()和restore()来控制,避免你不想要的累加效果。

cxt.rotate(rot/180*Math.PI);//旋转

cxt.scale(sx,sy);//缩放

左边的代码绘制出现右边的情况和你想象的是不是有差别

四个顶点的坐标缩放了,线段的长度缩放了,线段的宽度缩放了。

所以使用scale要注意这些细节,如果产生这些不可接受的效果,那么只能选择其他方式实现了

2、深入理解图形变换

图形变换是把一个图形的所有顶点坐标进行在计算,计算的过程是由变换矩阵来计算的

二维的变换矩阵是3*3,三维的就是4*4

 

cxt.transform( a , b , c , d , e , f)

因为transform有累加效果,所以有下面这个函数

cxt.setTransform( a , b , c , d , e , f)//忽略之前所有的transform,直接相对于单位矩阵变换

原文地址:https://www.cnblogs.com/wufangfang/p/6374680.html