SOURCE

console 命令行工具 X clear

                    
>
console
class Rect {
    constructor({
        xpos = 0,
        ypos = 0,
        zpos = 0
    }) {
        this.x = 0;
        this.y = 0;
        this.xpos = xpos;
        this.ypos = ypos;
        this.zpos = zpos;
        this.scaleX = 1;
        this.scaleY = 1;
        this.color = "#ffffff";
        this.alpha = 1;
        this.w = Math.random() * 100 + 50;
        this.h = Math.random() * 150 + 100;
    }
    draw(context) {
        context.save();
        context.beginPath();
        context.translate(this.x, this.y);
        context.scale(this.scaleX, this.scaleY);
        context.strokeStyle = this.color;
        context.rect(0, 0, this.w, this.h)
        context.stroke();
        context.restore();
    }
}

function move(targets) {
    targets.forEach(target => {
        const scale = fl / (fl + target.zpos)
        target.xpos += vx
        target.ypos += vy
        target.zpos += vz
        if (target.zpos < -fl) {
            target.zpos += 10000
        }
        if (target.zpos > 10000 - fl) {
            target.zpos-=10000
        }
        // if (target.x < 0) {
        //     target.xpos += 3000
        // }
        // if (target.x)
        target.scaleX = target.scaleY = scale
        target.x = vpX + target.xpos * scale
        target.y = vpY + target.ypos * scale
        target.zpos += vz
    })
    return targets
}


function sort(targets) {
    return targets.sort((a, b) => b.zpos - a.zpos)
}

function draw(targets) {
    targets.forEach(target => target.draw(ctx))
    return targets
}

function drawFrame(targets) {
    requestAnimationFrame(() => {
        drawFrame(targets)
    })
    ctx.clearRect(0, 0, canvas.width, canvas.height)

    vx += ax
    vy += ay
    vz += az
    vx *= friction
    vy *= friction
    vz *= friction

    draw(sort(move(targets)))
}

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

canvas.width = window.innerWidth
canvas.height = window.innerHeight

const vpX = canvas.width / 2
const vpY = canvas.height / 2
const fl = 250
const floor = canvas.height - 50
const friction = 0.95
let vz = 0
let vx = 0
let vy = 0
let az = -0.1
let ax = 0
let ay = 0


const rects = new Array(100).fill().map(() => new Rect({
    xpos: Math.random() * 2000 - 1000,
    ypos: Math.random() * floor,
    zpos: Math.random() * 10000
}))

window.addEventListener('keydown', event => {
    switch (event.keyCode) {
        // up
        case 38:
            az = -1
            break
        // left
        case 37:
            ax = 1
            break
        // right
        case 39:
            ax = -1
            break
        // down
        case 40:
            az = 1
            break
        // space
        case 32:
            ay = 1
            break
    }
})
window.addEventListener('keyup', event => {
    switch (event.keyCode) {
        case 38:
        case 40:
            az = 0
            break
        case 37:
        case 39:
            ax = 0
            break
        case 32:
            ay = -0.5
            break
    }
})

drawFrame(rects)
<canvas id="canvas"></canvas>
html, body {
    margin: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #000;
}