Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The purpose of the function is to attach CSS-animations to HTML-elements with a text-content property. Like for example h1, div, p etc.

It's not fully elaborated. Nevertheless have I decided to put it here for review.

So: Any hints and recommendations welcome.

/**
  * Adds an CSS-Animation to HTML-element which have a textContent-
  *   property, so that the single chars become animated.
  *
  * @param { string } selector - A CSS-selector which provides HTML-elements
  *   with an text-content property.
  * @param { object } itemTrigger 
  * @param { string } eventTrigger - E.g. 'click', 'focus', 'pointerleave'.
  * @param { string } classWithAnimation - CSS-class with 'animation'-property.
  * @param { number } timeBetween - Time between the single char animations.
  * @param { number } durationAnimation - Time until the animation is removed again.
  */

function addAnimationToText ( selector, itemTrigger, eventTrigger, 
                               classWithAnimation, timeBetween, durationAnimation ) {
  var text = document.querySelector(selector);
  var chars = text.textContent.split('');
  var spans = null;

  function wrapChars() {
    var wrapped = '';

    chars.forEach(function(item) {
      if (/\s/.test(item)) {
        wrapped += '<span>' + item + '</span>';
      } else {
        wrapped += '<span class="wrapped">' + item + '</span>';
      }			
    });

    return wrapped;
  }

  function addAnimationClass() {

    itemTrigger.addEventListener(eventTrigger, function() {

      spans.forEach(function(item, i) {
        const DELAY = i * timeBetween;

        setTimeout(function () {
          item.classList.add(classWithAnimation)
        }, DELAY);
        setTimeout(function () {
          item.classList.remove(classWithAnimation)
        }, DELAY + durationAnimation);
      });
    });
  }

  text.innerHTML = wrapChars();

  spans = document.querySelectorAll(selector + ' .wrapped');
  spans = Array.prototype.slice.call(spans);

  addAnimationClass();
}

var headline = document.querySelector('h1');
var exec = document.querySelector('#exec');
var subHeadline = document.querySelector('.sub-headline');
var paragraph = document.querySelector('p');

addAnimationToText('.main-headline', exec, 'click', 'single-char', 500, 1000);
addAnimationToText('.sub-headline', subHeadline, 'pointerover', 'single-char', 500, 1000);
addAnimationToText('p:first-of-type', paragraph, 'pointerover', 'changing-color-char', 100, 3000);
.wrap {
  width: 800px;
  margin: 50px auto;
  font-size: 32px;
  font-family: verdana, sans-serif;
  background-color: rgba(0, 90, 255, 0.1);
  padding: 20px 30px;
}

.single-char {
  text-shadow: 3px 3px 8px grey;
  color: orange;
  animation: moveY 1s;
  animation-iteration-count: 1;
}

.changing-color-char {
  animation: changeColor 3s;
  animation-iteration-count: infinite;
  font-weight: 800;
}

button:hover {
  cursor: pointer;
  opacity: 0.7;
}

.wrap p {
  font-size: 16px;
}

@keyframes changeColor {
  0% {
    color: red;
  }
  20% {
    color: orange;
  }
  40% {
    color: yellow;
  }
  60% {
    color: lime;
  }
  80% {
    color: blue;
  }
  100% {
    color: violet;
  }
}

@keyframes moveY {
  0% {
    opacity : 0;
    transform : translateY(0);
  }
  10% {
    opacity : 0.5;
    transform : translateY(-10px);
  }
  20% {
    opacity : 0.5;
    transform : translateY(-20px);
  }
  30% {
    opacity : 0.5;
    transform : translateY(-10px);
  }
  40% {
    opacity : 1.0;
    transform : translateY(0);
  }
  50% {
    opacity : 0.5;
    transform : translateY(10px);
  }
  60% {
    opacity : 0;
    transform : translateY(20px);
  }
  70% {
    opacity : 0;
    transform : translateY(30px);
  }
  80% {
    opacity : 0;
    transform : translateY(20px);
  }
  90% {
    opacity : 0;
    transform : translateY(10px);
  }
  100% {
    opacity : 0;
    transform : translateY(0);
  }
}
<div class="wrap">
  <h1 class="main-headline" id="main">Lorem Ipsum</h1>
  <div class="sub-headline" id="sub">Welcome to our homepage!</div>
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
    Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus
    mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
    Nulla consequat massa quis enim.</p>
  <button id="exec">Exec</button>
</div>

share|improve this question
    
If your animations are getting really complex, you might want to use a JavaScript animation library instead of CSS. – gcampbell Jun 9 at 17:25
    
@gcampbell Can you recommend one? Velocity.js one hears often. But that doesn't mean that it is really the best one. – mizech Jun 10 at 6:17
    
Well there's the Web Animations API, which will eventually become built into browsers but for now you have to use a polyfill. The library that's been around for a long time is GSAP, which is pretty reliable and has lots of features. There's also Velocity.js, newer than GSAP but also seems reliable. And if you're using jQuery 3 you can use its animations (but don't if you're using jQuery 2). – gcampbell Jun 10 at 8:47
    
@gcampbell The GSAP-showcases are awesome. Thanks a lot. :) – mizech Jun 10 at 10:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.