alexmacarthur / typeit

The most versatile JavaScript typewriter effect library on the planet.
https://typeitjs.com
GNU General Public License v3.0
3.08k stars 200 forks source link

Force queue to finish all at once? #359

Open meetar opened 1 year ago

meetar commented 1 year ago

I'm using typeit-react 2.6.4 in React 18.2.0. I'm trying to add a keyhandler to make a TypeIt instance finish its queue all at once. I've tried:

instance.options({speed: 0}).go()

...but that doesn't seem to have any effect. I'd assume this should work, as the docs says .options() is to "update options on the fly" but I must be misinterpreting them.

I've tried

instance.reset();
instance.options({speed: 0}).go()

...but this just restarts the original queue at the original speed.

I've tried

instance.flush();
instance.options({speed: 0}).go()

...but that doesn't seem to clear the existing queue, or change the speed. It erases what's been typed, but then continues from where it left off, with new timeouts added interleaved with the existing ones, so the result is a jumble of letters. Here's an example result from executing the above code immediately after "jump" in "The quick brown fox jumps over the lazy dog.":

"s overT hthee qluaizcyk dborgo.wn fox jump"

Is this a bug or a feature request?

For the record instance.empty().go() doesn't seem to have any effect on a currently executing queue either.

meetar commented 1 year ago

For posterity, here's a little backstory, and my workaround. I'm making a rpg-style text interface which allows the user to hit enter to fast-forward to the end of the typing animation.

I have a "text" state, and a "complete" state value to false. I made a function called getTypeIt() which takes a typing speed and some text, and returns a <TypeIt /> component keyed by the speed. It looks something like this:

<TypeIt key={speed}
  options={{
    speed: speed,
    afterComplete: () => {
      setComplete(true)
    }
  }}>{text}</TypeIt>

When the fast-forward interaction occurs, I set a "complete" state value. Then I call my function like so:

{complete ? getTypeIt(0, text) : getTypeIt(speed, text)}

The last part is to set up a useEffect() to watch for text changes and reset the "complete" value:

useEffect(() => {
  setComplete(false);
}, [text])