Reputation: 819
I have a typing animation on a html web page. I want to rotate the text in an array but ensure each item in the array stays on the page rather than being deleting before the next one starts.
var TxtRotate = function (el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
};
TxtRotate.prototype.tick = function () {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">' + this.txt + '</span>';
var that = this;
var delta = 300 - Math.random() * 100;
if (this.isDeleting) { delta /= 2; }
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 500;
}
setTimeout(function () {
that.tick();
}, delta);
};
window.onload = function () {
var elements = document.getElementsByClassName('txt-rotate');
for (var i = 0; i < elements.length; i++) {
var toRotate = elements[i].getAttribute('data-rotate');
var period = elements[i].getAttribute('data-period');
if (toRotate) {
new TxtRotate(elements[i], JSON.parse(toRotate), period);
}
}
// INJECT CSS
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".txt-rotate > .wrap { border-right: 0.08em solid #666 }";
document.body.appendChild(css);
};
<h1>
We develop
<span class="txt-rotate"
data-period="2000"
data-rotate='[ "websites.", "databases.", "in HTML and CSS.", "in ASP.NET.", "in C#.", "using Bootstrap."]'></span>
</h1>
Expected output:
We develop websites.
databases.
in HTML and CSS.
in ASP.NET
in C#.
using Bootstrap.
Each item in the array needs to be typed first before the next one starts being typed. Once all items have been typed, it needs to stay on the page as a list, the animation should stop and not repeat.
Upvotes: 1
Views: 1811
Reputation: 2984
var TxtRotate = function (el, toRotate, period, fixedText) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.fixedText=fixedText;
this.tick();
this.isDeleting = false;
};
TxtRotate.prototype.tick = function () {
//Stops when text completes
if(this.loopNum >= this.toRotate.length) return;
var i = this.loopNum;
var fullTxt = this.toRotate[i];
// Get the letter to substring that needs to be appended in the span
this.txt = fullTxt.substring(0, this.txt.length + 1);
if(this.loopNum === 0) {
this.el.innerHTML = '<span class="wrap">' +this.fixedText+' '+ this.txt + '</span>';
}else{
//adds a letter on the screen
var spacing = '';
var countSpacing = 0
while(countSpacing < (this.fixedText.length * 2) + 1) {spacing = spacing+" "; countSpacing++;}
this.el.innerHTML = '<span class="wrap">' +spacing+ this.txt + '</span>';
}
var that = this;
//calculates the time to wait before writing next letter
var delta = 300 - Math.random() * 100;
// If backspacing reduce it by half
if (this.isDeleting) { delta /= 2; }
// If the word is complete
if (!this.isDeleting && this.txt === fullTxt) {
//add a delay of 500mx
delta = 500;
// add a new line (</br>
this.el.innerHTML = `<span class="wrap">${this.el.textContent}</br></span>`;
// add a sibling element to you element
var next_txt=document.createElement("span");
// add sibling element to the parent
this.el.parentNode.appendChild(next_txt);
// make your self new element, so that it writes into the new element next time
this.el = next_txt;
// pick the next word
this.loopNum++;
//clear current txt
this.txt = '';
}
setTimeout(function () {
that.tick();
}, delta);
};
window.onload = function () {
var elements = document.getElementsByClassName('txt-rotate');
for (var i = 0; i < elements.length; i++) {
var toRotate = elements[i].getAttribute('data-rotate');
var period = elements[i].getAttribute('data-period');
var fixedText = elements[i].getAttribute('data-fixed');
if (toRotate) {
new TxtRotate(elements[i], JSON.parse(toRotate), period, fixedText);
}
}
// INJECT CSS
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".txt-rotate > .wrap { border-right: 0.08em solid #666 }";
document.body.appendChild(css);
};
<h1>
<span class="txt-rotate"
data-period="2000"
data-fixed="We develop"
data-rotate='[ "websites.", "databases.", "in HTML and CSS.", "in ASP.NET.", "in C#.", "using Bootstrap."]'></span>
</h1>
See if this is what you want @RA
Upvotes: 2