水波紋特效

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Water Effect</title>
        <style>
            body {
                margin: 0;
                padding: 0;
                overflow: hidden;
                background-color: black;
            }
            canvas {
                display: block;
                width: 100%;
                height: 100%;
            }
        </style>
    </head>
    <body>
        <script>
            const canvas = document.createElement("canvas");
            document.body.appendChild(canvas);
            const ctx = canvas.getContext("2d");
            const width = (canvas.width = window.innerWidth);
            const height = (canvas.height = window.innerHeight);

            const particles = [];
            const particleCount = Math.floor(width / 20) * Math.floor(height / 20);
            const spread = 100;

            for (let i = 0; i < particleCount; i++) {
                particles.push({
                    x: (i % Math.floor(width / 20)) * 20,
                    y: Math.floor(i / Math.floor(width / 20)) * 20,
                    velocityX: 0,
                    velocityY: 0,
                    accelerationX: 0,
                    accelerationY: 0,
                    size: Math.random() * 3 + 1,
                    color: "#fff",
                    initialX: (i % Math.floor(width / 20)) * 20,
                    initialY: Math.floor(i / Math.floor(width / 20)) * 20,
                });
            }

            // 更新粒子的位置和速度
            function updateParticle(particle) {
                // 计算粒子与鼠标之间的距离
                const dx = particle.initialX - mouse.x;
                const dy = particle.initialY - mouse.y;
                const dist = Math.sqrt(dx * dx + dy * dy);
                // 计算粒子与鼠标之间的角度
                const angle = Math.atan2(dy, dx);
                // 计算粒子受到的力, 距离越大,力远小
                let force = spread / (dist * dist);
                // 如果距离小于30,则粒子受到鼠标的吸引力
                if (dist < 30) {
                    particle.accelerationX = force * Math.cos(angle);
                    particle.accelerationY = force * Math.sin(angle);
                } else {
                    particle.accelerationX = 0;
                    particle.accelerationY = 0;
                }
                //小球距初始点的距离
                const odx = particle.x - particle.initialX;
                const ody = particle.y - particle.initialY;
                const odist = Math.sqrt(odx * odx + ody * ody);

                if (dist < 30) {
                    if (odist < 100) {
                        // 减速远离
                        particle.velocityX -= particle.accelerationX;
                        particle.velocityY -= particle.accelerationY;
                        particle.x += particle.velocityX;
                        particle.y += particle.velocityY;
                    } else {
                        particle.velocityX = 0;
                        particle.velocityY = 0;
                    }
                } else {
                    if (odist == 0) {
                        particle.velocityX = 0;
                        particle.velocityY = 0;
                    } else {
                        // 加速靠近
                        particle.velocityX += particle.accelerationX;
                        particle.velocityY += particle.accelerationY;
                        particle.x -= particle.velocityX;
                        particle.y -= particle.velocityY;
                    }
                }
            }

            function renderParticle(particle) {
                ctx.beginPath();
                ctx.fillStyle = particle.color;
                ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
                ctx.fill();
            }

            function render() {
                ctx.clearRect(0, 0, width, height);
                particles.forEach((particle) => {
                    updateParticle(particle);
                    renderParticle(particle);
                });
                requestAnimationFrame(render);
            }

            const mouse = {
                x: 0,
                y: 0,
            };

            window.addEventListener("mousemove", (e) => {
                mouse.x = e.clientX;
                mouse.y = e.clientY;
            });

            render();
        </script>
    </body>
</html>

posted @ 2025-11-20 12:35  johnjackson  阅读(5)  评论(0)    收藏  举报