Vissza az animációkhoz
Szöveganimációk

Írógép – becsomagolódó visszafelé mozgással.

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

Élő előnézet
HTML · CSS · JS
HTML
<div class="we-typewriter-card">
    <h2 class="we-typewriter">
        Fedezd fel a világ rejtett csodáit.
    </h2>
</div>
CSS
.we-typewriter-card {
    display: inline-block;
    padding: 34px 46px;

    background: #f4f1e9;
    border: 1px solid rgba(0, 0, 0, .08);
    border-radius: 18px;

    box-shadow:
        0 18px 45px rgba(0, 0, 0, .22);

    overflow: hidden;
}

.we-typewriter {
    margin: 0;

    color: #111111;
    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(30px, 5vw, 64px);
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: .01em;

    text-align: center;
    white-space: nowrap;
}

.we-typewriter::after {
    content: "";
    display: inline-block;
    width: 2px;
    height: 1em;
    margin-left: 5px;

    vertical-align: -.12em;

    background: #111111;

    animation: weTypewriterCursor .8s step-end infinite;
}

@keyframes weTypewriterCursor {
    0%,
    50% {
        opacity: 1;
    }

    51%,
    100% {
        opacity: 0;
    }
}

@media (max-width: 700px) {
    .we-typewriter-card {
        max-width: 100%;
        padding: 28px 24px;
    }

    .we-typewriter {
        white-space: normal;
    }
}
JavaScript
document.querySelectorAll(".we-typewriter").forEach(element => {

    const originalText = element.textContent.trim();

    element.textContent = "";

    let position = 0;
    let deleting = false;

    const typingSpeed = 75;
    const deletingSpeed = 48;
    const pauseAfterTyping = 1800;
    const pauseAfterDeleting = 650;

    function typeText() {

        if (!deleting) {

            element.textContent =
                originalText.slice(0, position);

            position++;

            if (position > originalText.length) {
                deleting = true;

                setTimeout(
                    deleteText,
                    pauseAfterTyping
                );

                return;
            }

            setTimeout(
                typeText,
                typingSpeed
            );

        } else {

            deleteText();
        }
    }

    function deleteText() {

        element.textContent =
            originalText.slice(0, position);

        position--;

        if (position < 0) {
            position = 0;
            deleting = false;

            setTimeout(
                typeText,
                pauseAfterDeleting
            );

            return;
        }

        setTimeout(
            deleteText,
            deletingSpeed
        );
    }

    typeText();
});