Skip to main content

Hero Animation

The Hero Animation component provides an elegant rotating text effect, perfect for hero sections where you want to cycle through different words or phrases.

Overview

Implemented in hero-animation.js, this component creates a smooth letter-by-letter animation that cycles through multiple words, creating an engaging visual effect for headlines.

Implementation

The core animation logic from hero-animation.js:1:
(function() {
    'use strict';

    function initHeroAnimation() {
        const words = document.getElementsByClassName('word');
        if (words.length === 0) return;

        const wordArray = [];
        let currentWord = 0;

        words[currentWord].style.opacity = 1;

        for (let i = 0; i < words.length; i++) {
            splitLetters(words[i]);
        }

        function changeWord() {
            const cw = wordArray[currentWord];
            const nw = currentWord == words.length - 1 ? wordArray[0] : wordArray[currentWord + 1];

            for (let i = 0; i < cw.length; i++) {
                animateLetterOut(cw, i);
            }

            for (let i = 0; i < nw.length; i++) {
                nw[i].className = 'letter behind';
                nw[0].parentElement.style.opacity = 1;
                animateLetterIn(nw, i);
            }

            currentWord = (currentWord == words.length - 1) ? 0 : currentWord + 1;
        }

        changeWord();
        setInterval(changeWord, 4000);
    }
})();

Letter Animation

Animate Out

From hero-animation.js:38:
function animateLetterOut(cw, i) {
    setTimeout(function () {
        cw[i].className = 'letter out';
    }, i * 80);
}

Animate In

From hero-animation.js:44:
function animateLetterIn(nw, i) {
    setTimeout(function () {
        nw[i].className = 'letter in';
    }, 340 + (i * 80));
}

Text Splitting

The component splits words into individual letter spans (hero-animation.js:50):
function splitLetters(word) {
    const content = word.innerHTML;
    word.innerHTML = '';
    const letters = [];

    for (let i = 0; i < content.length; i++) {
        const letter = document.createElement('span');
        letter.className = 'letter';

        if (content.charAt(i) === '¨') {
            letter.innerHTML = '&nbsp;';
            letter.style.opacity = '0';
        } else {
            letter.innerHTML = content.charAt(i);
        }

        word.appendChild(letter);
        letters.push(letter);
    }

    wordArray.push(letters);
}

Search Focus Handler

Bonus feature - automatic search input focus (hero-animation.js:77):
function initSearchContainerFocus() {
    const searchContainer = document.querySelector('.search-container');
    if (searchContainer) {
        searchContainer.addEventListener('click', function (event) {
            const isFilterButton = event.target.closest('.filter-toggle');
            if (!isFilterButton) {
                const searchInput = document.getElementById('is-search-input-10380') || 
                                  document.getElementById('klef-search');
                if (searchInput) {
                    searchInput.focus();
                }
            }
        });
    }
}

Auto-Initialization

From hero-animation.js:94:
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        initHeroAnimation();
        initSearchContainerFocus();
    });
} else {
    initHeroAnimation();
    initSearchContainerFocus();
}

HTML Structure

To use the hero animation, structure your HTML like this:
<div class="hero-text">
  <h1>
    We create 
    <span class="rotating-words">
      <span class="word">brands</span>
      <span class="word">experiences</span>
      <span class="word">solutions</span>
      <span class="word">impact</span>
    </span>
  </h1>
</div>

CSS Requirements

You’ll need CSS to handle the letter animations:
.letter {
  display: inline-block;
  position: relative;
  transition: all 0.3s ease;
}

.letter.out {
  transform: translateY(-100%);
  opacity: 0;
}

.letter.behind {
  transform: translateY(100%);
  opacity: 0;
}

.letter.in {
  transform: translateY(0);
  opacity: 1;
}

Configuration

Animation Timing

  • Letter out delay: 80ms per letter (line 41)
  • Letter in delay: 80ms per letter + 340ms offset (line 47)
  • Word change interval: 4000ms (4 seconds) (line 74)

Special Characters

The component supports the special character ¨ for invisible spacing:
<span class="word">hello¨world</span>
<!-- Creates: hello world with invisible space -->

Usage Example

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="hero-section">
    <h1>
      Building 
      <span class="rotating-words">
        <span class="word">tomorrow</span>
        <span class="word">innovation</span>
        <span class="word">the future</span>
      </span>
    </h1>
  </div>

  <script src="/shared/components/hero/hero-animation.js"></script>
</body>
</html>

Performance Notes

  • Uses setTimeout for precise timing control
  • Minimal DOM manipulation after initialization
  • Only animates visible words
  • No dependencies required

Browser Support

Works in all modern browsers that support:
  • ES6 arrow functions
  • getElementsByClassName
  • setTimeout
  • CSS transitions

Build docs developers (and LLMs) love