skip to Main Content

I need to make animation like on this website in menu:
https://displaay.net/typefaces/retail/

Is there an existing solutions? I’ve tried to make it with copilot, but didn’t succeed.

<script>
document.addEventListener('DOMContentLoaded', function() {
    var titles = [
        'Text1',
        'Text12',
        'Text3'
    ];
    var currentIndex = 0;

    function changeTitle() {
        // Select the _H1 element
        var element = document.querySelector('._H1');
        if (element) {
            // Split the current title into characters and wrap each character in a span
            var chars = element.textContent.split('');
            element.innerHTML = chars.map(char => `<span>${char}</span>`).join('');

            // Function to change a character to a random one
            function changeChar(index) {
                if (index < chars.length) {
                    var randomChar = String.fromCharCode(Math.floor(Math.random() * (126 - 33 + 1)) + 33);
                    chars[index] = `<span class="animate">${randomChar}</span>`;
                    element.innerHTML = chars.join('');
                    setTimeout(() => changeChar(index + 1), 20); // Adjust the delay as needed
                } else {
                    // After all characters have changed, change the text to the next title
                    setTimeout(() => {
                        element.innerHTML = titles[currentIndex];
                        currentIndex = (currentIndex + 1) % titles.length; // Loop through the titles
                    }, 2000); // Wait for 2 seconds before changing the text
                }
            }

            // Start changing the characters
            changeChar(0);
        }
    }

    // Change the title immediately and then every 5 seconds
    changeTitle();
    setInterval(changeTitle, 5000); // 5000 milliseconds = 5 seconds
});

2

Answers


  1. Inspired by you initial code I did the following. It creates a randon string, and as long as that character is not the right one it will continue with another random character. Until it gets the entire string correct or 100 "rounds" has passed.

    const max_count = 100;
    const interval_ms = 30;
    
    document.addEventListener('DOMContentLoaded', e => {
      document.querySelectorAll('.animated').forEach(elm => animateText(elm));
    });
    
    function animateText(element, interval) {
      if (element.initialtext) {
        element.count++;
        let randomStr = Object.keys(element.initialtext)
          .map(i => String.fromCharCode(Math.floor(Math.random() * (126 - 33 + 1)) + 33)).join('');
        element.animatedStr = Object.keys(element.initialtext)
          .map(i => (element.animatedStr[i] == element.initialtext[i]) ? element.animatedStr[i] : randomStr[i]).join('');
        element.textContent = (element.count < max_count) ? element.animatedStr : element.initialtext;
        if (element.textContent != element.initialtext) {
          setTimeout(() => {animateText(element)}, interval_ms);
        } else {
          delete element.count;
          delete element.initialtext;
          delete element.animatedStr;
        }
      } else {
        element.count = 0;
        element.initialtext = element.textContent;
        element.animatedStr = Object.keys(element.initialtext).map(i => ' ').join('');
        element.innerHTML = '';
        animateText(element);
      }
    }
    <h1 class="animated">Some title</h1>
    <h1><span class="animated">Some</span> <span class="animated">title</span></h1>
    Login or Signup to reply.
  2. This isn’t precise, but it’s a start. Let me know what can be improved.

    Improvement: Randomizing all the letters that aren’t the same as the equivalent position letter in the target word. Pretty much like the other answer.

    function randomChar() {
      return String.fromCharCode(Math.floor(Math.random() * (126 - 33 + 1)) + 33)
    }
    
    function randomWord(length) {
      var arr = []
      for (var i = 0; i < length; i++) {
        arr.push(randomChar())
      }
      return arr.join('')
    }
    
    function wordToTarget(word, target) {
      var arr = word.split('')
      var brr = target.split('')
      var crr = []
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] === brr[i]) {
          crr.push(arr[i])
        } else {
          crr.push(randomChar())
        }
      }
      return crr.join('')
    }
    
    function setTitle(element, title, index, iterations, delay) {
      if (index === iterations) {
        element.innerText = title
        return
      }
    
      if (index <= title.length) {
        var word = randomWord(index)
      } else {
        word = wordToTarget(element.innerText, title)
      }
      element.innerText = word
    
      setTimeout(function() {
        setTitle(element, title, index + 1, iterations, delay)
      }, delay)
    }
    
    var titles = [
      'Display',
      'TypeFace',
      'Custom'
    ];
    var elems = document.querySelectorAll(".word")
    elems.forEach(function(elem, index) {
    
      setTimeout(function() {
        setTitle(elem, titles[index], 0, 100, 25)
      }, index * 300)
    
    })
    h1 {
      display: inline;
      margin-right: 30px;
    }
    <h1 class="word"></h1>
    <h1 class="word"></h1>
    <h1 class="word"></h1>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search