canvas黑客帝国效果

这个动画效果,就如标题所示,是一个绝对的酷炫动画效果

原文来自 前端圈

效果图  

代码

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
        <meta charset="UTF-8"> 
        <title>Martrix</title> 
        <style> 
            body{ 
                padding: 0; 
                margin: 0; 
                overflow: hidden; 
            } 
        </style> 
    </head>
    <body>
        <canvas id="canvas" style="background:#000;"></canvas> 
        <script> 
            window.onload = function(){ 
                var canvas = document.querySelector('canvas'), 
                    context = canvas.getContext('2d'), 
                    w, h; 
                w = canvas.width = window.innerWidth; 
                h = canvas.height = window.innerHeight; 
                //初始化 
                var clearColor = 'rgba(0, 0, 0, .1)', //用于绘制渐变阴影 
                    wordColor = "#33ff33", //文字颜色 
                    words = "0123456789qwertyuiopasdfghjklzxcvbnm,./;'\\\\[]QWERTYUIOP{}ASDFGHJHJKL:ZXCVBBNM<>?", 
                    wordsArr = words.split(''), //将文字拆分进一个数组 
                    font_size = 16,  //字体大小 
                    clumns = w / font_size, //文字降落的列数 
                    drops = []; 
                for (var i=0; i < clumns; i++) { 
                    drops[i] = 1; 
                } 
                function draw(){
                    context.save(); 
                    context.fillStyle = wordColor; 
                    context.font = font_size + "px arial"; 
                    //核心 
                    for (var i = 0; i < drops.length; i++){ 
                        var text = wordsArr[Math.floor(Math.random() * wordsArr.length)]; 
                        context.fillText(text, i * font_size, drops[i] * font_size); 
                        if (drops[i] * font_size > h && Math.random() > 0.98){ 
                            drops[i] = 0; 
                        } 
                        drops[i]++; 
                    } 
                    context.restore(); 
                } 
                //动画循环 
                (function drawFrame(){ 
                    window.requestAnimationFrame(drawFrame, canvasC); 
                    context.fillStyle = clearColor; 
                    context.fillRect(0, 0, w, h); 
                    draw(); 
                }()) 
                //resize 
                function resize(){ 
                    w = canvas.width = window.innerWidth; 
                    h = canvas.height = window.innerHeight;`` 
                } 
                canvas.addEventListener("resize", resize); 
            } 
        </script> 
    </body> 
</html>

这段代码有两个比较核心的地方:

1. 在初始化部分,我们定义了一个变量clearColor = ‘rgba(0, 0, 0, .1)’,用处就和注释一样,用于绘制阴影,它的主要用处在动画循环部分。原理可以这样理解:我们每画新的一帧,就在上面覆盖一个透明度为0.1的矩形模块,这样就形成了我们看到的阴影,是不是很简单呢?

2. 在初始化的注释处和核心模块处,这部分的原理是这样:首先我们设置了每个字体的大小(font_size),然后,用canvas的宽度除以字体的大小,我们就得到了需要绘制的列数(clumns), 然后创建了一个数组drops,数组的长度为clumns,并且每个元素的值都为1(drops在这有什么用呢?继续往下看)。

在绘制部分,我们采取的思路是一行一行的绘制,首先在循环中随机的获取文字,在文字绘制API部分注意这行代码:  

context.fillText(text, i * font_size, drops[i] * font_size);

我们知道该API有三个参数,第一个是绘制的文字,第二,三是文字的坐标。在X坐标部分为i * font_size,也就是说在循环完成后每个文字的X轴坐标是(0, 16, 32,48…), 而Y坐标为drops[i] * font_size由于drops内元素的初始值都为1,所以文字的Y坐标为(16, 16, 16, …),这样我们就相当于先绘制了第一行的文字。那么紧接着我们绘制第二行只需要将drops中的元素加1即可,即(第二行的Y轴坐标为(32,32,32…))。

依次类推,我们就绘制了满屏的文字,通过渐变阴影我们就可以看到文字似乎是向下运动的效果。为了让他们看上去运动的速度不一致,我们加上了这行代码:

if (drops[i] * font_size > h && Math.random() > 0.98){ 
    drops[i] = 0; 
}

这行代码我们,判断的是当前绘制的这行文字的Y坐标是否超过了canvas的高度,如果超过又从第一行开始绘制,那么如何让他们出现差异性呢!小秘密在Math.random() > 0.98这,if中的两个条件一个是判断文字高度,另一个是判断一个随机数是佛大于0.98,只有当两个条件同时成立才能回到第一行重新绘制。所以,由于第二个条件是随机的,那么差异性就自然而然的出现了!

看看,只需要这么简单的代码就能写出这么酷炫的效果,是不是很赞!你也试试吧!不理解没关系,这里只是让你看看canvas能做出多么酷炫的效果。如果,有什么不懂的地方可以,评论哦。

展示:

P.S 若演示看不到请刷新本页