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)
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?
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.
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.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With