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>
其中是对于绘图状态的保存和恢复 ,就是说你设置了很多状态属性,比如颜色啊,宽度啊,位移旋转缩放,然后你操作完了,你恢复一下设置前的绘图状态。
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,直接相对于单位矩阵变换


浙公网安备 33010602011771号