canvas动画之三 -- 黑客帝国文字掉落效果

Posted 旗smile

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了canvas动画之三 -- 黑客帝国文字掉落效果相关的知识,希望对你有一定的参考价值。

今天要实现的效果是黑客帝国里面的文字掉落效果,先来看一下图

点击这里,查看demo

其实效果也是比较好实现的,只要计算出每个文字该出现的地方,然后绘制文字就可以了。

下面就来说具体的实现方法吧。

首先,新建页面写上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>

canvas标签设置完了之后,然后再来设置一个数组,也就是从屏幕上掉落出来哪些文字,当然这里设置什么都可以,我设置的是0~9、a~z,为了简单我就是使用了split方法将字符串转换为数组:

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

接下来就该设置一下字体的大小和屏幕总共能容纳多少列了,这里我把字体大小设置为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;

刚刚忘了一点,没有设置onresize,这里设置一下,当然这个在什么时候设置都是可以的,在window上添加onresize事件,浏览器窗口改变时重新计算canvas的大小:

window.onresize = function()
    setSize();


function setSize()
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

现在准备工作都完成了,接下来就开始绘制文字效果吧,前面已经定义了数组,现在需要从数组中随机取得一个数字,通过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]++;

在上面这个循环之前为了让效果更好看,我们需要让背景透明度逐渐变化,并且还需要设置好字体,所以整个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]++;
    

接下来只要让它不断的循环绘制就可以了:

init();

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

然后整个绚丽的效果就完成了,是不是很简单呢。

下面是整个代码:

<!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>

以上是关于canvas动画之三 -- 黑客帝国文字掉落效果的主要内容,如果未能解决你的问题,请参考以下文章

使用canvas实现图片滑动验证

HTML5 Canvas核心技术 图形动画与游戏开发学习总结

canvas的measureText()方法

帝国cms 关键字替换bug

如何在UWP用C#实现HTML5中canvas各种画图操作

七款炫酷的页面特效