前面我們已經(jīng)繪制好了太極圓,接下來就是要用JS來實現(xiàn)下面幾個功能:
點擊“加速/減速”按鈕實現(xiàn)太極圓的速度變化:
1.當(dāng)速度達(dá)到一定時,加速或減速按鈕便無法點擊
2.點擊停止按鈕后,太極圓停止,按鈕的值改為開始
3.在id為cycle的<span>元素中實現(xiàn)顯示太極圓的速度
當(dāng)我們打開網(wǎng)頁時,我們想看到太極圓已經(jīng)在旋轉(zhuǎn),且<span>中已經(jīng)有對應(yīng)的值。要實現(xiàn)旋轉(zhuǎn)我們就要知道需旋轉(zhuǎn)的原理:
我們通過使用rotate(Angle);方法來旋轉(zhuǎn)畫布的坐標(biāo)系,然后重新將太極圓畫到畫布上,就可以實現(xiàn)太極圓的旋轉(zhuǎn),so what?難道我們一直需要用上次的方法重新畫一個太極嘛?no no no!當(dāng)然不是了,我們可以把之前畫的太極圓保存下來,之后就只需要使用drawImage(image,x,y)方法就能將太極圖放到畫布上了。不過放圖片之前我們先用clearRect(x,y.width,height);方法將畫布已有內(nèi)容清除。那么問題來了,怎么樣才能保存原來畫好的圖片呢?
1,獲得太極圓的路徑
var imgURL=tua.toDataURL("image/png")
2,動態(tài)創(chuàng)建 img 元素
var image=document.createElement("img");
3.將獲得imgURL賦給image的src屬性
image.src = imgURL;
所以我們就已經(jīng)得到了太極圓的圖片引用image
function fang(){
tua.clearRect(-240,-240,480,480);
tua.rotate(-0.05);
tua.drawImage(image,-240,-240);}
于是我們就順利成章的寫出了旋轉(zhuǎn)一次的函數(shù),可是這好像不對???那有問題?首先我們得調(diào)用函數(shù)啊,不然無法動起來,而且調(diào)動一次函數(shù)肯定是不夠的,我們必須持續(xù)調(diào)動,自動調(diào)動函數(shù)執(zhí)行的函數(shù)有兩個:
setInterval(function,time)與setTimeout(function,time)
因為要一直持續(xù)調(diào)用函數(shù)fang();所以我們決定選擇setInterval(function,time);考慮到我們接下來,要實現(xiàn)旋轉(zhuǎn)速度的改變,我們把setInterval(function,time);賦值給一個變量auto:
var auto=self.setInterval(fang,time);
這樣就可以通過clearInterval(auto);方法來取消方法的自動調(diào)用。接著更改time的值,再調(diào)用var auto=self.setInterval(fang,time);我們就可以實現(xiàn)太極圓的旋轉(zhuǎn)速度。time表示自動調(diào)用函數(shù)的間隔時間,time越小,速度越快,time為數(shù)值類型,單位為ms(毫秒);
那么問題又來了,似乎全程沒有看見time的值啊,確實,我們應(yīng)該在一開始就聲明全局變量time.我們在函數(shù)外面聲明var time=20;(該聲明最好放在開頭)
即一打開網(wǎng)頁我們用20ms的時間間隔來調(diào)用fang函數(shù)。
那么我們這樣做到速度的實時更新呢?因為每次點擊按鈕都要改變值,所以我們最好把他封裝成一個函數(shù),與time類似我們把求出來的速度也提前在函數(shù)外面聲明:
var num_cycle =0;
同時因為要把這個值賦給id為cycle的<span>元素,我們就得先得到<span>元素的引用:
var cycle = document.getElementById("cycle");
function jisuan(){
num_cycle = 0.05*45/time*1000/360;
num_cycle = num_cycle.toFixed(2);
//取小數(shù)點后兩位
cycle.innerHTML = num_cycle;
//將計算得到的速度值放到<span>中
}
網(wǎng)頁加載后運行函數(shù)jisuan();
那么剩下的,我們就只要完成按鈕的動作時間就可以了
得到三個按鈕的引用:
var inc = document.getElementById("inc");
var dec = document.getElementById("dec");
var stopp = document.getElementById("stop");
在對按鈕分別設(shè)置動作事件:
function put(){
inc.onclick=function(){
if(time==4){
inc.disabled=true;
//當(dāng)time減小到4時,就無法再點擊加速按鈕
}
else{
if(time==36){
dec.disabled=false;
//如果time此時是36的話,點擊加速按鈕,減速按鈕便恢復(fù)成可點擊狀態(tài)
}
clearInterval(auto);
time -= 4;
//即time=time-4;
auto=self.setInterval(fan,time);
jisuan();
//更新<span>框內(nèi)的速度值
}
}
dec.onclick=function(){
if(time==36){
dec.disabled=true;
//當(dāng)time增加到36時,就無法再點擊減速按鈕
}
else{
if(time==4){
inc.disabled=false;
//如果time此時是36的話,點擊加速按鈕,減速按鈕便恢復(fù)成可點擊狀態(tài)
}
clearInterval(auto);
time += 4;
auto=self.setInterval(fan,time);
jisuan();
}
}
stopp.onclick=function(){
if(stopp.innerHTML=="停止"){
//當(dāng)按鈕名為停止時,我們點擊按鈕后,速度變?yōu)?
clearInterval(auto);
num_cycle = 0;
cycle.innerHTML = num_cycle;
stopp.innerHTML = "開始";
//將按鈕的內(nèi)容變?yōu)椤伴_始"
}
else{
jisuan();
auto=self.setInterval(fan,time);
stopp.innerHTML = "停止";}
}
}
put();
好了,大功告成,太極圓就這樣可以自由地旋轉(zhuǎn)了!?。?/p>
完整代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<style>
#message{
position: absolute;
left: 450px;
top: 50px;
width: 120px;
}
.message2{
display:inline-block;
width:60px;}
#cycle{
text-align:right;}
button{
height: 30px;
width: 60px;
margin-left: 75px;
}
</style>
<title>無標(biāo)題文檔</title>
</head>
<body>
<canvas id="canvas" width="480px" height="480px"></canvas>
<span id="message"><span id="cycle" class="message2"></span><span class="message2">:圈/秒</span></span>
<br>
<button id="inc">加速</button>
<button id="dec">減速</button>
<button id="stop">停止</button>
<script>
var taiji=document.getElementById("canvas");
var cycle = document.getElementById("cycle");
var inc = document.getElementById("inc");
var dec = document.getElementById("dec");
var stopp = document.getElementById("stop");
var time=20;
var num_cycle =0;
var tua=taiji.getContext("2d");
tua.beginPath();
tua.translate(240,240);
tua.moveTo(0,-200);
tua.arc(0,-100,100,3/2*Math.PI,1/2*Math.PI,true);
tua.arc(0,100,100,3/2*Math.PI,1/2*Math.PI,false);
tua.arc(0,0,200,1/2*Math.PI,3/2*Math.PI,true);
tua.fillStyle = "black";
tua.fill();
tua.arc(0,0,200,3/2*Math.PI,1/2*Math.PI,true);
tua.stroke();
tua.closePath();
tua.beginPath();
tua.arc(0,-100,20,0,2*Math.PI,true);
tua.fillStyle = "white";
tua.fill();
tua.stroke();
tua.closePath();
tua.beginPath();
tua.arc(0,100,20,0,2*Math.PI,true);
tua.fillStyle = "black";
tua.fill();
tua.stroke();
tua.closePath();
var imgURL=taiji.toDataURL("image/png");
var image=document.createElement("img");
image.src = imgURL;
function fang(){
tua.clearRect(-240,-240,480,480);
tua.rotate(-0.05);
tua.drawImage(image,-240,-240);}
var auto=self.setInterval(fang,time);
function jisuan(){
num_cycle = 0.05*45/time*1000/360;
num_cycle = num_cycle.toFixed(2);
cycle.innerHTML = num_cycle;
}
jisuan();
function put(){
inc.onclick=function(){
if(time==4){
inc.disabled=true;
}
else{
if(time==36){
dec.disabled=false;
}
clearInterval(auto);
time -= 4;
auto=self.setInterval(fang,time);
jisuan();
}
}
dec.onclick=function(){
if(time==36){
dec.disabled=true;
}
else{
if(time==4){
inc.disabled=false;
}
clearInterval(auto);
time += 4;
auto=self.setInterval(fang,time);
jisuan();
}
}
stopp.onclick=function(){
if(stopp.innerHTML=="停止"){
clearInterval(auto);
num_cycle = 0;
cycle.innerHTML = num_cycle;
stopp.innerHTML = "開始";
}
else{
jisuan();
auto=self.setInterval(fang,time);
stopp.innerHTML = "停止";}
}
}
put();
</script>
</body>
</html>