Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raise ( Reveal ) text from bottom css animation

I was just going through the web and found some cool text animations over here. so I thought of taking a part of it and extending it. As I know what to do first I went through the stack to find out whether any question will relate my idea and for my surprise, I had found one that explains what I need but that has not been answered correctly. I guess the main cause was because it was not explained correctly. so I will try my best to explain the idea.

Previously asked question

The Idea.

Let's suppose I have a heading tag that I need to animate. Them main Idea is not to break one same sentence into two instead if you write a heading or paragraph tag the whole thing should animate. I want to lift/reveal/raise the words from where they are in the image (from the line)enter image description here

I have changed some of the existing code from the source I got. But the text is revealing/raising from the bottom of the whole block. Which I don't want. I want it to raise them from the line at bottom.

The Code:

// Wrap every letter in a span
$('.ml16').each(function() {
  $(this).html($(this).text().replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>"));
});

anime.timeline({
    loop: true
  })
  .add({
    targets: '.ml16 .letter',
    translateY: [100, 0],
    easing: "easeOutExpo",
    duration: 1400,
    delay: function(el, i) {
      return 30 * i;
    }
  }).add({
    targets: '.ml16',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
.wrap {
  width: 700px;
  margin: 100px auto;
}

.ml16 {
  color: #402d2d;
  padding: 40px 0;
  font-weight: 800;
  font-size: 2em;
  text-transform: uppercase;
  letter-spacing: 0.5em;
  overflow: hidden;
  text-transform: uppercase;
  font-family: sans-serif;
}

.ml16 .letter {
  display: inline-block;
  line-height: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>

<div class="wrap">
  <h1 class="ml16"><span>Made with love for a testing purpose</span></h1>
</div>

Can someone help me pushing my incomplete idea to a destination?

like image 408
Mohammed Wahed Khan Avatar asked Jul 19 '19 10:07

Mohammed Wahed Khan


People also ask

Can you animate text in CSS?

But there are some animations that can be made using only CSS. One of them is changing the word text animation. In this type of animation, a word is selected to change after a certain time interval.

How do you do a fade effect in CSS?

Method 1: Using CSS animation property: A CSS animation is defined with 2 keyframes. One with the opacity set to 0, the other with the opacity set to 1. When the animation type is set to ease, the animation smoothly fades in the page. This property is applied to the body tag.

How do you get the typewriter effect in CSS?

Note that, in order for the typewriter effect to work, we've added the following: "overflow: hidden;" and a "width: 0;" , to make sure the text content isn't revealed until the typing effect has started. "border-right: . 15em solid orange;" , to create the typewriter cursor.


1 Answers

What you need to do is wrap each word in another span (say, <span class="word"></span>) and set an overflow: hidden to that - see this fiddle: https://jsfiddle.net/w5uz4mex/

This will ensure that each word independently gets 'hidden' as it animates.

// Wrap every word in a span
$('.ml16').each(function() {
  let text = $(this).text();
  let words = text.split(' ');
  
  // Clear current element
  this.innerHTML = '';
  
  // Loop through each word, wrap each letter in a span
  for(let word of words) {
    let word_split = word.replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>");
    
    // Wrap another span around each word, add word to header
    this.innerHTML += '<span class="word">' + word_split + '</span>';
  }
});

anime.timeline({
    loop: true
  })
  .add({
    targets: '.ml16 .letter',
    translateY: [100, 0],
    easing: "easeOutExpo",
    duration: 1400,
    delay: function(el, i) {
      return 30 * i;
    }
  }).add({
    targets: '.ml16',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
.wrap {
  width: 700px;
  margin: 100px auto;
}

.ml16 {
  color: #402d2d;
  padding: 40px 0;
  font-weight: 800;
  font-size: 2em;
  text-transform: uppercase;
  letter-spacing: 0.5em;
  overflow: hidden;
  text-transform: uppercase;
  font-family: sans-serif;
}

.ml16 .word {
  display: inline-block;
  overflow: hidden;
  height: 2em;
  margin: 0 0.4em;
}

.ml16 .letter {
  display: inline-block;
  line-height: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="wrap">
  <h1 class="ml16">Made with love for a testing purpose</h1>
</div>

Edit: As a bonus (unrelated) this can be done very simply without jQuery, and instead utilising CSS animations. This also gives you the benefit of very easily being able to add new animations via the CSS, without having to touch the JS. This is just a quick demo, so should be used as a starting point only (i.e. it has not been tested for any production environment).

See below for an example of slideUp, slideDown and zoomIn

/**
 * Create new class for sliding text
 *
 * @params {Element} wrapper - HTML element with text content
 */
class TextSliderUpper {
  constructor(wrapper) {
    this.wrapper = wrapper;

    // Set delay between characters (in ms)
    this.delay = 40;

    // Wrap content in relevant wrappers
    this._wrapContent();
  }

  _wrapContent() {
    let words = this.wrapper.textContent.split(' ');
    let delay = 0;
    let content = '';

    // Loop through each word, wrap each character in a span
    words.forEach((word, multiplier) => {
      let word_split = word.split(/([^\x00-\x80]|\w)/g);
      let word_content = '';

      // Look through each letter, add a delay (incremented)
      word_split.forEach((char, index) => {
        delay += this.delay;

        word_content += `<span style="animation-delay: ${delay}ms">${char}</span>`;
      });

      // Add spacing between words
      if (content !== '') content += ' ';

      // Add wrapped words to content
      content += `<span>${word_content}</span>`;
    })

    // Add content to wrapper
    this.wrapper.innerHTML = content;
  }

  init() {
    this.wrapper.classList.add('show');
  }
}

// Get a list of all headers
let headers = document.querySelectorAll('[data-animate]');

// Loop through, add relevant class
Array.from(headers).forEach(header => {
  let slideHeader = new TextSliderUpper(header);

  // Allow for delays? Sure!
  let delay = header.dataset.delay || 0;

  // Delay class (if necessary)
  setTimeout(() => {
    slideHeader.init();
  }, delay)
})
body {
  font-family: sans-serif;
}

h1 {
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 0.1em;
}

[data-animate] {
  line-height: 1.2em;
}
[data-animate] > span {
  display: inline-block;
  height: 1.2em;
  overflow: hidden;
}
[data-animate] > span > span {
  display: none;
  animation: 3s cubic-bezier(0, 1.2, 0.1, 0.9);
  animation-fill-mode: backwards;
}
[data-animate].show > span > span {
  display: inline-block;
}

[data-animate=slideup] > span > span {
  animation-name: slideUp;
}

[data-animate=zoomin] > span > span {
  animation-name: zoomIn;
}

[data-animate=slidedown] > span > span {
  animation-name: slideDown;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translate(0, 1.2em);
  }
}
@keyframes zoomIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
}
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translate(0, -1.2em);
  }
}
<h1 data-animate="slideup">This is some text. Hello there!</h1>

<hr />

<h1 data-animate="zoomin" data-delay="2000">I am delayed!</h1>

<hr />

<h1 data-animate="slidedown" data-delay="7000">I am late to the party!</h1>
like image 112
Oliver Avatar answered Sep 21 '22 10:09

Oliver