原生Javascript代码雨

效果图
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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: 1.5vmax;
            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() {
        // pick(
        //     // r(0xE63E, 0xE757),  //=>这是一个范围
        //     // r(0x0061, 0x007a),  //=>这是一个范围
        //     // r(0x0041, 0x005a)   //=>这是一个范围
        //     (0x6885, 0x5a49) //=>这是指定字符: 梅婉
        //      0x5b59, 0x4f73,0x4e3d //=>这是指定字符:孙佳丽
        // )
        return String.fromCharCode(pick(0x6885, 0x5a49)); //pick括号内放unicode指定字符或范围
    }
    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(18, 30%,${85 / len * (i + 1)}%) 
        `; //=>这里改文字颜色
        // color: hsl(25, 100%, ${85 / len * (i + 1)}%)
                    if (last) {
                        c.mutate();
                        c.element.style = `
            color: hsl(18, 93.1%, 94.3%);
            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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值