背景:

一日在网上闲逛的之时,突然看到一个利用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 < 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.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 < 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.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 < 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传送门地址



我是车大棒,深藏功与名!(滑稽脸)

车大棒浅谈for循环+canvas实现黑客帝国矩形阵的更多相关文章

  1. for循环+canvas实现黑客帝国矩形阵

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  2. canvas实现黑客帝国矩形阵

    在博客园看到了车大棒的写了一篇关于实现黑客帝国矩形阵,觉得canvas还是有一些奇妙的地方所在,故做个笔记记录一下. 实现的效果如下: 真的是一两行关键的代码添加就能实现意想不到的效果. 由于是can ...

  3. 车大棒浅谈jQuery源码(二)

    前言 本来只是一个自己学习jQuery笔记的简单分享,没想到获得这么多人赏识.我自己也是傻呵呵的一脸迷茫,感觉到受宠若惊. 不过还是有人向批判我的文章说,这是基本知识点,完全跟jQuery源码沾不上边 ...

  4. 车大棒浅谈jQuery源码(一)

    背景 因为最近辞职找工作,投了许多家公司.结果简历要么石沉大海,一点音讯都没有,要么就是邮件回复说不匹配.后面加了一些QQ群,才发现原来我工作经验年限太少了.现在深圳都是3经验起步,北京据说更加恐怖. ...

  5. 浅谈HTML5中canvas中的beginPath()和closePath()的重要性

    beginPath的作用很简单,就是开始一段新的路径,但在使用canvas绘图的过程中却非常重要 先来看一小段代码: var ctx=document.getElementById("can ...

  6. 【java】浅谈for循环

    for语法: for(初始化条件; 判断条件(bool型,不可缺省); 条件改变)// 初始化条件,条件改变可以是多条,eg for(x=1,y=1;x<4;x++,y++) { 执行的操作 } ...

  7. 浅谈JavaScript的Canvas(绘制图形)

    HTML5中新增加的一个元素canvas,要使用canvas元素,浏览器必须支持html5.通过canvas标签来创建元素,并需要为canvas指定宽度和高度,也就是绘图区域的大小. <canv ...

  8. 浅谈for循环

    for循环 <script> /* ** (1) 是执行代码块之前 ** (2) 运行代码块的条件 ** (3) 需要执行的代码块 ** (4) 代码块执行后执行 ** 执行顺序是(1)( ...

  9. Spring5.0源码学习系列之浅谈循环依赖问题

    前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文浅谈Spring循环依赖问题,这是一个面试比较常见的问题 1.什么是循环依赖? 所谓的循环依 ...

随机推荐

  1. css3的::selection属性

    大家都知道浏览器对选中的文本默认样式都是统一的,Windows下是一个深蓝色的背景,白字的前景,而在Mac下是一个淡蓝色背景,白色字体,就如上图所展示的一样,自从有了这个“::selection”选择 ...

  2. Redis缓存服务搭建及实现数据读写--转载

    来自 http://www.cnblogs.com/lc-chenlong/p/3218157.html 1.  下载安装Redis 下载地址:https://github.com/MSOpenTec ...

  3. 第十七篇 --ANDROID DisplayManager 服务解析一

    ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地).HDMI显示类型以及支持WIFI D ...

  4. CodeForces 590B Chip 'n Dale Rescue Rangers

    这题可以o(1)推出公式,也可以二分答案+验证. #include<iostream> #include<cstring> #include<cmath> #inc ...

  5. 结合Pnotify插件--app-jquery-notify.js

    $.NOTIFY = { showSuccess : function (title, text, context) { var opt = { title : title, text : text, ...

  6. [iOS]C语言技术视频-06-程序循环结构(for{})

    下载地址: 链接: http://pan.baidu.com/s/1dD11Zwt 密码: rke9

  7. CDOJ 1270 Playfair

    模拟题,代码写得比较乱... #include<cstdio> #include<cstring> #include<cmath> #include<queu ...

  8. jquery刷新iframe页面的方法(兼容主流)

    1,reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet])   参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取 ...

  9. window环境变量

    首先Window中有很多乱七八糟的路径变量之类的,归类下来有几类,主要是为了我们分清楚概念,以免搞的糊涂了. 1. Window系统的环境变量:顾名思义,就是系统级别的变量,或者利用我们编程的角度来讲 ...

  10. ANSI标准

    NSI:美国国家标准学会(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)成立于1918年.当时,美国的许多企业和专业技术团体,已开始了标准化工作,但因彼此间没 ...