本篇博文經過製做一個小球運動動畫的實例,來學習在HTML5的畫布上實現動畫製做的方法,同時理解面向對象程序設計的基本思想。javascript
先在HTML頁面中設置一個畫布。html
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">java
</canvas>canvas
再將小球畫在canvas(畫布)上面。瀏覽器
可編寫以下的HTML代碼。函數
<!DOCTYPE html>學習
<head>測試
<title>運動的小球(一)</title>動畫
</head>this
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x=100, y=100,radius=25;
context.beginPath();
context.arc(x, y, radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "blue";
context.fill();
</script>
</body>
</html>
其中,變量x、y、radius分別是小球的圓心座標(x,y)和半徑radius。
將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色的小球。這個小球沒有什麼特別的,其實是一個簡單的圓形,用arc()函數繪製出來的。
添加一個animation函數,在函數中先用clearRect 清理掉畫布裏以前的小球圓形,而後從新繪製小球,以後修改小球的圓心座標。再用window.requestAnimationFrame()控制動畫。
設小球x座標軸(水平方向)的移動速度爲xspeed、y座標軸(豎直方向)的移動速度爲yspeed,則修改小球圓心座標的方法爲:x += xspeed; y +=yspeed; 。
從新編寫的HTML代碼以下。
<!DOCTYPE html>
<head>
<title>運動的小球(二)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x=100, y=100, xspeed=5, yspeed=1, radius=25;
function animation()
{
context.clearRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.arc(x, y, radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "blue";
context.fill();
x += xspeed;
y += yspeed;
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色的小球在運動。
在瀏覽器中打開添加了animation函數的html文件,會發現小球很快會移出畫布。這是因爲animation函數中沒有進行邊界碰撞測試,所以,須要在修改小球圓心座標後,判斷小球按新的圓心座標繪製時是否會超出畫布的尺寸,並控制相應的速度量反轉(增量變減量或者減量變增量)。修改後的animation函數以下:
function animation()
{
context.clearRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.arc(x, y, radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "blue";
context.fill();
x += xspeed;
y += yspeed;
if (y+radius>=canvas.height || y-radius<=0)
yspeed = -yspeed;
if (x+ radius >= canvas.width || x-radius<= 0)
xspeed = -xspeed;
window.requestAnimationFrame(animation);
}
修改animation函數後,完整的HTML文件內容以下:
<!DOCTYPE html>
<head>
<title>運動的小球(三)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x=100, y=100, xspeed=5, yspeed=1, radius=25;
function animation()
{
context.clearRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.arc(x, y, radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "blue";
context.fill();
x += xspeed;
y += yspeed;
if (y+radius>=canvas.height || y-radius<=0)
yspeed = -yspeed;
if (x+ radius >= canvas.width || x-radius<= 0)
xspeed = -xspeed;
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色的小球在運動,而且小球在碰撞到邊界後,會改變方向,這樣小球繼續在框中運動,不會出界。
分別用 var x1=100, y1=100, xspeed1=5, yspeed1=1, radius1=25;
var x2=50, y2=50, xspeed2=3, yspeed2=1, radius2=15;來表示兩個小球的數據。
而後將animation函數中有關小球的繪製和座標修改語句複製一次並修改相應的變量名便可。
修改後的HTML代碼以下。
<!DOCTYPE html>
<head>
<title>運動的小球(四)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x1=100, y1=100, xspeed1=5, yspeed1=1, radius1=25;
var x2=50, y2=50, xspeed2=3, yspeed2=1, radius2=15;
function animation()
{
context.clearRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.arc(x1, y1, radius1, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "blue";
context.fill();
context.beginPath();
context.arc(x2, y2, radius2, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = "red";
context.fill();
x1 += xspeed1;
y1 += yspeed1;
if (y1+radius1>=canvas.height || y1-radius1<=0)
yspeed1 = -yspeed1;
if (x1+ radius1 >= canvas.width || x1-radius1<= 0)
xspeed1 = -xspeed1;
x2 += xspeed2;
y2 += yspeed2;
if (y2+radius2>=canvas.height || y2-radius2<=0)
yspeed2 = -yspeed2;
if (x2+ radius2 >= canvas.width || x2-radius2<= 0)
xspeed2 = -xspeed2;
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色和一個紅色的小球在運動。
按上面的方法,若是再增長一個或多個小球,相應的代碼會複製屢次。實際上,小球是一個對象,它包括圓心座標(x,y)、半徑radius、水平方向的移動速度xspeed、豎直方向的移動速度yspeed和小球顏色等屬性,以及繪製小球和小球移動一步(指圓心座標變化)等操做。顯然,將小球能夠定義爲一個對象更合適。
採用構造函數的方法定義小球對象的HTML代碼以下。
<!DOCTYPE html>
<head>
<title>運動的小球(五)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// 定義小球對象
function Ball(x,y,xspeed,yspeed,radius,color){
this.x=x;
this.y=y;
this.xspeed=xspeed;
this.yspeed=yspeed;
this.radius=radius;
this.color=color;
this.draw=function()
{
context.beginPath();
context.arc(this.x,this.y,this.radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle =this.color;
context.fill();
}
this.step=function()
{
this.x += this.xspeed;
this.y += this.yspeed;
if (this.y+this.radius>=canvas.height || this.y-this.radius<=0)
this.yspeed = -this.yspeed;
if (this.x+ this.radius >= canvas.width || this.x-this.radius<= 0)
this.xspeed = -this.xspeed;
}
}
// 建立三個小球
var ball1=new Ball(100,100,5,3,25,"#0000FF");
var ball2=new Ball(50, 40,3,1,20,"#FF0000");
var ball3=new Ball(30, 30, 3, 2, 15,"#00FFFF");
function animation()
{
context.clearRect(0,0,canvas.width,canvas.height);
ball1.draw();
ball2.draw();
ball3.draw();
ball1.step();
ball2.step();
ball3.step();
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色、一個紅色和一個青色的三個小球在運動。
採用對象後,增長一個運動小球就很方便了,只需先建立一個小球對象
var ball4=new Ball(10, 20, 3, 2, 15,"#FFFF00");
再添加兩條語句 ball4.draw();和 ball4.step();便可。
若是將animation函數中的語句 context.clearRect(0,0,canvas.width,canvas.height);改寫爲以下兩條語句:
context.fillStyle = 'rgba(255,255,255,0.3)';
context.fillRect(0,0,canvas.width,canvas.height);
這樣在清除前一幀動畫時,因爲是用一個半透明的fillRect函數填充畫布,能夠爲每一個小球增長一個長尾效果。
添加了長尾效果的小球運動動畫HTML文檔內容以下:
<!DOCTYPE html>
<head>
<title>運動的小球(六)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// 定義小球對象
function Ball(x,y,xspeed,yspeed,radius,color){
this.x=x;
this.y=y;
this.xspeed=xspeed;
this.yspeed=yspeed;
this.radius=radius;
this.color=color;
this.draw=function()
{
context.beginPath();
context.arc(this.x,this.y,this.radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle =this.color;
context.fill();
}
this.step=function()
{
this.x += this.xspeed;
this.y += this.yspeed;
if (this.y+this.radius>=canvas.height || this.y-this.radius<=0)
this.yspeed = -this.yspeed;
if (this.x+ this.radius >= canvas.width || this.x-this.radius<= 0)
this.xspeed = -this.xspeed;
}
}
// 建立三個小球
var ball1=new Ball(100,100,5,3,25,"#0000FF");
var ball2=new Ball(50, 40,3,1,20,"#FF0000");
var ball3=new Ball(30, 30, 3, 2, 15,"#00FFFF");
function animation()
{
context.fillStyle = 'rgba(255,255,255,0.3)';
context.fillRect(0,0,canvas.width,canvas.height);
ball1.draw();
ball2.draw();
ball3.draw();
ball1.step();
ball2.step();
ball3.step();
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色、一個紅色和一個青色的三個小球在運動,而且每一個小球運動時帶有長尾效果,如圖1所示。
圖1 帶有長尾效果的運動小球
爲了對小球運動的開始和結束進行控制,能夠在頁面中增長「開始」和「中止」兩個按鈕,單擊相應的按鈕產生相應的操做。
添加按鈕操做後的HTML代碼以下。
<!DOCTYPE html>
<head>
<title>運動的小球(七)</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="border:3px double #996633;">
</canvas>
<br/><input id="start" type="button" value="開始">
<input id="stop" type="button" value="中止">
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var handle=0;
// 定義小球對象
function Ball(x,y,xspeed,yspeed,radius,color){
this.x=x;
this.y=y;
this.xspeed=xspeed;
this.yspeed=yspeed;
this.radius=radius;
this.color=color;
this.draw=function()
{
context.beginPath();
context.arc(this.x,this.y,this.radius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle =this.color;
context.fill();
}
this.step=function()
{
this.x += this.xspeed;
this.y += this.yspeed;
if (this.y+this.radius>=canvas.height || this.y-this.radius<=0)
this.yspeed = -this.yspeed;
if (this.x+ this.radius >= canvas.width || this.x-this.radius<= 0)
this.xspeed = -this.xspeed;
}
}
// 建立三個小球
var ball1=new Ball(100,100,5,3,25,"#0000FF");
var ball2=new Ball(50, 50,3,1,20,"#FF0000");
var ball3=new Ball(20, 20, 3, 2, 15,"#00FFFF");
ball1.draw();
ball2.draw();
ball3.draw();
function animation()
{
context.fillStyle = 'rgba(255,255,255,0.3)';
context.fillRect(0,0,canvas.width,canvas.height);
ball1.draw();
ball2.draw();
ball3.draw();
ball1.step();
ball2.step();
ball3.step();
handle=window.requestAnimationFrame(animation);
}
var running=false;
var startBtn=document.getElementById('start');
var stopBtn=document.getElementById('stop');
startBtn.addEventListener('click', function () {
if (!running)
{
handle=requestAnimationFrame(animation);
running=true;
}
});
stopBtn.addEventListener('click', function () {
cancelAnimationFrame(handle);
handle=null;
running=false;
});
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,能夠看到在瀏覽器窗口中出現一個藍色、一個紅色和一個青色的三個小球,這三個小球初始時靜止。單擊「開始」按鈕後,小球開始運動,單擊「中止」按鈕,小球中止運動,在當前位置靜止不動。再單擊「開始」按鈕,小球又開始運動。