1.1.1 • Published 3 years ago

theater-ts v1.1.1

Weekly downloads
50
License
-
Repository
github
Last release
3 years ago

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.

ParamDefaultDescription
options{autoplay, erase, minSpeed, maxSpeed, locale}Options (see below).

Breakdown of the available options:

OptionDefaultDescription
autoplaytrueIf true, automatically play the scenario (when calling addScene).
erasetrueWhether 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).
localedetectDetermine 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>)
ParamDefaultDescription
name: stringName used to identify the actor.
options: ActorConfigaccuracy: 0.8, speed: 0.8, displayCaret: falseActor'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)
ParamDefaultDescription
eventNameEvent's name to listen to.
callbackFunction 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'

1.1.1

3 years ago

1.1.0

3 years ago

1.0.2

3 years ago

1.0.3

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago

0.0.1

3 years ago