JavaScript动画实例:转呀转
在Canvas API中,上下文CanvasRenderingContext2D对象提供了一个与坐标旋转相关的方法:
void rotate(in float angle); // 按给定的弧度顺时针旋转angle
rotate()方法旋转的中心始终是canvas的原点。如果要改变旋转中心,需要使用translate方法。
我们可以将绘制的图形每隔一定的时间间隔后,旋转一定的角度重新绘制一次,这样就可以得到旋转的动画效果。
1.旋转的扇叶
将一个梯形按顺时针旋转90°的方式绘制4次,可以绘制出一个扇叶图案。将绘制的扇叶图案每隔0.1秒后顺时针旋转12°,重新绘制一遍,得到旋转的扇叶动画。
编写如下的HTML代码。
<!DOCTYPE html>
<head>
<title>旋转的扇叶</title>
<script type="text/javascript">
var context;
var i;
function draw(id)
{
var canvas = document.getElementById(id);
if (canvas == null)
return false;
context = canvas.getContext('2d');
i=3;
setInterval(move,100);
}
function move()
{
context.clearRect(0,0,400,300);
context.save();
context.fillStyle = 'green';
context.translate(100,100);
context.rotate(i*Math.PI/45)
drawLeaf();
i+=3;
if (i>=90) i=3;
context.restore();
}
function drawLeaf() // 绘制扇叶
{
context.save();
for (var j=0;j<4;j++)
{
context.rotate(Math.PI/2);
context.beginPath();
context.moveTo(-20,-80);
context.lineTo(0,-80);
context.lineTo(0,0);
context.lineTo(-30,0);
context.closePath();
context.fill();
}
context.restore();
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="200" height="200" style="border:3px double #996633;">
</canvas>
</body>
</html>
将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到扇叶的旋转动画,如图1所示。
图1 旋转的扇叶
2.旋转的五角星
将绘制的五角星图案每隔0.1秒后顺时针旋转12°,重新绘制一遍,得到旋转的五角星动画。
编写如下的HTML代码。
<!DOCTYPE html>
<head>
<title>旋转的五角星</title>
<script type="text/javascript">
var context;
var i;
function draw(id)
{
var canvas = document.getElementById(id);
if (canvas == null)
return false;
context = canvas.getContext('2d');
i=3;
setInterval(move,100);
}
function move()
{
context.clearRect(0,0,400,300);
context.save();
context.fillStyle = 'green';
context.translate(100,100);
context.rotate(i*Math.PI/45)
drawStar(80);
i+=3;
if (i>=90) i=3;
context.restore();
}
function drawStar(r) // 绘制五角星图案
{
context.save();
context.fillStyle="red";
context.beginPath();
context.moveTo(r,0);
for (var i=0;i<9;i++)
{
context.rotate(Math.PI/5);
if(i%2 == 0)
context.lineTo((r/2),0);
else
context.lineTo(r,0);
}
context.closePath();
context.fill();
context.restore();
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="200" height="200" style="border:3px double #996633;">
</canvas>
</body>
</html>
将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到五角星的旋转动画,如图2所示。
图2 旋转的五角星
3.旋转的正六边形漩涡
我们先来画一个正六边形。这样作图,设从起点向绘图方向画一条长为i的线段,将线段的终点设为新的起点,同时绘图方向旋转60°,再画一条长为i+1的线段,重复这样的过程共绘制六条线段,则这六条线段构成一个正六边形。
编写HTML文件内容如下。
<!DOCTYPE html>
<head>
<title>正六边形</title>
<script type="text/javascript">
function draw(id)
{
var canvas=document.getElementById(id);
if (canvas==null)
return false;
var context=canvas.getContext('2d');
context.fillStyle="#EEEEFF";
context.fillRect(0,0,400,400);
context.translate(canvas.width/2, canvas.height/2);
var colors = ['red','yellow', 'green', 'cyan','blue', 'purple' ];
for (i =150; i < 156; i++)
{
context.strokeStyle = colors[i % 6];
context.lineWidth = 2;
context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, i/2);
context.stroke();
context.translate(0, i/2);
context.rotate(-60 * (2 * Math.PI / 360));
}
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">
</canvas>
</body>
</html>
将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在画布中绘制一个正六边形图案,如图3所示。
图3 一个正六边形
绘制图3的程序中,循环进行了6次,只绘制6条边。若修改“for (i =150; i < 156; i++)”语句为“for (i =150; i < 180; i++)”,使得循环进行30次,则在画布中绘制出如图4所示的图案,该图案有5个六边形围成。若修改语句为“for (i =0; i < 360; i++)”,则在画布中绘制出如图5所示的六边形图案。
图4 5个六边形围成的图案
图5 正六边形
生成图5图案的程序中,绘图时旋转的角度为60°,若将旋转角度改成59°,即将语句“context.rotate(-60 * (2 * Math.PI / 360));”修改为“context.rotate(-59 * (2 * Math.PI / 360));”,则在画布中绘制出如图6所示的正六边形漩涡。
图6 正六边形漩涡
将图6的正六边形漩涡旋转起来。编写如下的HTML文件。
<!DOCTYPE html>
<head>
<title>旋转的正六边形漩涡</title>
<script type="text/javascript">
var context;
var count;
function draw(id)
{
var canvas = document.getElementById(id);
if (canvas == null)
return false;
context = canvas.getContext('2d');
count=3;
setInterval(move,100);
}
function move()
{
context.clearRect(0,0,400,400);
context.save();
context.translate(200, 200);
context.rotate(count*Math.PI/45)
drawSix();
count+=3;
if (count>=90) count=3;
context.restore();
}
function drawSix() // 绘制正六边形漩涡图案
{
context.save();
var colors = ['red','yellow', 'green', 'cyan','blue', 'purple' ];
for (i = 0; i < 360; i++)
{
context.strokeStyle = colors[i % 6];
context.lineWidth = i / 200 + 1;
context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, i/2);
context.stroke();
context.translate(0, i/2);
context.rotate(-59 * (2 * Math.PI / 360));
}
context.restore();
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">
</canvas>
</body>
</html>
将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到正六边形漩涡的旋转动画,如图7所示。
图7所示的动画显得有些单调,我们修改上面的程序,使得在绘制正六边形时的旋转角度进行变化,得到不断转呀转的正六边形。
编写的HTML文件内容如下。这个HTML文件的内容与上一个HTML文件内容,修改了两处,为方便读者引用,还是给出完整文件内容。
图7 正六边形漩涡的旋转动画
<!DOCTYPE html>
<head>
<title>旋转的正六边形漩涡</title>
<script type="text/javascript">
var context;
var count;
function draw(id)
{
var canvas = document.getElementById(id);
if (canvas == null)
return false;
context = canvas.getContext('2d');
count=0;
setInterval(move,50);
}
function move()
{
context.clearRect(0,0,400,400);
context.save();
context.translate(200, 200);
context.rotate(count*Math.PI/45)
drawSix();
count++;
if (count>=360) count=0;
context.restore();
}
function drawSix() // 绘制正六边形漩涡图案
{
context.save();
var colors = ['red','yellow', 'green', 'cyan','blue', 'purple' ];
var rotation = (2 * Math.sin(count / (3.14 * 20)));
for (i = 0; i < 360; i++)
{
context.strokeStyle = colors[i % 6];
context.lineWidth = i / 200 + 1;
context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, i/2);
context.stroke();
context.translate(0, i/2);
context.rotate((-60 + rotation) * 2 * Math.PI / 360);
}
context.restore();
}
</script>
</head>
<body onload="draw('myCanvas');">
<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">
</canvas>
</body>
</html>
将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到一个更加生动的不断转呀转的正六边形漩涡的旋转动画,如图8所示。
图8 更生动的正六边形漩涡的旋转动画