用html实现文字雨

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文字雨</title>
  <style>
    html, body { 
      height: 100%; 
      margin: 0; 
      overflow: hidden;
    }
    body { 
      display: flex; 
      align-items: center; 
      justify-content: center;
      background: #000; 
    }
    main {
      display: flex;
    }
    p {
      line-height: 1;
    }
    span {
      display: block;
      width: 2vmax; 
      height: 2vmax; 
      font-size: 2vmax; 
      color: #9bff9b11;
      text-align: center;
      font-family: "Helvetica Neue", Helvetica, sans-serif;
    }
  </style>
</head>
<body>
  <main></main>
  <script>
    function r(from, to) {
      return ~~(Math.random() * (to - from + 1) + from);
    }
    function pick() {
      return arguments[r(0, arguments.length - 1)];
    }
    function getChar() {
      return String.fromCharCode(pick(
        r(0x3041, 0x30ff),
        r(0x2000, 0x206f),
        r(0x0020, 0x003f)
      ));
    }
    function loop(fn, delay) {
      let stamp = Date.now();
      function _loop() {
        if (Date.now() - stamp >= delay) {
          fn(); stamp = Date.now();
        }
        requestAnimationFrame(_loop);
      }
      requestAnimationFrame(_loop);
    }
    class Char {
      constructor() {
        this.element = document.createElement('span');
        this.mutate();
      }
      mutate() {
        this.element.textContent = getChar();
      }
    }
    class Trail {
      constructor(list = [], options) {
        this.list = list;
        this.options = Object.assign(
          { size: 10, offset: 0 }, options
        );
        this.body = [];
        this.move();
      }
      traverse(fn) {
        this.body.forEach((n, i) => {
          let last = (i == this.body.length - 1);
          if (n) fn(n, i, last);
        });
      }
      move() {
        this.body = [];
        let { offset, size } = this.options;
        for (let i = 0; i < size; ++i) {
          let item = this.list[offset + i - size + 1];
          this.body.push(item);
        }
        this.options.offset =
          (offset + 1) % (this.list.length + size - 1);
      }
    }
    class Rain {
      constructor({ target, row }) {
        this.element = document.createElement('p');
        this.build(row);
        if (target) {
          target.appendChild(this.element);
        }
        this.drop();
      }
      build(row = 20) {
        let root = document.createDocumentFragment();
        let chars = [];
        for (let i = 0; i < row; ++i) {
          let c = new Char();
          root.appendChild(c.element);
          chars.push(c);
          if (Math.random() < .5) {
            loop(() => c.mutate(), r(1e3, 5e3));
          }
        }
        this.trail = new Trail(chars, {
          size: r(10, 30), offset: r(0, 100)
        });
        this.element.appendChild(root);
      }
      drop() {
        let trail = this.trail;
        let len = trail.body.length;
        let delay = r(10, 100);
        loop(() => {
          trail.move();
          trail.traverse((c, i, last) => {
            c.element.style = `
        color: hsl(136, 100%, ${85 / len * (i + 1)}%)
      `;
            if (last) {
              c.mutate();
              c.element.style = `
          color: hsl(136, 100%, 85%);
          text-shadow:
            0 0 .5em #fff,
            0 0 .5em currentColor;
        `;
            }
          });
        }, delay);
      }
    }

    const main = document.querySelector('main');
    for (let i = 0; i < 50; ++i) {
      new Rain({ target: main, row: 50 });
    }
  </script>
</body>
</html>
相关推荐
前端AK君3 分钟前
React中台系统如何嵌入到业务系统中
前端
Slice_cy4 分钟前
不定高虚拟列表
前端
前端AK君13 分钟前
React组件库如何在vue项目中使用
前端
Moonbit23 分钟前
MoonBit 再次走进清华:张宏波受邀参加「思源计划」与「程序设计训练课」
前端·后端·编程语言
RestCloud26 分钟前
一站式数据集成:iPaaS 如何让开发者和业务人员都满意?
前端·后端·架构
li357437 分钟前
React 核心 Hook 与冷门技巧:useReducer、useEffect、useRef 及 is 属性全解析
前端·javascript·react.js
菜市口的跳脚长颌40 分钟前
Web3 基础
前端
快乐是Happy41 分钟前
分享一个非常实用的防止重复提交操作
前端·javascript
王蛋11141 分钟前
前端工作问题或知识记录
前端·npm·node.js
云枫晖43 分钟前
JS核心知识-执行上下文
前端·javascript