1. 程式人生 > 實用技巧 >JavaScript動畫例項:旋轉的正三角形

JavaScript動畫例項:旋轉的正三角形

給定一個正三角形的重心座標為(x0,y0),高為h,可以用如下的語句繪製一個底邊水平的正三角形。

ctx.beginPath();

ctx.moveTo(x0,y0-h*2/3);

ctx.lineTo(x0+h/Math.sqrt(3), y0+h/3);

ctx.lineTo(x0-h/Math.sqrt(3), y0+h/3);

ctx.lineTo(x0,y0-h*2/3);

ctx.closePath();

ctx.stroke();

給定正三角形個數count,通過迴圈的方式可以繪製出count個重心相同、高度不同正三角形。編寫如下的HTML程式碼。

<!DOCTYPE html>

<html>

<head>

<title>重心相同高度不同的正三角形</title>

</head>

<body>

<canvas id="myCanvas" width="500" height="500" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas=document.getElementById('myCanvas');

ctx= canvas.getContext('2d');

var height=360;

var x0=250;

var y0=(500-height)/2-(height/7)+(height*2/3);

var count=4;

ctx.lineWidth=1;

ctx.fillStyle="#FF3388";

ctx.strokeStyle="#FFFFFF";

for (var i=0;i<count;i++)

{

var nHeight = height-(height/count)*i;

ctx.beginPath();

ctx.moveTo(x0,y0-nHeight*2/3);

ctx.lineTo(x0+nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0-nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0,y0-nHeight*2/3);

ctx.closePath();

ctx.stroke();

ctx.fill();

};

</script>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中繪製出如圖1所示的4個重心相同高度不同的正三角形。

圖1 4個重心相同高度不同的正三角形

若將圖1中除最外層的三角形固定不動外,其餘的3個正三角形繞重心進行旋轉,會產生怎樣的效果呢?

編寫如下的HTML程式碼。

<!DOCTYPE html>

<html>

<head>

<title>旋轉的正三角形</title>

</head>

<body>

<canvas id="myCanvas" width="500" height="500" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas=document.getElementById('myCanvas');

ctx= canvas.getContext('2d');

var height=360;

var x0=250;

var y0=(500-height)/2-(height/7)+(height*2/3);

var count=4;

var speed=2;

ctx.lineWidth=1;

ctx.fillStyle="#FF3388";

ctx.strokeStyle="#FFFFFF";

var j = 0;

function draw()

{

ctx.clearRect(0,0,500,500);

ctx.save();

for (var i=0;i<=count;i++)

{

var nHeight = height-(height/count)*i;

ctx.translate(x0,y0);

ctx.rotate(i*j/(80*speed));

ctx.translate(-x0,-y0);

ctx.beginPath();

ctx.moveTo(x0,y0-nHeight*2/3);

ctx.lineTo(x0+nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0-nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0,y0-nHeight*2/3);

ctx.closePath();

ctx.stroke();

ctx.fill();

};

ctx.restore();

j++;

if (j>100000) j=0;

}

function move()

{

draw();

requestAnimationFrame(move);

}

move();

</script>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中呈現出如圖2所示重心相同高度不同的正三角形繞重心旋轉的動畫效果。

圖2 正三角形繞重心旋轉效果(一)

若將上面程式中語句“var speed=2;”改寫為“var speed=-2;”,其餘部分保持不變,則正三角形會逆時針旋轉,如圖3所示。

圖3 正三角形繞重心旋轉效果(二)

若將增加旋轉的三角形的個數並適當調低旋轉速度的級別,即修改語句:

“var count=4; var speed=2;” 為 “var count=20; var speed=12;”,其餘部分保持不變,則在畫布中呈現出如圖4所示的正三角形旋轉效果。

圖4 正三角形繞重心旋轉效果(三)

由圖2、3或4可以看出,正三角形繞重心旋轉時,越小的三角形旋轉得越快。若將所有的正三角形都用同一種角速度進行旋轉,即簡單地修改語句 “ctx.rotate(i*j/(80*speed));”為“ctx.rotate(j/(80*speed));”,則在畫布中呈現出如圖5所示的正三角形旋轉效果。

圖5 正三角形繞重心旋轉效果(四)

若為旋轉的正三角形設定裁切區域,使得旋轉超出最外層三角形的部分均不可見。編寫如下的HTML檔案。

<!DOCTYPE html>

<html>

<head>

<title>旋轉的正三角形</title>

</head>

<body>

<canvas id="myCanvas" width="500" height="500" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas=document.getElementById('myCanvas');

ctx= canvas.getContext('2d');

var height=360;

var x0=250;

var y0=(500-height)/2-(height/7)+(height*2/3);

var count=24;

var speed=18;

ctx.lineWidth=2;

ctx.fillStyle="#FF3388";

ctx.strokeStyle="#FFFFFF";

var j = 0;

function draw()

{

ctx.clearRect(0,0,500,500);

ctx.save();

for (var i=0;i<=count;i++)

{

var nHeight = height-(height/count)*i;

ctx.beginPath();

ctx.moveTo(x0,y0-nHeight*2/3);

ctx.lineTo(x0+nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0-nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0,y0-nHeight*2/3);

ctx.closePath();

ctx.clip();

ctx.translate(x0,y0);

ctx.rotate(i*j/(80*speed));

ctx.translate(-x0,-y0);

ctx.beginPath();

ctx.moveTo(x0,y0-nHeight*2/3);

ctx.lineTo(x0+nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0-nHeight/Math.sqrt(3), y0+nHeight/3);

ctx.lineTo(x0,y0-nHeight*2/3);

ctx.closePath();

ctx.stroke();

ctx.fill();

};

ctx.restore();

j++;

if (j>1000) j=0;

}

function move()

{

draw();

requestAnimationFrame(move);

}

move();

</script>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中呈現出如圖6所示旋轉效果。

圖6 正三角形內的旋轉