Easy Typewriter effect/animation with Javascript

Published on 28 December 2020 1 minute read (60 words)

I've recently "ascended" into more than just a Web developer, so I felt like I needed to add a bit of sparkle to my home page with a nice typewriter animation showing all the things I can do. Now you can too.

Add a cool typewriter effect/animation to your design with this one simple snippet I've written for you:

typewriter.js

function Typewriter(el) {
   const instance = {
      el,
      eventLoop: [],

      wait: (time) => {
         instance.eventLoop.push(
            () => new Promise((resolve) => setTimeout(resolve, time))
         );

         return instance;
      },

      type: (text) => {
         instance.eventLoop.push(
            () =>
               new Promise((resolve) => {
                  let idx = 0;

                  const typeOut = (text) => {
                     window.requestAnimationFrame(() => {
                        if (idx < text.length) {
                           el.innerHTML += text.charAt(idx);
                           idx++;

                           setTimeout(() => typeOut(text), 125);
                        } else {
                           resolve();
                        }
                     });
                  };

                  typeOut(text);
               })
         );

         return instance;
      },

      clear: () => {
         instance.eventLoop.push(
            () =>
               new Promise((resolve) => {
                  const clearText = () => {
                     window.requestAnimationFrame(() => {
                        if (el.innerHTML !== "") {
                           el.innerHTML = el.innerHTML.substr(
                              0,
                              el.innerHTML.length - 1
                           );

                           setTimeout(clearText, 125);
                        } else {
                           resolve();
                        }
                     });
                  };

                  clearText();
               })
         );

         return instance;
      },

      run: (loop) => {
         let i = 0;

         const _run = () =>
            new Promise((resolve) => {
               if (i < instance.eventLoop.length) {
                  return instance.eventLoop[i]().then(() => {
                     i++;
                     return _run();
                  });
               }
               
               if (loop) {
                  instance.run(loop);  
               }
               
               resolve();
            });

         _run();
      }
   };

   return instance;
}

Demo and usage