JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果


Posted in Javascript onMarch 17, 2020

先看看JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落最终效果:

JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果

HTML代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/ok.css" rel="external nofollow" >
<title>code by-zhenyu.sha</title>
</head>
 
<body>
<canvas id="canvas"></canvas>
</body>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="http://neilcarpenter.com/demos/canvas/matrix/stats.min.js"></script>
<script type="text/javascript" src="js/ok.js"></script>
</html>

js代码:

(function() {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
      window[vendors[x] + 'CancelRequestAnimationFrame'];
  }
  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() {
          callback(currTime + timeToCall);
        },
        timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
}());
// stats
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
var M = {
  settings: {
    COL_WIDTH: 20,
    COL_HEIGHT: 25,
    VELOCITY_PARAMS: {
      min: 4,
      max: 8
    },
    CODE_LENGTH_PARAMS: {
      min: 20,
      max: 40
    }
  },
  animation: null,
  c: null,
  ctx: null,
  lineC: null,
  ctx2: null,
  WIDTH: window.innerWidth,
  HEIGHT: window.innerHeight,
  COLUMNS: null,
  canvii: [],
  font: '30px matrix-code',
  letters: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '$', '+', '-', '*', '/', '=', '%', '"', '\'', '#', '&', '_', '(', ')', ',', '.', ';', ':', '?', '!', '\\', '|', '{', '}', '<', '>', '[', ']', '^', '~'],
  codes: [],
  createCodeLoop: null,
  codesCounter: 0,
  init: function() {
    M.c = document.getElementById('canvas');
    M.ctx = M.c.getContext('2d');
    M.c.width = M.WIDTH;
    M.c.height = M.HEIGHT;
    M.ctx.shadowBlur = 0;
    M.ctx.fillStyle = '#000';
    M.ctx.fillRect(0, 0, M.WIDTH, M.HEIGHT);
    M.ctx.font = M.font;
    M.COLUMNS = Math.ceil(M.WIDTH / M.settings.COL_WIDTH);
    for (var i = 0; i < M.COLUMNS; i++) {
      M.codes[i] = [];
      M.codes[i][0] = {
        'open': true,
        'position': {
          'x': 0,
          'y': 0
        },
        'strength': 0
      };
    }
    M.loop();
    M.createLines();
    M.createCode();
    // not doing this, kills CPU
    // M.swapCharacters();
    window.onresize = function() {
      window.cancelAnimationFrame(M.animation);
      M.animation = null;
      M.ctx.clearRect(0, 0, M.WIDTH, M.HEIGHT);
      M.codesCounter = 0;
      M.ctx2.clearRect(0, 0, M.WIDTH, M.HEIGHT);
      M.WIDTH = window.innerWidth;
      M.HEIGHT = window.innerHeight;
      M.init();
    };
  },
  loop: function() {
    M.animation = requestAnimationFrame(function() {
      M.loop();
    });
    M.draw();
    stats.update();
  },
  draw: function() {
    var velocity, height, x, y, c, ctx;
    // slow fade BG colour
    M.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
    M.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
    M.ctx.fillRect(0, 0, M.WIDTH, M.HEIGHT);
    M.ctx.globalCompositeOperation = 'source-over';
    for (var i = 0; i < M.COLUMNS; i++) {
      // check member of array isn't undefined at this point
      if (M.codes[i][0].canvas) {
        velocity = M.codes[i][0].velocity;
        height = M.codes[i][0].canvas.height;
        x = M.codes[i][0].position.x;
        y = M.codes[i][0].position.y - height;
        c = M.codes[i][0].canvas;
        ctx = c.getContext('2d');
        M.ctx.drawImage(c, x, y, M.settings.COL_WIDTH, height);
        if ((M.codes[i][0].position.y - height) < M.HEIGHT) {
          M.codes[i][0].position.y += velocity;
        } else {
          M.codes[i][0].position.y = 0;
        }
      }
    }
  },
  createCode: function() {
    if (M.codesCounter > M.COLUMNS) {
      clearTimeout(M.createCodeLoop);
      return;
    }
    var randomInterval = M.randomFromInterval(0, 100);
    var column = M.assignColumn();
    if (column) {
      var codeLength = M.randomFromInterval(M.settings.CODE_LENGTH_PARAMS.min, M.settings.CODE_LENGTH_PARAMS.max);
      var codeVelocity = (Math.random() * (M.settings.VELOCITY_PARAMS.max - M.settings.VELOCITY_PARAMS.min)) + M.settings.VELOCITY_PARAMS.min;
      var lettersLength = M.letters.length;
      M.codes[column][0].position = {
        'x': (column * M.settings.COL_WIDTH),
        'y': 0
      };
      M.codes[column][0].velocity = codeVelocity;
      M.codes[column][0].strength = M.codes[column][0].velocity / M.settings.VELOCITY_PARAMS.max;
      for (var i = 1; i <= codeLength; i++) {
        var newLetter = M.randomFromInterval(0, (lettersLength - 1));
        M.codes[column][i] = M.letters[newLetter];
      }
      M.createCanvii(column);
      M.codesCounter++;
    }
    M.createCodeLoop = setTimeout(M.createCode, randomInterval);
  },
  createCanvii: function(i) {
    var codeLen = M.codes[i].length - 1;
    var canvHeight = codeLen * M.settings.COL_HEIGHT;
    var velocity = M.codes[i][0].velocity;
    var strength = M.codes[i][0].strength;
    var text, fadeStrength;
    var newCanv = document.createElement('canvas');
    var newCtx = newCanv.getContext('2d');
    newCanv.width = M.settings.COL_WIDTH;
    newCanv.height = canvHeight;
    for (var j = 1; j < codeLen; j++) {
      text = M.codes[i][j];
      newCtx.globalCompositeOperation = 'source-over';
      newCtx.font = '30px matrix-code';
      if (j < 5) {
        newCtx.shadowColor = 'hsl(104, 79%, 74%)';
        newCtx.shadowOffsetX = 0;
        newCtx.shadowOffsetY = 0;
        newCtx.shadowBlur = 10;
        newCtx.fillStyle = 'hsla(104, 79%, ' + (100 - (j * 5)) + '%, ' + strength + ')';
      } else if (j > (codeLen - 4)) {
        fadeStrength = j / codeLen;
        fadeStrength = 1 - fadeStrength;
        newCtx.shadowOffsetX = 0;
        newCtx.shadowOffsetY = 0;
        newCtx.shadowBlur = 0;
        newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + (fadeStrength + 0.3) + ')';
      } else {
        newCtx.shadowOffsetX = 0;
        newCtx.shadowOffsetY = 0;
        newCtx.shadowBlur = 0;
        newCtx.fillStyle = 'hsla(104, 79%, 74%, ' + strength + ')';
      }
      newCtx.fillText(text, 0, (canvHeight - (j * M.settings.COL_HEIGHT)));
    }
    M.codes[i][0].canvas = newCanv;
  },
  swapCharacters: function() {
    var randomCodeIndex;
    var randomCode;
    var randomCodeLen;
    var randomCharIndex;
    var newRandomCharIndex;
    var newRandomChar;
    for (var i = 0; i < 20; i++) {
      randomCodeIndex = M.randomFromInterval(0, (M.codes.length - 1));
      randomCode = M.codes[randomCodeIndex];
      randomCodeLen = randomCode.length;
      randomCharIndex = M.randomFromInterval(2, (randomCodeLen - 1));
      newRandomCharIndex = M.randomFromInterval(0, (M.letters.length - 1));
      newRandomChar = M.letters[newRandomCharIndex];
      randomCode[randomCharIndex] = newRandomChar;
    }
    M.swapCharacters();
  },
  createLines: function() {
    M.linesC = document.createElement('canvas');
    M.linesC.width = M.WIDTH;
    M.linesC.height = M.HEIGHT;
    M.linesC.style.position = 'absolute';
    M.linesC.style.top = 0;
    M.linesC.style.left = 0;
    M.linesC.style.zIndex = 10;
    document.body.appendChild(M.linesC);
    var linesYBlack = 0;
    var linesYWhite = 0;
    M.ctx2 = M.linesC.getContext('2d');
    M.ctx2.beginPath();
    M.ctx2.lineWidth = 1;
    M.ctx2.strokeStyle = 'rgba(0, 0, 0, 0.7)';
    while (linesYBlack < M.HEIGHT) {
      M.ctx2.moveTo(0, linesYBlack);
      M.ctx2.lineTo(M.WIDTH, linesYBlack);
      linesYBlack += 5;
    }
    M.ctx2.lineWidth = 0.15;
    M.ctx2.strokeStyle = 'rgba(255, 255, 255, 0.7)';
    while (linesYWhite < M.HEIGHT) {
      M.ctx2.moveTo(0, linesYWhite + 1);
      M.ctx2.lineTo(M.WIDTH, linesYWhite + 1);
      linesYWhite += 5;
    }
    M.ctx2.stroke();
  },
  assignColumn: function() {
    var randomColumn = M.randomFromInterval(0, (M.COLUMNS - 1));
    if (M.codes[randomColumn][0].open) {
      M.codes[randomColumn][0].open = false;
    } else {
      return false;
    }
    return randomColumn;
  },
  randomFromInterval: function(from, to) {
    return Math.floor(Math.random() * (to - from + 1) + from);
  },
  snapshot: function() {
    window.open(M.c.toDataURL());
  }
};
function eventListenerz() {
  var controlToggles = document.getElementsByClassName('toggle-info');
  var controls = document.getElementById('info');
  var snapshotBtn = document.getElementById('snapshot');
  function toggleControls(e) {
    e.preventDefault();
    controls.className = controls.className === 'closed' ? '' : 'closed';
  }
  for (var j = 0; j < 2; j++) {
    controlToggles[j].addEventListener('click', toggleControls, false);
  }
  snapshotBtn.addEventListener('click', M.snapshot, false);
}
window.onload = function() {
  M.init();
  eventListenerz();
};

css代码:

@import url("http://fonts.googleapis.com/css?family=Carrois+Gothic");
@font-face {
  font-family: 'matrix-code';
  src: url('http://neilcarpenter.com/demos/canvas/matrix/font/matrix-code.eot?#iefix') format('embedded-opentype'), url('http://neilcarpenter.com/demos/canvas/matrix/font/matrix-code.woff') format('woff'), url('http://neilcarpenter.com/demos/canvas/matrix/font/matrix-code.ttf') format('truetype'), url('http://neilcarpenter.com/demos/canvas/matrix/font/matrix-code.svg#svgFontName') format('svg');
}
html,
body {
  -webkit-font-smoothing: antialiased;
  font: normal 12px/14px "Carrois Gothic", sans-serif;
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  color: #fff;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
body {
  background: black;
}
#stats {
  z-index: 100;
}
#info {
  background: rgba(0, 0, 0, 0.7);
  position: fixed;
  bottom: 0;
  left: 0px;
  width: 250px;
  padding: 10px 20px 20px;
  z-index: 100;
  -webkit-transform-origin: bottom center;
  -moz-transform-origin: bottom center;
  -o-transform-origin: bottom center;
  transform-origin: bottom center;
  -webkit-transform: rotate(0deg);
  -moz-transform: rotate(0deg);
  -o-transform: rotate(0deg);
  transform: rotate(0deg);
  -webkit-transition: -webkit-transform .5s ease-in-out;
  -moz-transition: -moz-transform .5s ease-in-out;
  -o-transition: -o-transform .5s ease-in-out;
  transition: transform .5s ease-in-out;
}
#info.closed {
  -webkit-transform: rotate(180deg);
  -moz-transform: rotate(180deg);
  -o-transform: rotate(180deg);
  transform: rotate(180deg);
}
.toggle-info {
  position: absolute;
  display: block;
  height: 10px;
  background: rgba(0, 0, 0, 0.8);
  width: 290px;
  left: 0;
  text-align: center;
  padding: 3px 0 7px;
  text-decoration: none;
  color: white;
  text-shadow: none;
}
.toggle-info:hover {
  background: rgb(0, 0, 0);
}
#close {
  top: -20px;
}
#open {
  bottom: -20px;
  -webkit-transform: rotate(-180deg);
  -moz-transform: rotate(-180deg);
  -o-transform: rotate(-180deg);
  transform: rotate(-180deg);
}
button {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
  border: 0;
  border-radius: 2px;
  padding: 7px 10px;
  box-shadow: 0 0 3px 0px rgba(255, 255, 255, 0.3);
  cursor: pointer;
}
button:hover {
  background: rgba(255, 255, 255, 0.1);
}
pa {
  color: #fff;
}
pa:hover {
  color: #EFFDEB;
  text-shadow: 0px 0px 5px #75AD61;
}

本文介绍了使用JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果的代码实例,更多JS特效请查看下面的相关链接

Javascript 相关文章推荐
JavaScript 嵌套函数指向this对象错误的解决方法
Mar 15 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
Apr 28 Javascript
Jquery绑定事件(bind和live的区别介绍)
Aug 23 Javascript
JavaScript Ajax Json实现上下级下拉框联动效果实例代码
Nov 23 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
Oct 22 Javascript
jQuery实现横向带缓冲的水平运动效果(附demo源码下载)
Jan 29 Javascript
Angularjs中使用layDate日期控件示例
Jan 11 Javascript
Vue 短信验证码组件开发详解
Feb 14 Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
Feb 14 Javascript
ionic实现下拉刷新载入数据功能
May 11 Javascript
详解Vue.js使用Swiper.js在iOS
Sep 10 Javascript
如何在 ant 的table中实现图片的渲染操作
Oct 28 Javascript
js实现简单点赞操作
Mar 17 #Javascript
vue+ESLint 配置保存 自动格式化代码
Mar 17 #Javascript
HTML+JS实现“代码雨”效果源码(黑客帝国文字下落效果)
Mar 17 #Javascript
JavaScript实现横版菜单栏
Mar 17 #Javascript
JavaScript实现留言板案例
Mar 17 #Javascript
es6函数之严格模式用法实例分析
Mar 17 #Javascript
JavaScript实现字符串与HTML格式相互转换
Mar 17 #Javascript
You might like
php 删除无限级目录与文件代码共享
2008/11/22 PHP
php printf输出格式使用说明
2010/12/05 PHP
PHP将整个网站生成HTML纯静态网页的方法总结
2012/02/05 PHP
php获取一定范围内取N个不重复的随机数
2016/05/28 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
按Enter键触发事件的jquery方法实现代码
2014/02/17 Javascript
使用jQuery操作HTML的table表格的实例解析
2016/03/13 Javascript
利用AngularJs实现京东首页轮播图效果
2016/09/08 Javascript
JavaScript计算值然后把值嵌入到html中的实现方法
2016/10/29 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
详解VueJS应用中管理用户权限
2018/02/02 Javascript
详解Vue This$Store总结
2018/12/17 Javascript
小程序server请求微信服务器超时的解决方法
2019/05/21 Javascript
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
[01:50]《我与DAC》之玩家:iG夺冠时的那面红旗
2018/03/29 DOTA
python爬虫框架talonspider简单介绍
2017/06/09 Python
基于python批量处理dat文件及科学计算方法详解
2018/05/08 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
Python打开文件,将list、numpy数组内容写入txt文件中的方法
2018/10/26 Python
Python八皇后问题解答过程详解
2019/07/29 Python
numpy实现神经网络反向传播算法的步骤
2019/12/24 Python
pytorch快速搭建神经网络_Sequential操作
2020/06/17 Python
HTML5 Canvas 旋转风车绘制
2017/08/18 HTML / CSS
京东奢侈品:全球奢侈品牌
2018/03/17 全球购物
广告词串烧
2014/03/19 职场文书
学期评语大全
2014/04/30 职场文书
营销团队口号
2014/06/06 职场文书
学校周年庆活动方案
2014/08/22 职场文书
2014年财政所工作总结
2014/11/22 职场文书
个人党性分析总结
2015/03/05 职场文书
上甘岭观后感
2015/06/10 职场文书
毕业实习证明范本
2015/06/16 职场文书
导游词之崇武古城
2019/10/07 职场文书