Vissza az animációkhoz
Háttéranimációk

Élő háló

Élő előnézet – az animáció teljes méretben.

Élő előnézet
HTML · CSS · JS
HTML
<div class="we-bg-network">

    <canvas class="we-bg-network-canvas"></canvas>

    <div class="we-bg-network-content">
        <span>WEBELEMENTS</span>
        <h2>Élő hálózat</h2>
        <p>
            Egy folyamatosan változó digitális tér a háttérben.
        </p>
    </div>

</div>
CSS
.we-bg-network {
    position: relative;

    width: 100%;
    min-height: 420px;

    overflow: hidden;

    background: #080b11;

    display: flex;
    align-items: center;
    justify-content: center;

    isolation: isolate;
}

.we-bg-network-canvas {
    position: absolute;

    inset: 0;

    width: 100%;
    height: 100%;

    pointer-events: none;

    opacity: .72;
}

.we-bg-network-content {
    position: relative;
    z-index: 2;

    max-width: 620px;

    padding: 45px;

    text-align: center;

    color: #f4f1e9;

    pointer-events: none;
}

.we-bg-network-content span {
    display: block;

    margin-bottom: 16px;

    color: #7ac98e;

    font-family: Inter, system-ui, sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .2em;
}

.we-bg-network-content h2 {
    margin: 0 0 14px;

    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(40px, 7vw, 72px);
    font-weight: 500;
    line-height: 1;
}

.we-bg-network-content p {
    margin: 0;

    color: rgba(244, 241, 233, .62);

    font-family: Inter, system-ui, sans-serif;
    font-size: 14px;
    line-height: 1.7;
}
JavaScript
document.querySelectorAll(".we-bg-network").forEach(background => {

    const canvas = background.querySelector(
        ".we-bg-network-canvas"
    );

    const ctx = canvas.getContext("2d");

    let width;
    let height;
    let animationFrame;

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

    const particles = [];

    function resize() {

        const rect = background.getBoundingClientRect();

        width = canvas.width = rect.width;
        height = canvas.height = rect.height;

        particles.length = 0;

        const count = Math.min(
            70,
            Math.max(35, Math.floor(width / 14))
        );

        for (let i = 0; i < count; i++) {

            particles.push({
                x: Math.random() * width,
                y: Math.random() * height,
                vx: (Math.random() - .5) * .22,
                vy: (Math.random() - .5) * .22,
                size: Math.random() * 1.5 + .6
            });
        }
    }

    function draw() {

        ctx.clearRect(0, 0, width, height);

        particles.forEach(particle => {

            if (mouse.x !== null) {

                const dx = particle.x - mouse.x;
                const dy = particle.y - mouse.y;

                const distance =
                    Math.sqrt(dx * dx + dy * dy);

                if (distance < 110 && distance > 0) {

                    const force =
                        (110 - distance) / 110;

                    particle.x +=
                        (dx / distance) * force * .8;

                    particle.y +=
                        (dy / distance) * force * .8;
                }
            }

            particle.x += particle.vx;
            particle.y += particle.vy;

            if (particle.x < -20) particle.x = width + 20;
            if (particle.x > width + 20) particle.x = -20;

            if (particle.y < -20) particle.y = height + 20;
            if (particle.y > height + 20) particle.y = -20;

            ctx.beginPath();

            ctx.arc(
                particle.x,
                particle.y,
                particle.size,
                0,
                Math.PI * 2
            );

            ctx.fillStyle =
                "rgba(122, 201, 142, .55)";

            ctx.fill();
        });

        for (let i = 0; i < particles.length; i++) {

            for (let j = i + 1; j < particles.length; j++) {

                const dx =
                    particles[i].x - particles[j].x;

                const dy =
                    particles[i].y - particles[j].y;

                const distance =
                    Math.sqrt(dx * dx + dy * dy);

                if (distance < 105) {

                    const opacity =
                        (1 - distance / 105) * .24;

                    ctx.beginPath();

                    ctx.moveTo(
                        particles[i].x,
                        particles[i].y
                    );

                    ctx.lineTo(
                        particles[j].x,
                        particles[j].y
                    );

                    ctx.strokeStyle =
                        `rgba(122, 201, 142, ${opacity})`;

                    ctx.lineWidth = .7;

                    ctx.stroke();
                }
            }
        }

        animationFrame =
            requestAnimationFrame(draw);
    }

    background.addEventListener("mousemove", event => {

        const rect = background.getBoundingClientRect();

        mouse.x =
            event.clientX - rect.left;

        mouse.y =
            event.clientY - rect.top;
    });

    background.addEventListener("mouseleave", () => {

        mouse.x = null;
        mouse.y = null;
    });

    window.addEventListener("resize", resize);

    resize();
    draw();
});