Canvas之"黑客帝國"

首先,在新建頁面寫上canvas標籤,在js中獲取並設置高寬:

<canvas id="canvas"></canvas>
<script>
    var canvas = document.getElementById("canvas"),
            ctx = canvas.getContext("2d");

    //設置canvas大小,全屏顯示
    setSize();

    //設置大小的函數
    function setSize(){
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

canvas標籤設置完了之後,然後再來設置一個數組,也就是從屏幕上掉落出來哪些文字,當然這裏設置什麼都可以,我設置的是0~9、a~z,爲了簡單我就是使用了split方法將字符串轉換爲數組:

var txt = "0123456789abcdefghijklmnopqrstuvwxyz";
var arr = txt.split("");
  • 1
  • 2
  • 1
  • 2

接下來就該設置一下字體的大小和屏幕總共能容納多少列了,這裏我把字體大小設置爲16px,爲了方便計算這裏先設置爲16,然後用瀏覽器的寬度除以字體大小,就能計算出來屏幕可以容納多少列文字,還需要設置一個數組,來保存每一列中的文字該在哪裏繪製,當然每列第一個字都是從屏幕最上面開始,需要初始化一下:

//字體大小
var font_size = 16;
//多少列,整數
var column = Math.floor(canvas.width / font_size) ;
//每列文字繪製點
var drop = [];
//初始化數組
for(let i = 0;i<column ; i++){
    drop[i] = 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

剛剛忘了一點,沒有設置onresize,這裏設置一下,當然這個在什麼時候設置都是可以的,在window上添加onresize事件,瀏覽器窗口改變時重新計算canvas的大小:

window.onresize = function(){
    setSize();
}

function setSize(){
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

現在準備工作都完成了,接下來就開始繪製文字效果吧,前面已經定義了數組,現在需要從數組中隨機取得一個數字,通過Math.random()產生隨機數獲取,輸出文字時使用fillText()可以在指定位置輸出文字,當每一列中繪製的文字超過瀏覽器的高度時,則從0開始重新繪製,當然如果所有的列都是在佔滿瀏覽器高度再重新繪製時這樣的效果並不好看,所以我們需要一個隨機數,當隨機數大於0.9的時候就重新繪製,繪製完每一列文字的時候,需要保存一下下一次該列文字該在什麼地方出現:

//逐行輸出文字
for (var i = 0; i < drops.length; i++) {
    //隨機取要輸出的文字
    var text = txts[Math.floor(Math.random() * txts.length)];
    //輸出文字,注意座標的計算
    ctx.fillText(text, i * font_size, drops[i] * font_size);

    //如果繪滿一屏或隨機數大於0.95(此數可自行調整,效果會不同)
    if (drops[i] * font_size > c.height || Math.random() > 0.95){
        drops[i] = 0;
    }
    //用於Y軸座標增加
    drops[i]++;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在上面這個循環之前爲了讓效果更好看,我們需要讓背景透明度逐漸變化,並且還需要設置好字體,所以整個draw()函數如下:

//輸出文字
function draw() {
    //讓背景逐漸由透明到不透明
    ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
    ctx.fillRect(0, 0, c.width, c.height);

    ctx.fillStyle = "#0F0"; //文字顏色
    ctx.font = font_size + "px arial";
    //逐行輸出文字
    for (var i = 0; i < drops.length; i++) {
        //隨機取要輸出的文字
        var text = txts[Math.floor(Math.random() * txts.length)];
        //輸出文字,注意座標的計算
        ctx.fillText(text, i * font_size, drops[i] * font_size);

        //如果繪滿一屏或隨機數大於0.95(此數可自行調整,效果會不同)
        if (drops[i] * font_size > c.height || Math.random() > 0.95){
            drops[i] = 0;
        }

        //用於Y軸座標增加
        drops[i]++;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

接下來只要讓它不斷的循環繪製就可以了:

init();

//初始化
function init(){
    setSize();
    setInterval(draw,50);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然後整個絢麗的效果就完成了,是不是很簡單呢。

下面是整個代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>黑客帝國</title>
    <style>
        *{
            padding: 0;
            margin:0;
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
    var canvas = document.getElementById("canvas"),
            ctx = canvas.getContext("2d");
    setSize();
    var arr = "0123456789abcdefghijklmnopqrstuvwxyz".split("");
    var font_size = 16;
    var column = Math.floor(canvas.width / font_size) ;
    var drop = [];
    for(let i = 0;i<column ; i++){
        drop[i] = 1;
    }

    init();

    //初始化
    function init(){
        setSize();
        setInterval(draw,50);
    }

    //輸出文字
    function draw(){
        ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
        ctx.fillRect(0,0,canvas.width,canvas.height);

        ctx.fillStyle = "#0F0";  //文字顏色
        ctx.font = font_size + "px arial";

        //逐行輸出文字
        for(var i = 0;i<drop.length ; i++){
            //隨機輸出文字
            var text = arr[Math.floor(Math.random()*arr.length)];

            //輸出文字,座標重新計算
            ctx.fillText(text,i*font_size, drop[i]*font_size);

            //如果繪滿一頁或者隨機數超過0.9則重新繪製
            if(drop[i] * font_size >canvas.height || Math.random() > 0.9){
                drop[i] = 0;
            }
            drop[i] ++ ;
        }
    }

    window.onresize = function(){
        setSize();
    }

    function setSize(){
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
</script>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章