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

Perspektivikus digitális rács

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

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

    <div class="we-bg-grid-lines"></div>

    <div class="we-bg-grid-content">
        <span>WEBELEMENTS</span>
        <h2>Digitális tér</h2>
        <p>
            Egy végtelennek tűnő tér, amely lassan folyamatos mozgásban marad.
        </p>
    </div>

</div>
CSS
.we-bg-grid {
    position: relative;
    width: 100%;
    min-height: 520px;
    overflow: hidden;
    background: #080b11;
    display: flex;
    align-items: center;
    justify-content: center;
    isolation: isolate;
    perspective: 700px;
}

.we-bg-grid-lines {
    position: absolute;
    width: 180%;
    height: 180%;
    left: -40%;
    top: 38%;
    transform:
        perspective(500px)
        rotateX(62deg);
    transform-origin: center top;

    background-image:
        linear-gradient(
            rgba(95, 189, 125, .20) 1px,
            transparent 1px
        ),
        linear-gradient(
            90deg,
            rgba(95, 189, 125, .20) 1px,
            transparent 1px
        );

    background-size: 70px 70px;

    mask-image:
        linear-gradient(
            to bottom,
            transparent 0%,
            rgba(0, 0, 0, .95) 18%,
            #000 100%
        );

    -webkit-mask-image:
        linear-gradient(
            to bottom,
            transparent 0%,
            rgba(0, 0, 0, .95) 18%,
            #000 100%
        );

    animation: weGridMove 7s linear infinite;
}

@keyframes weGridMove {
    from {
        transform:
            perspective(500px)
            rotateX(62deg)
            translateY(0);
    }

    to {
        transform:
            perspective(500px)
            rotateX(62deg)
            translateY(70px);
    }
}

.we-bg-grid::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(
            ellipse at center 45%,
            transparent 0%,
            rgba(8, 11, 17, .12) 45%,
            rgba(8, 11, 17, .92) 100%
        );
    z-index: 2;
    pointer-events: none;
}

.we-bg-grid-content {
    position: relative;
    z-index: 3;
    max-width: 680px;
    padding: 45px;
    text-align: center;
    pointer-events: none;
}

.we-bg-grid-content span {
    display: block;
    margin-bottom: 16px;
    color: #7ac98e;
    font-family: Inter, system-ui, sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .24em;
}

.we-bg-grid-content h2 {
    margin: 0 0 16px;
    color: #f4f1e9;
    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(42px, 7vw, 78px);
    font-weight: 500;
    line-height: 1;
}

.we-bg-grid-content p {
    margin: 0 auto;
    max-width: 540px;
    color: rgba(244, 241, 233, .62);
    font-family: Inter, system-ui, sans-serif;
    font-size: 14px;
    line-height: 1.8;
}

@media (max-width: 700px) {

    .we-bg-grid {
        min-height: 460px;
    }

    .we-bg-grid-lines {
        background-size: 48px 48px;
    }

    .we-bg-grid-content {
        padding: 30px 22px;
    }
}
JavaScript
document.querySelectorAll(".we-bg-grid").forEach(container => {

    const grid = container.querySelector(".we-bg-grid-lines");

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

        const rect = container.getBoundingClientRect();

        const x =
            (event.clientX - rect.left) /
            rect.width;

        const y =
            (event.clientY - rect.top) /
            rect.height;

        const moveX = (x - .5) * 18;
        const moveY = (y - .5) * 10;

        grid.style.marginLeft = `${moveX}px`;
        grid.style.marginTop = `${moveY}px`;
    });

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

        grid.style.marginLeft = "0px";
        grid.style.marginTop = "0px";
    });

});