神奇的 Canvas

最近在瀏覽掘金網站的時候看到掘金小冊中有一個頗有(便)意(宜)思的冊子:如何使用 Canvas 製做出炫酷的網頁背景特效,便想到給個人博客添加一個炫酷的背景。順便學習一下 canvas 這個元素的使用。html

效果

最終效果就在博客上就能看到啦。下面來講一下實現方式。android

實現

建議對 canvas 還不瞭解的同窗去掘金小冊上學習學習,我這裏再也不講解。canvas

個人博客是用 Hexo 搭建的,使用了 Archer 主題,博客的最上層樣式做者定義在 layout.ejs 文件裏。數組

<!DOCTYPE html>
<html>
   ...
    <div class="wrapper">
        ...
    </div>
    ...
</html>
複製代碼

既然是在 canvas 裏面畫炫酷的背景,那就須要在這裏添加一個 canvas 元素,而且和 div:class="wrapper" 同樣大。bash

改造 layout.ejs 文件,用一個 div 將 div:class="wrapper" 和咱們的 canvas 包裹起來:app

<!DOCTYPE html>
<html>
    ...
    <div id="container-wrapper-canvas" style="position:relative;">
        <div class="wrapper">
        ...
        </div>
        <canvas id="myCanvas" style="position:absolute;left:0;top:0;z-index:0;pointer-events:none;" />
        <script>
        </script>
        ...
    </div>
    ...
</html>
複製代碼

由於不想讓 canvas 響應點擊事件,因此在它的 style 裏面加上:dom

pointer-events:none;
複製代碼

先定義一些變量(如下代碼一股腦塞到 script 標籤裏就行啦)。函數

// 屏幕寬高
let container = document.getElementById('container-wrapper-canvas')
let WIDTH = container.offsetWidth
let HEIGHT = container.offsetHeight
// canvas
let canvas = document.getElementById('myCanvas')
let context = canvas.getContext('2d')
// 圓點數量
let roundCount = HEIGHT / 10
// 存放遠點屬性的數組
let round = []

// 令 canvas 鋪滿屏幕
canvas.width = WIDTH
canvas.height = HEIGHT
複製代碼

構造圓點位置顏色大小等屬性學習

// 構造圓點位置顏色大小等屬性
function roundItem(index, x, y) {
    this.index = index
    this.x = x
    this.y = y
    this.r = Math.random() * 4 + 1
    let alpha = (Math.floor(Math.random() * 5) + 1) / 10 / 2
    this.color = "rgba(0,0,0," + alpha + ")"
}
複製代碼

畫圓點動畫

// 畫圓點
roundItem.prototype.draw = function() {
    context.fillStyle = this.color
    context.shadowBlur = this.r * 2
    context.beginPath()
    context.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false)
    context.closePath()
    context.fill()
}
複製代碼

這裏看着很熟悉,在作 android、iOS 開發自定義 View 的時候就遇到過相似的代碼,在 draw() 函數裏畫圖,這裏我想到能夠在移動端使用相似的方法畫出相似的背景。

這個時候調用初始化函數就能夠看到靜態的一個個小圓點了

// 調用初始化函數
init();
function init() {
    for(var i = 0; i < roundCount; i++ ){
        round[i] = new roundItem(i,Math.random() * WIDTH,Math.random() * HEIGHT);
        round[i].draw();
    }
    animate()
}
複製代碼

爲了讓小圓點動起來,咱們寫下面的函數。

// 移動圓點
roundItem.prototype.move = function () {
    // y方向移動速度與圓點半徑成正比
    this.y -= this.r / 20

    // x方向移動分兩個方向,移動速度與圓點半徑成正比
    if (this.index % 2 == 0) {
        this.x -= 0.08
    } else {
        this.x += this.r / 40
    }

    // 若是超出範圍就把它拉回來
    if (this.y <= 0) {
        this.y += HEIGHT
    }
    if (this.x <= 0) {
        this.x += WIDTH
    }
    if (this.x >= WIDTH) {
        this.x -= WIDTH
    }

    this.draw()
}
複製代碼
// 定義動畫
function animate() {
    context.clearRect(0, 0, WIDTH, HEIGHT);
    for (var i in round) {
        round[i].move()
    }
    requestAnimationFrame(animate)
}
複製代碼

這個時候就能夠看到動態的一個個小圓點了。

是否是很炫酷呢,有空我再將它改造得更炫酷一點。

相關文章
相關標籤/搜索