Mansi Shukla
Mansi Shukla

Reputation: 387

How to repeat Type Writer effect using JS?

I want to have a type writer effect on my website. Such that it repeats the data in array infinite times not just once.

I tried to build one with JS but it's only showing data in the array only one time.

For example I have an array :

var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];

I want it to be shown like this :

Amsterdam
Full Service.
Webdevelopment
Vivank

Amsterdam
Full Service.
Webdevelopment
Vivank

Amsterdam
Full Service.
Webdevelopment
Vivank.....

upto many times

What my code is doing it stops after one cycle. I want it to repeat cycle unlimited times.

Also, I am getting some kind of error.

Error: { "message": "Script error.", "filename": "", "lineno": 0, "colno": 0 }

Any Help?

Also how to add a pause to animation so that it starts to alter the text in p after a minute ?

Here is what i have tried so far :

document.addEventListener('DOMContentLoaded',function(event){
  // array with texts to type in typewriter
  var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
  
  // type one text in the typwriter
  // keeps calling itself until the text is finished
  function typeWriter(text, i, fnCallback) {
    // chekc if text isn't finished yet
    if (i < (text.length)) {
      // add next character to h1
     document.querySelector("#tw").innerHTML = text.substring(0, i+1) +'<span aria-hidden="true"></span>';

      // wait for a while and call this function again for next character
      setTimeout(function() {
        typeWriter(text, i + 1, fnCallback)
      }, 100);
    }
    // text finished, call callback if there is a callback function
    else if (typeof fnCallback == 'function') {
      // call callback after timeout
      setTimeout(fnCallback, 700);
    }
  }
  // start a typewriter animation for a text in the dataText array
   function StartTextAnimation(i) {
     if (typeof dataText[i] == 'undefined'){
        setTimeout(function() {
          StartTextAnimation(0);
        }, 20000);
     }
     // check if dataText[i] exists
    if (i < dataText[i].length) {
      // text exists! start typewriter animation
     typeWriter(dataText[i], 0, function(){
       // after callback (and whole text has been animated), start next text
       StartTextAnimation(i + 1);
     });
    }

  }
  // start the text animation
  StartTextAnimation(0);
});
<p id="tw">A</p>

Upvotes: 2

Views: 1321

Answers (2)

dev101
dev101

Reputation: 1369

You already have the condition to check for undefined index, but you missed the additional condition to restart your sequence.

Also, you have some poor choice of variable names, namely, index "i" in both functions can be confusing, as one function iterates over words in array, and the other one over characters.

I've rewritten your functions and make the entire code more production-friendly and human-readable of what-is-going-on:

// array with text to type in typewriter
var dataText = [
	"Web Design.",
	"Web Development.",
	"Web Programming."
];

// typewriter speed
// set delay time between each character typing time
var CharDelay = 50;

// pause time between each completed word (delay before next word starts)
var WordPause = 1000;

// set initial word in dataText array
var WordOffset = 0;

// set sequence restart interval N [ms]
var RestartInterval = 3000;

// type one text in the typewriter
// keeps calling itself until complete word is printed
function typeWriter(text, i, fnCallback) {
	// check if word isn't finished yet
	if (i < (text.length)) {
		// add next character to html
		document.querySelector("#typewriter").innerHTML = text.substring(0, i+1) + '<span aria-hidden="true"></span>';

		// wait for a while and call this function again for next character
		setTimeout(function() {
			typeWriter(text, i+1, fnCallback)
		}, CharDelay);
	}

	// text finished, call callback if there is a callback function
	else if (typeof fnCallback == 'function') {
		// call callback after timeout
		setTimeout(fnCallback, WordPause);
	}
}

// start a typewriter animation in the dataText array
// @param int j = dataText array word index
function StartTextAnimation(j) {
	//console.log(j);
	//console.log(dataText.length);
	// restart animation after N seconds
	if (typeof dataText[j] == 'undefined' || j == dataText.length) {
		setTimeout(function() {
			StartTextAnimation(WordOffset);
		}, RestartInterval);
	}

	// check if dataText[j] exists
	else if (j < dataText[j].length) {
		// text exists! start typewriter animation
		typeWriter(dataText[j], 0, function() {
			// after callback (and whole text has been animated), start next word
			StartTextAnimation((j+1));
		});
	}
}

document.addEventListener('DOMContentLoaded', function(event) {
	// start text animation
	StartTextAnimation(WordOffset);
});
<div id="typewriter"></div>

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370729

All you need to do is pass the i (the index of the item you're iterating over) modulo dataText.length, to ensure that once i reaches dataText.length, StartTextAnimation gets called with 0 rather than an index which doesn't exist:

StartTextAnimation((i + 1) % dataText.length);

document.addEventListener('DOMContentLoaded',function(event){
  // array with texts to type in typewriter
  var dataText = [ "Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];
  
  // type one text in the typwriter
  // keeps calling itself until the text is finished
  function typeWriter(text, i, fnCallback) {
    // chekc if text isn't finished yet
    if (i < (text.length)) {
      // add next character to h1
     document.querySelector("#tw").innerHTML = text.substring(0, i+1) +'<span aria-hidden="true"></span>';

      // wait for a while and call this function again for next character
      setTimeout(function() {
        typeWriter(text, i + 1, fnCallback)
      }, 100);
    }
    // text finished, call callback if there is a callback function
    else if (typeof fnCallback == 'function') {
      // call callback after timeout
      setTimeout(fnCallback, 700);
    }
  }
  // start a typewriter animation for a text in the dataText array
   function StartTextAnimation(i) {
     if (typeof dataText[i] == 'undefined'){
        setTimeout(function() {
          StartTextAnimation(0);
        }, 20000);
     }
     // check if dataText[i] exists
    if (i < dataText[i].length) {
      // text exists! start typewriter animation
     typeWriter(dataText[i], 0, function(){
       // after callback (and whole text has been animated), start next text
       StartTextAnimation((i + 1) % dataText.length);
     });
    }

  }
  // start the text animation
  StartTextAnimation(0);
});
<p id="tw">A</p>

Or, for a large delay after a full loop is done, use else if after the undefined check instead of if:

if (dataText[i] === undefined) {
  setTimeout(function() {
    StartTextAnimation(0);
  }, 20000);
} else if (i < dataText[i].length) {
  // text exists! start typewriter animation
  typeWriter(dataText[i], 0, function() {
    // after callback (and whole text has been animated), start next text
    StartTextAnimation(i + 1);
  });
}

document.addEventListener('DOMContentLoaded', function(event) {
  // array with texts to type in typewriter
  var dataText = ["Amsterdam.", "Full Service.", "Webdevelopment.", "Vivank"];

  // type one text in the typwriter
  // keeps calling itself until the text is finished
  function typeWriter(text, i, fnCallback) {
    // chekc if text isn't finished yet
    if (i < (text.length)) {
      // add next character to h1
      document.querySelector("#tw").innerHTML = text.substring(0, i + 1) + '<span aria-hidden="true"></span>';

      // wait for a while and call this function again for next character
      setTimeout(function() {
        typeWriter(text, i + 1, fnCallback)
      }, 100);
    }
    // text finished, call callback if there is a callback function
    else if (typeof fnCallback == 'function') {
      // call callback after timeout
      setTimeout(fnCallback, 700);
    }
  }
  // start a typewriter animation for a text in the dataText array
  function StartTextAnimation(i) {
    if (dataText[i] === undefined) {
      setTimeout(function() {
        StartTextAnimation(0);
      }, 20000);
    } else if (i < dataText[i].length) {
      // text exists! start typewriter animation
      typeWriter(dataText[i], 0, function() {
        // after callback (and whole text has been animated), start next text
        StartTextAnimation(i + 1);
      });
    }
  }
  // start the text animation
  StartTextAnimation(0);
});
<p id="tw">A</p>

Upvotes: 2

Related Questions