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,直接相对于单位矩阵变换