CSS特效---代码雨

1、演示

2、一切尽在代码中

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>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() {
        const ZmStr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        const randomIndex = Math.floor(Math.random() * ZmStr.length)
        return ZmStr[randomIndex]
      }
      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() < 0.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>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bbamx.

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值