RA19
RA19

Reputation: 819

Typing Animation Javascript HTML rotation from array

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

Answers (1)

Dave Ranjan
Dave Ranjan

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+"&nbsp;"; 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

Related Questions