車大棒淺談for循環+canvas實現黑客帝國矩形陣

背景:
一日在網上閒逛的之時,忽然看到一個利用JQ插件實現canvas實現的電影黑客帝國的小Demo。以爲創意不錯,就下載下來研究一下。html

黑客帝國開場動畫效果Demo

網上瀏覽jQuery的寫法

$(document).ready(function() {
        var s = window.screen;
        var width = q.width = s.width;
        var height = q.height;
        var yPositions = Array(300).join(0).split('');
        var ctx = q.getContext('2d');

        var draw = function() {
            ctx.fillStyle = 'rgba(0,0,0,.05)';
            ctx.fillRect(0, 0, width, height);
            ctx.fillStyle = 'red';
            ctx.font = '10pt Georgia';
            yPositions.map(function(y, index) {
                text = String.fromCharCode(1e2 + Math.random() * 33);
                x = (index * 10) + 10;
                q.getContext('2d').fillText(text, x, y);
                if(y > Math.random() * 1e4) {
                    yPositions[index] = 0;
                } else {
                    yPositions[index] = y + 10;
                }
            });
        };
        RunMatrix();

        function RunMatrix() {
            Game_Interval = setInterval(draw, 1000);

        }
    });

全程100行不到的代碼,主體的核心就是定時器調用canvas進行繪畫處理。要是讓我這種段子手來寫,估計我把敲爛鍵盤都想不出這樣營造效果。藝術細胞真的很重要咕~~(╯﹏╰)
jquery

老王:「等等大棒!不是說js+canvas實現黑客帝國矩形雨,但是你這個附上的代碼分明是jQ+canvas.git

老管:"就是!你這個標題汪,這是又要搞事情呀!"github

我:「別急呀!這個jQ+canvas由於網上不少人博客都有寫,因此這邊只是附上一下jQ代碼供你們參考。下面纔是我今天要經過for循環代替上面的map()來實現的!!canvas

夫子:別淨扯理由,你是根本就不會map()用法!!」數組

老齊: "淨說什麼大實話!大棒是根本看不懂......"瀏覽器

我:.........好吧!大家說對了,個人確是不會map()方法。(讓我蹲牆角哭會/((╥╯^╰╥)微信

大家開心就好

萬能for循環的寫法

好了不扯犢子了,言歸正傳。讓咱們回到下面要講的代碼上面來。dom

一、基本準備工做

1.一、HTML骨架部分字體

<canvas id="hacker" width="500" height="500">請使用Google瀏覽器或者IE9以上</canvas>

1.二、JavaScript部分

var hacker = document.getElementById("hacker");
var width = hacker.width = screen.width;  //screen.width拿到是當前屏幕寬度
var height = hacker.height;
var ctx = haceker.getContext('2d');

作完這幾步以後,咱們就可以拿到當前屏幕的寬度、以及canvas畫布的寬度和獲得canvas畫布的上下文。

二、數組的準備
var num = Math.ceil(width / 10);
var y = Array(num).join(0).split('');

這裏估計有人會詢問了,這裏建立一個數組是幹嗎。爲何數組的length >= num?

O(∩_∩)O哈哈~,彆着急,後面的代碼就會個你們逐一解釋了。

不要激動,先安靜的當一個美男子!

不要激動,先安靜的當一個美男子!

三、定義一個重複調用核心draw()方法
var draw = function() {
    ctx.fillStyle = 'rgba(0,0,0,.05)';   //創意核心語句之一
    ctx.fillRect(0, 0, width, height);
    ctx.fillStyle = '#0f0';
    ctx.font = '10px Microsoft YaHei';
    for(i = 0; i < y.length; i++) {
        var x = (i * 10) + 10;
        text = String.fromCharCode(1e2 + Math.random() * 33);
        var y1 = y[i];
        ke.getContext('2d').fillText(text, x, y1);
        console.log(height);
        if(y1 > Math.random() * 10 * height) {
            y[i] = 0;
        } else {
            y[i] = parseInt(y[i]) + 10;
        }
    }
}

3.一、ctx繪畫過程解釋

ctx.fillStyle = 'rgba(0,0,0,.05)';    //創意核心語句之一
ctx.fillRect(0, 0, width, height);

這裏爲設定的區域鋪上一個rgba(0,0,0,.05) 這樣黑色半透明的背景。

ctx.fillStyle = '#0f0';
ctx.font = '10px Microsoft YaHei';

這裏就是畫出大小爲 10px,字體爲微軟雅黑的字體。

兩行代碼看起來就是很普通的代碼,可是組合起來卻發生一個的變化。

爲何會有層次感呢?要知道getContext('2d')這句語句,就決定了canvas只能繪製2D圖像,不能繪製3D層次感的圖形!

答案就在 ctx.fillStyle = 'rgba(0,0,0,.05)';上面,當重複調用方法的時候,這種半透明的灰黑色背景就會蓋在以前的畫好綠色文字上面。所以所以就形成了有文字是綠色,有的文字變成灰綠色。

各個文字之間造成一種視覺差,從而讓人感受到3D立體矩形代碼陣效果。因此當我發現兩組這麼普通的代碼組合起發生如此厲害效果,立即激動拍了拍鍵盤。大呼一聲!

「哇靠!這個真心666!」

喵星人發來賀贊

3.二、for循環解釋

for(i = 0; i < num; i++) {
        var x = (i * 10) + 10;
        text = String.fromCharCode(65 + Math.random() * 62);
        var y1 = y[i];
        ctx.fillText(text, x, y1);
        console.log(height);
        if(y1 > Math.random() * 10 * height) {
            y[i] = 0;
        } else {
            y[i] = parseInt(y[i]) + 10;
        }
    }
}

3.三、關於canvasX軸上面文字控制

由於前面每次畫的文字大小都是10px,那麼若是我把canvasX軸平鋪滿。須要多少個文字呢。

答案 = Math.ceil(width / 10); => 即就是我前面的num

小說明:

爲何得用Math.ceil()向上取整,而不能用Math.floor向下取整,parseInt()之類。

由於假設num = 300.8樣子,那麼使用Math.floor() 或者parseInt(),就好把這個數轉換成300

那麼後面,繪製300個文字在canvasX軸,那麼最右邊就還有0.8個文字,也就是8px空隙一種沒有字母出現。向上取整,就會鋪滿,多的部分超出canvas區域,就會消失。

text = String.fromCharCode(65 + Math.random() * 62);這裏就是每次for循環的時候產生65 - 127 的數字,以後將其轉換爲大寫、小寫字母,以及一些符號

控制檯檢測text

3.4關於canvasY軸的控制

這裏前面定義的數組就派上用場了var y = Array(num).join(0).split('');,這裏就是用於記錄與控制每一次canvas文字的Y軸。

爲何要用數組去記錄呢?說實話,當初我也是這麼認爲的,因此我沒有嘗試控制每個文字Y軸的數據,讓因此的Y軸依次累加,結果效果以下:

讓全部的文字共用Y軸,而後依次累加

因此以後我就奇思妙想,讓每次文字是排列X軸平鋪數字隨機呈現。例如第一次平鋪300個,第二次平鋪100個,第三次平鋪200.......,可是我仍是錯了:

讓X軸隨機平鋪數量

錯誤的代碼示範:

失敗的代碼嘗試

因此屢次失敗的嘗試以後,發現仍是得控制利用一個數組控記錄與控制每個數字Y軸的數據。

用Y軸分配每個X軸點以後,後面產生如此的效果

四、代碼的收尾
Run();
function Run() {
    Game_Interval = setInterval(draw, 30);
}

以後設置一個定時器,每次間隔30ms調用一次,而後大功告成。一個炫酷的黑客帝國矩形雨效果就出來了。

固然前面JavaScript代碼可能太凌亂,因此這邊就把JavaScript的所有呈上:

window.onload = function() {
  var kacker = document.getElementById("hacker");
  var width = hacker.width = screen.width;
  var height = kacker.height;
  var ctx = hacker.getContext('2d');
  var num = Math.ceil(width / 10);
  var y = Array(num).join(0).split('');
  var draw = function() {
    ctx.fillStyle = 'rgba(0,0,0,.05)';
    ctx.fillRect(0, 0, width, height);
    ctx.fillStyle = '#0f0';
    ctx.font = '10px Microsoft YaHei';
    for(i = 0; i < num; i++) {
        var x = (i * 10) + 10;
        text = String.fromCharCode(65 + Math.random() * 62);
        //console.log(text);  用來檢測 text 的值
        var y1 = y[i];
        ctx.fillText(text, x, y1);
        if(y1 > Math.random() * 10 * height) {
            y[i] = 0;
        } else {
            y[i] = parseInt(y[i]) + 10;
        }
    }
}
Run();
function Run() {
    Game_Interval = setInterval(draw, 100);
    }
}

看到這裏不要覺得代碼就此結束了,好好吸取那個for循環以後。接下來再返回上面看一下map()方法,相信map()方法的用法是否是一會兒清晰明瞭。一舉兩得,既實現了5毛的特效,又幫助熟悉了一個map()方法用法.

效果預覽:黑客帝國矩形陣
(ps:效果圖掛在阿里雲上面,部分平臺點擊進去可能會有提示,例如微信,請忽略.....)

對於裏面完整blogDemo代碼感興趣的,能夠從本人github上閱覽。
源碼demo傳送門地址

動次!打次!鐺!

動次!打次!鐺! 我是車大棒,深藏功與名!(滑稽臉)

相關文章
相關標籤/搜索