npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

theater-ts

v1.1.1

Published

Typing animation mimicking human behavior.

Readme

TheaterTS

Typing animation mimicking human behavior.

This repository is a rework in Typescript of the library TheaterJS done by Zhouzi

If you're not particularly interested in managing multiple actors and the several features TheaterJS has to offer (e.g mistakes, variable speed, callbacks, html support, and so on), have a look at this fiddle. It's a minimalist version that supports play/stop, it has a lot of comments so you understand what's going on under the hood. It might well be enough for you usage :)

Installation

With npm:

npm install theater-ts

Example

<div id="vader"></div>
<div id="luke"></div>
const theaterOptions = new TheaterConfig(true, true, new SpeedConfig(80, 80), new SpeedConfig(450, 450));
this.theaterTS = new TheaterTS(theaterOptions);
this.theaterTS.on('type:start, erase:start', () => {
  // add a class to actor's dom element when he starts typing/erasing
  const actor = this.theaterTS.getCurrentActor();
  actor.element.classList.add('is-typing');
})
.on('type:end, erase:end', () => {
  // and then remove it when he's done
  const actor = this.theaterTS.getCurrentActor();
  actor.element.classList.remove('is-typing');
});
this.theaterTS
  .addActor('vader', new ActorConfig(0.5, 0.5))
this.theater.addActor("vader").addActor("luke");

this.theater
.addScene("vader:Luke...", 400)
.addScene("luke:What?", 400)
.addScene("vader:I am", 200, ".", 200, ".", 200, ". ")
.addScene("Your father!")
.addScene(theater.replay());

Documentation

To get started, you'll first need to create a new TheaterTS object by providing some options.

| Param | Default | Description | | ------- | ---------------------------------------- | ---------------------- | | options | {autoplay, erase, minSpeed, maxSpeed, locale} | Options (see below). |

Breakdown of the available options:

| Option | Default | Description | | -------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | autoplay | true | If true, automatically play the scenario (when calling addScene). | | erase | true | Whether you want an erase animation or not (in this case, it will just erase the whole sentence) | | minSpeed | { erase: 80, type: 80 } | Minimum delay between each typed characters (the lower, the faster). | | maxSpeed | { erase: 450, type: 450 } | The maximum delay between each typed characters (the greater, the slower). | | locale | detect | Determine which keyboard to use when typing random characters (mistakes). Note: "detect" is an option to detect the user's locale and use if it's supported. |

TheaterTS objects have two public (read only) properties:

  • theater.options: object's options.
  • theater.status: object's status (whether "playing", "stopping" or "ready").

addActor

Add an actor to the casting.

Example

var theater = TheaterTS();

theater
  .addActor("vader")
  .addActor("luke", 0.8, ".luke-selector")
  .addActor("yoda", { accuracy: 0.4, speed: 0.6 }, function(displayValue) {
    console.log("%s said yoda", displayValue);
  });

Usage

theater.addActor(<name>, <options>, <callback>)

| Param | Default | Description | | -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------ | | name: string | | Name used to identify the actor. | | options: ActorConfig | accuracy: 0.8, speed: 0.8, displayCaret: false | Actor's options, use it like this: new ActorConfig(0.5, 0.6, true) | | callback: (string) => void | (see below) | A function to call when actor's display value changes. |

Actors have three options:

  • accuracy (number between 0 and 0.8): used to determine how often an actor should make mistakes.
  • speed (number between 0 and 1): used to determine how fast the actor types.
  • displayCaret (boolean): whether you want to display a caret or not. Please be sure not to wrap any text with a block balise (like <div>)

I didn't create any css file to import for the caret as it directly depends on the font family, but you can base yours with this example:

.caret {
  color: inherit;
  font-size: 1.4em;
  vertical-align: text-bottom;
  line-height: 0.9;
  margin-left: -0.2em;
}

.blinking-caret {
  animation: blink 1s steps(2, start) infinite;
}

@keyframes blink {
  to {
    visibility: hidden;
  }
}

Note: the delay between each typed character varies to "mimick human behavior".

An actor callback is a function that is called when its display value is set. The default callbalck is :

(newValue) => {
  this.element.innerHTML = newValue;
}

You can safely ignore this argument if you gave the target element an id with the name of the actor, i.e:

theater.addActor("vader");

In this situation, TheaterJS will look for an element that matches the selector #vader. Also note that the actor will have an additional $element property referring to the DOM element when using a selector string.

getCurrentActor

Return the actor that is currently playing.

Example

const theater = TheaterTS();

theater
  .addActor("vader")
  .addScene("vader:Luke...")
  .addScene((done) => {
    var vader = theater.getCurrentActor();
    vader.$element.classList.add("dying");
    done();
  });

Usage

this.theater.getCurrentActor();

addScene

Add scenes to the scenario and play it if options.autoplay is true.

Example

const theater = TheaterTS();

theater
  .addActor("vader")
  .addScene("vader:Luke... ", "Listen to me!", 500)
  .addScene(theater.replay());

Usage

theater.addScene(<scene>)

A scene can be of 5 different types:

theater
  .addScene("vader:Luke... ") // 1
  .addScene(800) // 2
  .addScene("I am your father!") // 3
  .addScene(-7) // 4
  .addScene("mother!")
  .addScene(function(done) {
    // do stuff
    done();
  }); // 5
  1. .addScene('vader:Luke... ') erase actor's current display value, then type the new value.
  2. .addScene(800) make a break of 800 milliseconds before playing the next scene.
  3. .addScene('I am your father!') append value to the current actor's display value.
  4. .addScene(-7) erase 7 characters.
  5. .addScene(fn) call fn which receives a done callback as first argument (calling done() plays the next scene in the scenario).

Note that addScene actually accepts an infinite number of arguments so you could just do:

theater
  .addScene("vader:Luke... ", 800, "I am your father!")
  .addScene(-7, "mother!")
  .addScene(fn);

getCurrentSpeech

Return the speech that is currently playing.

Example

const theater = TheaterTS();

theater
  .addActor("vader")
  .addScene("vader:Luke...")
  .on("type:start", () => {
    console.log(theater.getCurrentSpeech()); // outputs 'Luke...'
  });

Usage

this.theater.getCurrentSpeech();

play

Play the scenario.

Example

var theater = TheaterTS({ autoplay: false });

theater.addActor("vader").addScene("vader:Luke...");

document.querySelector("button").addEventListener(
  "click",
  function() {
    theater.play();
  },
  false
);

Usage

theater.play();

replay

Replay the scenario from scratch (can be used as a callback to create a loop).

Example

var theater = TheaterTS();

theater
  .addActor("vader")
  .addScene("vader:Luke...")
  .addScene(theater.replay());

Usage

theater.replay();

stop

Stop the scenario after the current playing scene ends.

Example

var theater = TheaterTS();

theater.addActor("vader").addScene("vader:Luke... ", "I am your father...");

document.querySelector("button").addEventListener(
  "click",
  function() {
    theater.stop();
  },
  false
);

Usage

theater.stop();

urgentStop

Stop the scenario during a scene

continueCurrentScene

To call after an urgent stop to go back to where we were in the scene

on

Add a callback to execute when an event is emitted (e.g when a scene starts/ends).

Example

var theater = TheaterTS();

theater
  .on("type:start, erase:start", function() {
    var actor = theater.getCurrentActor();
    actor.$element.classList.add("blinking-caret");
  })
  .on("type:end, erase:end", function() {
    var actor = theater.getCurrentActor();
    actor.$element.classList.remove("blinking-caret");
  });

theater.addActor("vader").addScene("vader:Luke...");

Usage

theater.on(eventName: string, callback: () => void)

| Param | Default | Description | | --------- | ------- | ---------------------------------------------- | | eventName | | Event's name to listen to. | | callback | | Function to call when the event got published. |

The callback function receives the event's name as first argument.

A couple of things to note:

  • Listen to all event by using the shortcut: theater.on('*', callback).
  • An event is emitted when a sequence starts (sequence:start) and ends (sequence:end), e.g theater.addScene('vader:Luke.', 'vader:I am your father.') is one sequence.
  • An event is emitted when the scenario starts and ends, respectively scenario:start and scenario:end.
  • The scenario is stoppable within :end event listeners. It means that calling theater.stop() within a callback that listen for the :end of a scene will stop the scenario. This is useful for asynchronous callbacks (e.g animations).

Tag

TheaterTS, so has TheaterJS, modifies the innerHTMl of the actor and handles HTML tag by surrounding the sentences with its corresponding tag on each letter it enters.

Example

var theater = TheaterTS();

theater.addActor("vader")
    .addScene("vader:Luke...")
    .addScene(`<div class="dark-voice">I'm your father</div>`);

Note: Don't forget to use Encapsulation.none on Angular, so the class can be taken into account

Note: If you want to use some : in your sentence, you'll need to add \\ before each of them

Localized Keyboards

When making a mistake, an actor's gonna type a random character near the one he intended to. Those characters are taken from a "mapped" keyboard that you can configure on TheaterTS' instantiation: TheaterTS(new TheaterConfig(true, true, new SpeedConfig(80, 80), new SpeedConfig(450, 450), 'en')).

Available keyboard: 'en', 'fr', 'da', 'de', 'pl', 'pt', 'ru', 'es', 'el'