JavaScript動畫例項:圓點的衍生
考慮如下的曲線方程:
R=S*sqrt(n)
α=n*θ
X=R*SIN(α)
Y=R*COS(α)
其中,S和θ可指定某一個定值。對n迴圈取0~999共1000個值,對於每個n,按照給定的座標方程,求得一個座標值(x,y),然後以(x,y)為圓心繪製一個半徑為6的圓,可以得到一個螺旋狀的圖形。
編寫如下的HTML程式碼。
<html>
<head>
<title>衍生的圓點</title>
</head>
<body>
<canvas id="myCanvas" width="600" height="600" style="border:3px double #996633;">
</canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var scale = 10;
var theta = 30;
for (n=0;n<1000;n++)
{
var radius = scale * Math.sqrt(n);
var angle = n * theta * (Math.PI / 180);
var x = radius * Math.cos(angle) + canvas.width / 2;
var y = radius * Math.sin(angle) + canvas.height / 2;
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
ctx.fillStyle ='rgba(255,50,50,0.9)';
ctx.fill();
}
</script>
</body>
</html>
在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在畫布中繪製出如圖1所示的圖案。
圖1 scale = 10,theta = 30時繪製的圖案
若將上面程式中的語句“var theta = 30; ”改寫為“var theta =60; ”,其餘部分保持不變,則在畫布中繪製出如圖2所示的圖案。
圖2 scale = 10,theta = 60時繪製的圖案
在程式中,theta代表每個小圓圓心相對於上一個小圓圓心的偏移角度。一個圓周360°,因此當theta = 30時,會繪製出360/30=12條放射狀的線,如圖1所示;當theta =60時,會繪製出360/60=6條放射狀的線,如圖2所示。
若將上面程式中的語句“var theta = 30; ”改寫為“var theta =110; ”,其餘部分保持不變,則在畫布中繪製出如圖3所示的圖案。
圖3 scale = 10,theta =110時繪製的圖案
若再將程式中的語句“var scale = 10; ”改寫為“var scale =6; ”,則在畫布中繪製出如圖4所示的圖案。
圖4 scale = 6,theta =110時繪製的圖案
若將程式中的語句“var scale = 10; ”改寫為“var scale =15; ”,則在畫布中繪製出如圖5所示的圖案。
圖5 scale = 15,theta =110時繪製的圖案
對比圖3、4、5可知,scale的值可以可知各小圓的疏密程度。
將上面程式中1000個小圓的繪製過程動態展示出來,編寫如下的HTML檔案。
<html>
<head>
<title>衍生的圓點</title>
</head>
<body>
<canvas id="myCanvas" width="600" height="600" style="border:3px double #996633;background:black;">
</canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var hue = 0;
var scale = 10;
var n = 0;
var theta = 30;
function draw()
{
var radius = scale * Math.sqrt(n);
var angle = n * theta * (Math.PI / 180);
var x = radius * Math.cos(angle) + canvas.width / 2;
var y = radius * Math.sin(angle) + canvas.height / 2;
hue++;
if (hue >= 360) hue = 0;
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
ctx.fill();
n++;
if (n>=1000)
{
ctx.clearRect(0,0,canvas.width,canvas.height);
n=0;
}
}
setInterval("draw()",20);
</script>
</body>
</html>
在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中呈現出如圖6所示的動畫效果。
圖6 scale = 10,theta = 30時圓點衍生效果
更改scale和theta的值,會產生不同的圓點衍生效果。例如,修改scale=12,theta=137.5,則在瀏覽器視窗中呈現出如圖7所示的動畫效果。
圖7 scale = 12,theta = 137.5時圓點衍生效果
更進一步,我們將上面程式中的控制圓點疏密程度的引數scale和每次迭代偏移角度theta採用隨機數的方式確定其值。編寫如下的HTML程式碼。
<html>
<head>
<title>衍生的圓點</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;background:black;"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var hue = 0;
var scale = 12;
var n = 0;
var theta = 137.5;
function rand(min,max)
{
return Math.floor(Math.random()*(max-min)+min)+(Math.random()>0.5?0.5:0);
}
function draw()
{
var radius = scale * Math.sqrt(n);
var angle = n * theta * (Math.PI / 180);
var x = radius * Math.cos(angle) + canvas.width / 2;
var y = radius * Math.sin(angle) + canvas.height / 2;
hue++;
if (hue >= 360) hue = 0;
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
ctx.fill();
n++;
if (n>=500)
{
ctx.clearRect(0,0,canvas.width,canvas.height);
scale=rand(6,15);
theta=rand(20,170);
n=0;
}
}
setInterval("draw()",20);
</script>
</body>
</html>
在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中呈現出如圖8所示的動畫效果。
圖8 圓點的衍生動畫特效&n