Skip to content

Typing Animation

Jakub T. Jankiewicz edited this page Apr 27, 2024 · 23 revisions

Typing was first added in version 2.24.0 but in current form, with all updates and fixes, you should use at least 2.28.0 to use all the features. In version 2.29.0 animation will be added to exec function.

Higher-level API

Prompt animation

term.set_prompt("name: ", { typing: true, delay: 200 });

echo animation

term.echo("Hello", { typing: true, delay: 200 });

enter animation

term.enter("Hello", { typing: true, delay: 200 });

Enter method is missing feature added in version 2.31.0. It's like exec but without executing the command, it just echo the prompt and given command.

exec animation

Since version 2.29.0 exec also supports animation, it works similar to enter using low-level API but here it will also invoke the command, after the animation finishes.

term.exec("Hello", { typing: true, delay: 200 });

All those functions return a Promise (jQuery Deferred) that resolves when the animation ends.

If you return that promise from the interpreter it will automatically pause the terminal while the animation is running.

Sequence of animations

If you need to execute a sequence of animations, you need to wait until the previous animation finishes before you can call the next animation. The return value of a function that runs animation is always a promise. So you can use async/await to create a sequence of animations:

async function animation() {
    await term.echo("Hello", { typing: true, delay: 200 });
    await term.echo("jQuery", { typing: true, delay: 200 });
    await term.echo("Terminal", { typing: true, delay: 200 });
}

If you want to execute the sequence of animations when using echo without a newline (newline is set to false), you need to hide the prompt otherwise the prompt will show up in a split second between animations. it will not be visible long enough but it will look odd (the cursor will jump forward and backward between animations). The odd behavior will be visible if you add longer delay between animations.

To fix this issue you can use this code:

async function animation() {
    const prompt = term.get_prompt();
    term.set_prompt('');
    await term.echo("Hello, ", { typing: true, delay: 10, newline: false });
    await term.echo("jQuery ", { typing: true, delay: 500, newline: false });
    await term.echo("Terminal", { typing: true, delay: 500 });
    term.set_prompt(prompt);
}

The reason why prompt need to be set to an empty string is because typing animation use prompt internally to add typing effect before the cursor.

See this CodePen Demo

This works because internally the animation is using a prompt to show the text during animation, and when the animation finishes the full text is echoed and the prompt is restored to the original value.

Low-level API

Low-level API is a single method terminal::typing:

term.typing(<type>, <delay>, <string>, options);
  • terminal::typing returns a promise that resolves when the animation ends.
  • there is only one option, finalize
  • type is one of the strings: 'prompt', 'echo' or 'enter'.
  • prompt animation as the name suggests is an animation of the prompt and at the end, the prompt is set to the given string.
  • echo animation as the name suggests, animate the string that is echo into the terminal.
  • enter animation is an animation of entering the command and pressing enter, it uses the current prompt as a prefix after the animation starts.

Disabling interactive mode

This will be improved and it's tracked by issue #683

By default, if you run single animation, it will disable the key down event (that is a base for all interactivity). But if you do a longer animation sequence (e.g. using delay in between animations) you should disable key events yourself. The easiest way is to use this pattern:

let animation;
const term = $('body').terminal(function(command) {
}, {
    keydown: () => animation ? false : undefined
});

When the animation starts, set:

animation = true;

when the animation ends, set:

animation = false

This will ensure that you will not end up with a broken state when animation and interactive mode (like echo or prompt that is used internally for animations) overlap on each other.

To see examples of typing animation see demos: