车大棒浅谈for循环+canvas实现黑客帝国矩形阵

车大棒浅谈for循环+canvas实现黑客帝国矩形阵

来自:http://www.cnblogs.com/chedabang/p/6291504.html

背景:
一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小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进行绘画处理。要是让我这种段子手来写,估计我把敲烂键盘都想不出这样营造效果。艺术细胞真的很重要咕~~(╯﹏╰)

老王:“等等大棒!不是说js+canvas实现黑客帝国矩形雨,可是你这个附上的代码分明是jQ+canvas.

老管:”就是!你这个标题汪,这是又要搞事情呀!”

我:“别急呀!这个jQ+canvas因为网上很多人博客都有写,所以这边只是附上一下jQ代码供大家参考。下面才是我今天要通过for循环代替上面的map()来实现的!!

夫子:别净扯理由,你是根本就不会map()用法!!”

老齐: “净说什么大实话!大棒是根本看不懂……”

我:………好吧!你们说对了,我的确是不会map()方法。(让我蹲墙角哭会/((╥╯^╰╥)

万能for循环的写法

好了不扯犊子了,言归正传。让我们回到下面要讲的代码上面来。

1、基本准备工作

1.1、HTML骨架部分

canvas id="hacker" width="500" height="500">请使用Google浏览器或者IE9以上canvas>

1.2、 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画布的上下文。

2、数组的准备
var num = Math.ceil(width / 10);
var y = Array(num).join(0).split('');

这里估计有人会询问了,这里创建一个数组是干嘛。为什么数组的length >= num?

O(∩_∩)O哈哈~,别着急,后面的代码就会个大家逐一解释了。

3、定义一个重复调用核心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 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.1、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.2、for循环解释

    for(i = 0; 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.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 的数字,之后将其转换为大写、小写字母,以及一些符号

3.4关于canvasY轴的控制

这里前面定义的数组就派上用场了var y = Array(num).join(0).split('');,这里就是用于记录与控制每一次canvas文字的Y轴。

为什么要用数组去记录呢?说实话,当初我也是这么认为的,所以我没有尝试控制每一个文字Y轴的数据,让所以的Y轴依次累加,结果效果如下:

所以之后我就奇思妙想,让每次文字是排列X轴平铺数字随机呈现。例如第一次平铺300个,第二次平铺100个,第三次平铺200…….,但是我还是错了:

错误的代码示范:

所以多次失败的尝试之后,发现还是得控制利用一个数组控记录与控制每一个数字Y轴的数据。

4、代码的收尾
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 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()方法用法.

效果预览:黑客帝国矩形阵

 

–END

More from my site

好烂啊有点差凑合看看还不错很精彩 (No Ratings Yet)
Loading...
422 views

3 thoughts on “车大棒浅谈for循环+canvas实现黑客帝国矩形阵

  1. Fantastic goods from you, man. I’ve understand your stuff previous to and you are just too great. I actually like what you have acquired here, certainly like what you’re saying and the way in which you say it. You make it entertaining and you still care for to keep it smart. I can not wait to read far more from you. This is really a terrific web site.

  2. Usually I do not read article on blogs, but I would like to say that this write-up very forced me to try and do so! Your writing style has been surprised me. Thanks, very nice article.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

跳至工具栏