Harshit
Harshit

Reputation: 1565

How to animate the text in a for-loop?

I'm trying to create a sidebar animation effect as:

<div class="sidebar-description sidebar-personal-info-section">
    A passionate
    <span class="changing-keywords" id="change">
        <strong>
            <b class="hidden">software engineer</b>
            <b class="hidden">lifelong learner</b>
            <b class="hidden">blogger</b>
            <b class="hidden">traveller</b>
        </strong>
    </span><br>
</div>

I've written the HTML code but issue is that how should I display each text one at a time with small delay with slide-out animation effect? The loop should work infinite times.

Upvotes: 1

Views: 4300

Answers (4)

Nimitt Shah
Nimitt Shah

Reputation: 4587

Make it simple by using CSS key-frame animation.

Below is an example.

body{
    font-family:calibri;
  }
.codinfox-changing-keywords{
  vertical-align:top;
  overflow:hidden;
  height:20px;
  position:relative;
  display: inline-block;
    width: 250px;
}
.hidden{
  position:absolute;
  top: 20px;
  display:inline-block;
  width:250px;
    opacity:0;
  animation: slideme 8s infinite;
}
.hidden:nth-child(3){
  animation-delay: 2s;
}
.hidden:nth-child(5){
  animation-delay: 4s;
}
.hidden:nth-child(7){
  animation-delay: 6s;
}

@keyframes slideme {
  0% {
    top: 20px;
    opacity:0;
  }
  5% {
    top: 0px;
    opacity:1;
  }
  10%{
    top : 0;
    opacity:1;
  }
  20%{
    opacity:1;
  }
  25% {    
  opacity:0.1;
    top : 0;
  }
  30% {
    opacity:0;
    top: 20px;
  }
}
<div class="codinfox-sidebar-description sidebar-personal-info-section">
    A passionate
    <div class="codinfox-changing-keywords" id="change">
        <strong>
            <b class="hidden">software engineer</b><br/>
            <b class="hidden">lifelong learner</b><br/>
            <b class="hidden">blogger</b><br/>
            <b class="hidden">traveller</b>
        </strong>
    </div>
</div>

You can test it here as well!

Upvotes: 5

rufus1530
rufus1530

Reputation: 795

First, you need to work a little bit on your HTML. The <strong> tag shouldn't be used to style elements, not to mention the <b> tags. Below is my version of the code. First the HTML:

<div class="codinfox-sidebar-description sidebar-personal-info-section">
    A passionate
    <span class="changing-keyword shown">software engineer</span>
    <span class="changing-keyword">lifelong learner</span>
    <span class="changing-keyword">blogger</span>
    <span class="changing-keyword">traveller</span>
</div>

I took the liberity to change the class names and remove some tags that were, in my opinion, unnecessary here. Now, JavaScript:

const changingKeywords = document.querySelectorAll('span.changing-keyword');
const keywordsToggle = setKeywordsToggle(changingKeywords);

function setKeywordsToggle (keywords) {
    let index = 0;
  return setInterval(() => {
    keywords[index].classList.remove('shown');
    if (++index >= keywords.length) 
        index = 0;
    keywords[index].classList.add('shown');
  }, 2000);
}

Notice that I actually return the setInterval() function and assign it to keywordsToggle variable. This way, if I ever want to stop the animation, I can easily do so by running clearInterval(). The code toggles through all keywords it finds and assigns the shown class to the element determined by the value of index variable.

Finally, sample CSS:

.sidebar-personal-info-section {
  position: relative;
}

.changing-keyword {
  font-weight: bold;
  opacity: 0;
  transition: opacity 1s, visibility 1s;
  visibility: collapse;
  position: absolute;
  padding-left: .2rem;
}

.shown {
  opacity: 1;
  visibility: visible;
}

Notice the visibility transition, which actually works as transition delay. Other than that, I had to use a position property to make sure that every keyword is positioned near the "passionate" word, otherwise every word would appear in it's original position (I didn't use display:none since it's not animatable).

Working example:

const changingKeywords = document.querySelectorAll('span.changing-keyword');
const keywordsToggle = setKeywordsToggle(changingKeywords);

function setKeywordsToggle (keywords) {
	let index = 0;
  return setInterval(() => {
  	keywords[index].classList.remove('shown');
    if (++index >= keywords.length) 
    	index = 0;
    keywords[index].classList.add('shown');
  }, 2000);
}
.sidebar-personal-info-section {
  position: relative;
}

.changing-keyword {
  font-weight: bold;
  opacity: 0;
  transition: opacity 1s, visibility 1s;
  visibility: collapse;
  position: absolute;
  padding-left: .2rem;
}

.shown {
  opacity: 1;
  visibility: visible;
}
<div class="codinfox-sidebar-description sidebar-personal-info-section">
    A passionate
    <span class="changing-keyword shown">software engineer</span>
    <span class="changing-keyword">lifelong learner</span>
    <span class="changing-keyword">blogger</span>
    <span class="changing-keyword">traveller</span>
</div>

Upvotes: 1

Harshit
Harshit

Reputation: 1565

This something what I finally figured out!

var title = ['software engineer', 'tech blogger', 'traveller', 'lifelong learner'];

var i = 0;  // the index of the current item to show

setInterval(function() {            // setInterval makes it run repeatedly
  document
    .getElementById('change')
    .innerHTML = title[i++];    // get the item and increment
  if (i == title.length) i = 0;   // reset to first element if you've reached the end
}, 2000); 

Upvotes: 0

4m1r
4m1r

Reputation: 12542

My quick and dirty would look something like this.

// add rotate to Array
Array.prototype.rotate = function(n) {
    return this.slice(n, this.length).concat(this.slice(0, n));
}

// setup array
const jobs = ['employee', 'manager'];

// rotate jobs function
const rotateJobs = () => {
    document.querySelector('#id').innerHtml = jobs.rotate(1).shift();
}

// set interval
setInterval(rotateJobs, 1000);

The fade in / slide animation should be handled in css transitions.

Upvotes: 0

Related Questions