1

Here is JS+ Babel Typing animation, Now it start on-page load, and we can erase and retype it from the button given, But i want to repeat (Retype) it in every Three second if the Checked, How can i do that.

i tried this plz check:

class TextAnimation {

    constructor(text, opt_domElement) {
        this.text = text;
        this.curChar = 0;
        this.inTimeout = 0;
        this.outTimeout = 0;
        this.domElement = opt_domElement || this.createDomElement();
    }
    
    createDomElement() {
        const elem = document.createElement('p');
        elem.className = 'blink';
        elem.innerHTML = ' ';
        document.body.appendChild(elem);
        return elem;
    }

    getDelay(char, isLastChar = false) {
        let delay = this.delay;
        switch(char) {
            case ' ':
                delay = 3;
                break;
            case ',':
                delay = 3;
                break;
            case '.':
            case '!':
            case '?':
                delay = 3;
                break
            default:
                delay = 15;
           
 
        }

        if (isLastChar) {
            delay = 0;
        }
        return delay;
    }
    
    type(callback) {
        this.curChar++;
        this.domElement.innerHTML = this.text.substr(0, this.curChar);
        if (this.curChar < this.text.length + 1) {
            const prevChar = this.text.substr(this.curChar - 1 , 1);
            this.inTimeout = setTimeout(() => this.type(callback), this.getDelay(prevChar, this.curChar === this.text.length));
        } else {
            this.curChar = this.text.length;
            callback();
            return;
        }
        // console.log('type', this.curChar);
    }
    
    erase(callback) {
        this.curChar--;
        this.domElement.innerHTML = this.text.substr(0, this.curChar);
        if (this.curChar >= 0) {
            this.outTimeout = setTimeout(() => this.erase(callback), 10);
        } else {
            this.curChar = 0;
            callback();
            return;
        }
        // console.log('erase', this.curChar);
    }
    
    stopCurrentAnimation() {
        clearTimeout(this.inTimeout);
        clearTimeout(this.outTimeout);
    }
    
    animateIn(callback = () => {}) {
        this.stopCurrentAnimation();
        this.type(callback);
    }
    
    animateOut(callback = () => {}) {
        this.stopCurrentAnimation();
        this.erase(callback);
    }
    
}

console.clear();

const type = document.getElementById('type');
const erase = document.getElementById('erase');

const question = document.getElementById('qqq').innerHTML;
const foo = new TextAnimation(question);
foo.animateIn(() => { console.log('autoplay done'); });

type.addEventListener('click', () => foo.animateIn(() => { console.log('animation in done'); }), false);
erase.addEventListener('click', () => foo.animateOut(() => { console.log('animation out done'); }), false);
  html,
body {
    width: 100%;
    height: 100%;
    padding: 20px;
    margin: 0;
}

body {
    background-color: #000;
}

p {
    display: inline-block;
    font-family: monospace;
    font-size: 11px;
    line-height: 11px;
    min-height: 11px;
    color: #fff;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    margin: 0;
}

#qqq {display: none}


.blink:after {
    content: '';
    position: absolute;
    top: 0;
    right: -10px;
    width: 5px;
    height: 100%;
    background-color: #fff;
    animation: blinker 0.8s linear infinite;
}

@keyframes blinker {
    50% {
        opacity: 0;
    }
}
<button id="type">
    type
</button>
<button id="erase">
    erase
</button> <b style="color: yellow;">Checkbox:</b> <input type="checkbox" id="myCheck">
<br>

<div id="qqq">
<h3>This is the Typing Content , i want to make it in every three second it should be retype from start if the check button is cheked / enabled</h3> 
<h2>Any HTML Content</h2>

</div>
    <script type="text/javascript" src="https://fiddle.jshell.net/js/babel/babel.js"></script>
        <script src="https://fiddle.jshell.net/js/stringify.js" charset="utf-8"></script>

i tried to making solve this by trying this codes, But i didn't get success, i Hopw you master may be solve this. plz

RR Suthar
  • 653
  • 2
  • 10

1 Answers1

1

    class TextAnimation {

        constructor(text, opt_domElement) {
            this.text = text;
            this.curChar = 0;
            this.inTimeout = 0;
            this.outTimeout = 0;
            this.domElement = opt_domElement || this.createDomElement();
        }
        
        createDomElement() {
            const elem = document.createElement('p');
            elem.className = 'blink';
            elem.innerHTML = ' ';
            document.body.appendChild(elem);
            return elem;
        }
    
        getDelay(char, isLastChar = false) {
            let delay = this.delay;
            switch(char) {
                case ' ':
                    delay = 3;
                    break;
                case ',':
                    delay = 3;
                    break;
                case '.':
                case '!':
                case '?':
                    delay = 3;
                    break
                default:
                    delay = 15;
               
     
            }
    
            if (isLastChar) {
                delay = 0;
            }
            return delay;
        }
        
        
        type(callback) {
            this.curChar++;
            this.domElement.innerHTML = this.text.substr(0, this.curChar);
            if (this.curChar < this.text.length + 1) {
                const prevChar = this.text.substr(this.curChar - 1 , 1);
                this.inTimeout = setTimeout(() => this.type(callback), this.getDelay(prevChar, this.curChar === this.text.length));
            } else {
                this.curChar = this.text.length;
                callback();
                return;
            }
            // console.log('type', this.curChar);
        }
        
        erase(callback) {
            this.curChar--;
            this.domElement.innerHTML = this.text.substr(0, this.curChar);
            if (this.curChar >= 0) {
                this.outTimeout = setTimeout(() => this.erase(callback), 10);
            } else {
                this.curChar = 0;
                callback();
                return;
            }
            // console.log('erase', this.curChar);
        }
        
        stopCurrentAnimation() {
            clearTimeout(this.inTimeout);
            clearTimeout(this.outTimeout);
        }
        
        animateIn(callback = () => {}) {
            this.stopCurrentAnimation();
            this.type(callback);
        }
        
        animateOut(callback = () => {}) {
            this.stopCurrentAnimation();
            this.erase(callback);
        }
        
    }
    
    console.clear();
    
    

    const type = document.getElementById('type');
    const erase = document.getElementById('erase');
    
    const question = document.getElementById('qqq').innerHTML;
    const foo = new TextAnimation(question);
    foo.animateIn(() => { console.log('autoplay done'); });

    let i = true;
    let myInterval; 
    
    type.addEventListener('click', () => { 
        if(document.getElementById('myCheck').checked==true){
            foo.animateOut();
            myInterval=setInterval(() => {
                if(document.getElementById('myCheck').checked!=true){
                    clearInterval(myInterval);
                }
                    if(i==true){
                        i=false;
                        foo.animateIn();
                    }else{
                        i=true;
                        foo.animateOut();
                    }

                }, 3000);

            }else{
                clearInterval(myInterval);
                foo.animateIn();
            }
        }, false);
    erase.addEventListener('click', () => foo.animateOut(() => { 
        clearInterval(myInterval);
        console.log('animation out done'); }), false);
          html,
body {
    width: 100%;
    height: 100%;
    padding: 20px;
    margin: 0;
}

body {
    background-color: #000;
}

p {
    display: inline-block;
    font-family: monospace;
    font-size: 11px;
    line-height: 11px;
    min-height: 11px;
    color: #fff;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    margin: 0;
}

#qqq {display: none}


.blink:after {
    content: '';
    position: absolute;
    top: 0;
    right: -10px;
    width: 5px;
    height: 100%;
    background-color: #fff;
    animation: blinker 0.8s linear infinite;
}

@keyframes blinker {
    50% {
        opacity: 0;
    }
}
    <button id="type">
        type
    </button>
    <button id="erase">
        erase
    </button> <b style="color: yellow;">Checkbox:</b> <input type="checkbox" id="myCheck">
    <br>
    
    <div id="qqq">
    <h3>This is the Typing Content , i want to make it in every three second it should be retype from start if the check button is cheked / enabled</h3> 
    <h2>Any HTML Content</h2>
    
    </div>
        <script type="text/javascript" src="https://fiddle.jshell.net/js/babel/babel.js"></script>
            <script src="https://fiddle.jshell.net/js/stringify.js" charset="utf-8"></script>

I created 2 variable i and myInterval , after i controlled checkbox check in your type eventlistener. If there is check your function working 1 time and after i creating setinterval for myInterval. I using i vraible to use different function everytime , so firstly erase function working after animate function working and they're being working in loop for every 3 seconds. There is clear interval in setinterval so you can stop setinterval with unable check. Differen codes are:

let i = true;
let myInterval; 

type.addEventListener('click', () => { 
    if(document.getElementById('myCheck').checked==true){
        foo.animateOut();
        myInterval=setInterval(() => {
            if(document.getElementById('myCheck').checked!=true){
                clearInterval(myInterval);
            }
                if(i==true){
                    i=false;
                    foo.animateIn();
                }else{
                    i=true;
                    foo.animateOut();
                }

            }, 3000);

        }else{
            clearInterval(myInterval);
            foo.animateIn();
        }
    }, false);
erase.addEventListener('click', () => foo.animateOut(() => { 
    clearInterval(myInterval);
    console.log('animation out done'); }), false);

EDIT i add some thing now when you change browser tab if animate working its starting paragraph begining and if erase working it begining to remove paragraph's end , this is last version:

       class TextAnimation {

            constructor(text, opt_domElement) {
                this.text = text;
                this.curChar = 0;
                this.inTimeout = 0;
                this.outTimeout = 0;
                this.domElement = opt_domElement || this.createDomElement();
            }

            createDomElement() {
                const elem = document.createElement('p');
                elem.className = 'blink';
                elem.innerHTML = ' ';
                document.body.appendChild(elem);
                return elem;
            }

            getDelay(char, isLastChar = false) {
                let delay = this.delay;
                switch (char) {
                    case ' ':
                        delay = 3;
                        break;
                    case ',':
                        delay = 3;
                        break;
                    case '.':
                    case '!':
                    case '?':
                        delay = 3;
                        break
                    default:
                        delay = 15;


                }

                if (isLastChar) {
                    delay = 0;
                }
                return delay;
            }


            type(callback) {
                this.curChar++;
                this.domElement.innerHTML = this.text.substr(0, this.curChar);
                if (this.curChar < this.text.length + 1) {
                    const prevChar = this.text.substr(this.curChar - 1, 1);
                    this.inTimeout = setTimeout(() => this.type(callback), this.getDelay(prevChar, this.curChar === this.text.length));
                } else {
                    this.curChar = this.text.length;
                    callback();
                    return;
                }
                // console.log('type', this.curChar);
            }

            erase(callback) {
                this.curChar--;
                this.domElement.innerHTML = this.text.substr(0, this.curChar);
                if (this.curChar >= 0) {
                    this.outTimeout = setTimeout(() => this.erase(callback), 10);
                } else {
                    this.curChar = 0;
                    callback();
                    return;
                }
                // console.log('erase', this.curChar);
            }

            stopCurrentAnimation() {
                clearTimeout(this.inTimeout);
                clearTimeout(this.outTimeout);
            }

            animateIn(callback = () => { }) {
                this.stopCurrentAnimation();
                this.type(callback);
            }

            animateOut(callback = () => { }) {
                this.stopCurrentAnimation();
                this.erase(callback);
            }

        }

        console.clear();



        const type = document.getElementById('type');
        const erase = document.getElementById('erase');

        const question = document.getElementById('qqq').innerHTML;
        const foo = new TextAnimation(question);
        foo.animateIn(() => { console.log('autoplay done'); });

        let i = true;
        let myInterval;

        type.addEventListener('click', () => {
            if (document.getElementById('myCheck').checked == true) {
                foo.animateOut();
                myInterval = setInterval(() => {
                    if (document.getElementById('myCheck').checked != true) {
                        clearInterval(myInterval);
                    }
                    if (i == true) {
                        i = false;
                        foo.animateIn();
                    } else {
                        i = true;
                        foo.animateOut();
                    }

                }, 3000);

            } else {
                clearInterval(myInterval);
                foo.animateIn();
            }
        }, false);
        erase.addEventListener('click', () => foo.animateOut(() => {
            clearInterval(myInterval);
            console.log('animation out done');
        }), false);




        document.addEventListener("visibilitychange", begining , false);
        function begining() {
            clearInterval(myInterval);


            if(i==false){
                foo.curChar=0;
                foo.animateIn();
            }else if(i==true){
            foo.curChar=question.length;
            foo.animateOut();
        }

        myInterval = setInterval(() => {
                    if (document.getElementById('myCheck').checked != true) {
                        clearInterval(myInterval);
                    }
                    if (i == true) {
                        i = false;
                        foo.animateIn();
                    } else {
                        i = true;
                        foo.animateOut();
                    }

                }, 3000)
        
        }
      html,
        body {
            width: 100%;
            height: 100%;
            padding: 20px;
            margin: 0;
        }

        body {
            background-color: #000;
        }

        p {
            display: inline-block;
            font-family: monospace;
            font-size: 11px;
            line-height: 11px;
            min-height: 11px;
            color: #fff;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            margin: 0;
        }

        #qqq {
            display: none
        }


        .blink:after {
            content: '';
            position: absolute;
            top: 0;
            right: -10px;
            width: 5px;
            height: 100%;
            background-color: #fff;
            animation: blinker 0.8s linear infinite;
        }

        @keyframes blinker {
            50% {
                opacity: 0;
            }
        }
    <button id="type">
        type
    </button>
    <button id="erase">
        erase
    </button> <b style="color: yellow;">Checkbox:</b> <input type="checkbox" id="myCheck">
    <br>

    <div id="qqq">
        <h3>This is the Typing Content , i want to make it in every three second it should be retype from start if the
            check button is cheked / enabled</h3>
        <h2>Any HTML Content</h2>

    </div>
    <script type="text/javascript" src="https://fiddle.jshell.net/js/babel/babel.js"></script>
    <script src="https://fiddle.jshell.net/js/stringify.js" charset="utf-8"></script>
  • You do too much Hard work, First of all Thank You So Much for that, But one issue is there that is when we switch to other tab of chrome, and come back to this our text animation tab, then its should be start from start not to middle of last, according to the animation status of three second, Means simple, the typing animation should be start from first letter of my content when we swtich to our animation tab. – RR Suthar Feb 15 '21 at 12:56
  • Means the work you done is perfect, But plz add one more condition, based on document.addEventListener("visibilitychange", () => { var isVisible = document.visibilityState === "visible"; that complete my aim that is to start typing animation from the first letter of my content and the so on, when we swtich to our animation tab. By the way Love You :) – RR Suthar Feb 15 '21 at 12:56
  • i can understanding plz , make it restart from begening when my chrome tab become active document.addEventListener("visibilitychange", () => { var isVisible = document.visibilityState === "visible"; https://stackoverflow.com/questions/62773388/js-class-remove-not-working-properly-dev-tools-problem https://codepen.io/blex41/pen/GRoxMWd – RR Suthar Feb 15 '21 at 13:18
  • You are welcome and sorry my english still not well so i can't quite understand sometimes. I edited my answer i hope this is your wanted. – Reşit Abdullah Yavuzkol Feb 15 '21 at 14:01