cm-typing-effect
Version:
Typing animation effect for web elements with customizable caret and timing.
24 lines (23 loc) • 2.64 kB
JavaScript
var E=e=>typeof e=="string"?document.getElementById(e):e,x=e=>{if(!e)throw new Error("Invalid Target Element! (cm-typing-effect)");if(!e.textContent)throw new Error("Target Element Without Text! (cm-typing-effect)");if(e.children.length!=0)throw new Error("Target Element Has Internal Tags! (cm-typing-effect)")},u=(e,t,i)=>{let n=document.createElement("span");n.className="wrapper-cm-typing-effect";let r=document.createElement("span");r.className="text-cm-typing-effect",r.textContent=t;let s=document.createElement("span");return s.className="caret-cm-typing-effect",s.textContent=i,n.appendChild(r),n.appendChild(s),e.innerHTML="",e.appendChild(n),{wrapperElement:n,textElement:r,caretElement:s}},T=(e,t,i)=>{let n="cm-typing-effect-styles";if(!document.getElementById(n)){let r=document.createElement("style");r.id=n,r.textContent=`
@keyframes blinking-cm-typing-effect {
50% { color: transparent; }
}
@keyframes typing-cm-typing-effect {
from { width: 0; }
}
.wrapper-cm-typing-effect {
display: flex;
width: fit-content;
position: relative;
}
.text-cm-typing-effect {
display: flex;
height: 100%;
overflow: hidden;
white-space: nowrap;
width: 0;
}
.caret-cm-typing-effect {
user-select: none;
}
`,document.head.appendChild(r)}e&&h(t,i)},h=(e,t)=>{e.style.width=t+"ch"},w=(e,t,i,n)=>{if(h(e,t),n){e.style.animation=`typing-cm-typing-effect ${i}ms steps(${t}) reverse forwards`;return}e.style.animation=`typing-cm-typing-effect ${i}ms steps(${t})`},l=(e,t)=>{let i=(1/t).toFixed(2);e.style.animation=`blinking-cm-typing-effect ${i}s step-end infinite`},b=e=>e.style.removeProperty("animation"),v=(e,t)=>{e.style.position="absolute",e.style.left=`calc(100% + ${t}px)`},C=e=>{e.style.visibility==="hidden"&&e.style.removeProperty("visibility")},a=e=>new Promise(t=>{setTimeout(()=>t(!0),e)});var P=(e,{startDelay:t=0,endDelay:i=0,realisticTyping:n=!1,keepCaretBlinkingAfterEnd:r=!1,animationTime:s=1e3,caret:c="|",caretBlinkingSpeed:p=1.6,caretTakeSpace:H=!1,caretOffset:L=0,eraseMode:f=!1}={})=>new Promise(async M=>{let o=E(e);x(o);let y=!!o.querySelector(".caret-cm-typing-effect")?o.textContent.trim().slice(0,-c.length):o.textContent.trim(),g=y.length,{caretElement:m,textElement:d}=u(o,y,c);H||v(m,L),T(f,d,g),C(o),l(m,p),await a(t),n&&b(m),w(d,g,s,f),await a(s),l(m,p),await a(i),r||m.remove(),M()});export{P as startTyping};