用canvas給自己的博客園加背景(二)


canvas入門(二)

前一篇大概介紹了canvas繪圖的一些基礎API,本文來介紹動畫的部分,canvas最關鍵的函數是requestAnimationFrame(callback)

注:本文面向canvas入門人員,寫的如有紕漏請指出,不喜勿噴。

requestAnimationFrame(callback)

這是一個用於制作逐幀動畫的函數,在它出現之前,我們的動畫基本用setTimeout或者setInterval制作。

我們可以嘗試聲明一個animate函數:

//這個函數會在控制台無限輸出"dkplus-canvas"
(function animate() {
    requestAnimationFrame(animate);
    console.log("dkplus-canvas");
})();

此時打開控制台看一下效果。

可以看到animate()里面的操作在無限執行,而我們用canvas繪制動畫也可以選擇這樣的思路,無限刷新畫布,無限繪制畫布。

    ctx.arc(100,100,40,0,Math.PI*2,false);
    ctx.stroke();
(function animate() {
    requestAnimationFrame(animate);
    //在同一個坐標無限循環畫一個圓
    //重新定義開始坐標,試着注釋掉這一行看看效果有何不同
    ctx.beginPath();
    ctx.arc(100,100,40,0,Math.PI*2,false);
    ctx.stroke();
})();

這段代碼畫出來的圓和只畫一次的圓是有區別的,明顯很多個圓疊加在一起了。

我們試着改一改代碼:

//初始化坐標
var x = 100;
var y = 100;
(function animate() {
    requestAnimationFrame(animate);
    //重新定義開始坐標,試着注釋掉這一行看看效果有何不同
    ctx.beginPath();
    ctx.arc(x,y,40,0,Math.PI*2,false);
    ctx.stroke();
    //動態修改坐標
    x += 1;
    y += 1;
})();

刷新畫布

可以看到,這個圖確實是動起來了,但是前面的圖像沒有被清除,而是簡單的圖像覆蓋。所以我們要在每次繪圖之前先清楚畫布,使用clearRect()這個函數(可以說是canvas的橡皮擦)。

和fillRect(),strokeRect()參數一樣,clearRect(x坐標,y坐標,寬度,高度):

var x = 100;
var y = 100;
(function animate() {
    requestAnimationFrame(animate);
    //這是我們加入的橡皮擦函數
    ctx.clearRect(0,0,innerWidth,innerHeight);
    ctx.beginPath();
    ctx.arc(x,y,40,0,Math.PI*2,false);
    ctx.stroke();
    x += 1;
    y += 1;
})();

保存打開瀏覽器,效果確實不一樣了,看到的是一個圓圈在運動。

反彈條件

但是這個圓圈只會斜向下走,我們得做一些判斷,讓它反彈回來。比如說當圓心+半徑超出瀏覽器邊界時,我們把x+=1變為x+= -1。這里的1其實代表着速度,我們可以把速度儲存到一個變量里,方便修改。

//我把參數都設為變量
var x = 100;
var y = 100;
var dx = 6;
var dy = 6;
var radius = 40;
(function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,innerWidth,innerHeight);
    ctx.beginPath();
    ctx.arc(x,y,radius,0,Math.PI*2,false);
    ctx.stroke();
    //當觸及邊界時進行反彈
    if (x+radius>innerWidth || x-radius<0) {
        dx = -dx;
    }
    if (y+radius>innerHeight || y-radius<0) {
        dy = -dy;
    }
    x += dx;
    y += dy;
})();

既然都設了變量,為何不讓變量變起來呢?設為隨機數可好?

//半徑暫且不設隨機,以后有用
var x = Math.random()*innerWidth;
var y = Math.random()*innerHeight;
var dx = Math.random()*5;
var dy = Math.random()*5;
var radius = Math.random()*40;
})();

面向對象

本人對面向對象這塊不太熟,可能說的不太好請見諒

好,現在我們聲明一個function為Circle,假裝我們有一個Circle類,把這些變量傳進去,同時把我們剛才用於繪圖的、用於刷新的代碼都填進去。

var x = Math.random()*innerWidth;
var y = Math.random()*innerHeight;
var dx = Math.random()*5;
var dy = Math.random()*5;
var radius = 40;
//這是一個Circle對象
function Circle(x,y,dx,dy,radius) {
    this.x = x;
    this.y = y;
    this.dx = dx;
    this.dy = dy;
    this.raidus = radius;
    //這是繪制方法
    this.draw = function () {
        ctx.beginPath();
        ctx.arc(x,y,radius,0,Math.PI*2,false);
        ctx.stroke();
    }
    //這是刷新方法
    this.update = function () {
        if (x+radius>innerWidth || x-radius<0) {
            dx = -dx;
        }
        if (y+radius>innerHeight || y-radius<0) {
            dy = -dy;
        }
        x += dx;
        y += dy;
        //每刷新一次重新繪圖
        this.draw();
    }
}
//new一個Circle對象
var c = new Circle(x,y,dx,dy,radius);
function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,innerWidth,innerHeight);
    //對象c調用刷新方法
    c.update();
};
animate();

多圓

現在我們已經實現了一個圓在畫布上的彈跳,那么我們要怎么實現很多圓彈跳呢?

我們可以用for循環,循環隨機參數,循環制造圓,循環刷新不同的圓。那么我們先引進一個圓的數組,一切都是為了方便操作:

//圓的數組
var cirleArray = [];
//循環制造不同的圓,放進數組
for (var i = 0; i < 100; i++) {
    var x = Math.random()*innerWidth;
    var y = Math.random()*innerHeight;
    var dx = Math.random()*5;
    var dy = Math.random()*5;
    var radius = 40;
    cirleArray.push(new Circle(x,y,dx,dy,radius));
}
function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,innerWidth,innerHeight);
    //循環刷新不同的圓
    for (var i = 0; i < cirleArray.length; i++) {
        cirleArray[i].update();
    }
};
animate();

這篇就介紹到這里,大家有興趣可以試試,下一篇我們講怎么用canvas進行交互。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM