Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/qodesmith/typer

A JavaScript typing library with sexy syntax and diddly dependencies.
https://github.com/qodesmith/typer

typer typing typing-simulation

Last synced: 10 days ago
JSON representation

A JavaScript typing library with sexy syntax and diddly dependencies.

Awesome Lists containing this project

README

        

```
______
/\__ _\ __
\/_/\ \/ __ __ _____ __ _ __ /\_\ ____
\ \ \ /\ \/\ \ /\ '__`\ /'__`\/\`'__\ \/\ \ /',__\
\ \ \\ \ \_\ \\ \ \L\ \/\ __/\ \ \/ __ \ \ \ /\__, `\
\ \_\\/`____ \\ \ ,__/\ \____\\ \_\/\_\ _\ \ \\/\____/
\/_/ `/___/> \\ \ \/ \/____/ \/_/\/_//\ \_\ \\/___/
/\___/ \ \_\ \ \____/
\/__/ \/_/ By: The Qodesmith \/___/
```

# [Typer.js](http://aaroncordova.xyz/typer) ยท [![npm version](https://badge.fury.io/js/typer-js.svg)](https://badge.fury.io/js/typer-js)

Typer.js is an easy to use, choc-full-of-options, robust automated typing library. There are a number of [methods](#methods) with various options for you to impress your friends, have a parade thrown in your name, and officially obtain "that guy" status ("that gal" for the ladies).

Typer.js has **no library dependencies** so just slap it on your page and go. We still love you, [jQuery](https://cdnjs.com/libraries/jquery/). And the minified file is only 4k gzipped!

In short... Typer.js can type regular characters, [unicode](http://dev.w3.org/html5/html-author/charref) [characters](http://unicode-table.com/en/), whole words, half words, HTML elements, erase stuff, go fast, go slow, make new lines, fire events, listen to events, run functions, and make julienne fries in minutes.

#### Quick Links - API Methods

- [Cursor](#cursor)
- [Line](#line)
- [Back](#back)
- [Continue](#continue)
- [Pause](#pause)
- [Emit](#emit)
- [Listen](#listen)
- [Empty](#empty)
- [Run](#run)
- [End](#end)
- [Kill](#kill)
- [Halt](#halt)
- [Resume](#resume)
- [Repeat](#repeat)
- [Kill Switch](#kill-switch) (non-api feature)

## Installation

#### Manually

Simply include `typer.css` in the ``...

```html

...


```

and include `typer.min.js` just above your closing `` tag...

```html

...


```

#### Via NPM

From the CLI run:
`npm install typer-js`

In your project `require` this library:
`const typer = require('typer-js')`

Use fancy `import` for inclusion:
`import typer from 'typer-js'`

Files & locations:

| File | Location | Description |
| ------------ | -------------------------- | ----------------------------------- |
| typer.min.js | node_modules/typer-js/ | minified main file (4k gzipped!) |
| typer.css | node_modules/typer-js/ | stylesheet necessary for the cursor |
| typer.less | node_modules/typer-js/less | less: use it for your own builds |

## Usage

```javascript
typer(target, speed)
```

The Typer function itself takes two arguments:

1. `target` - two possibilities:
- `string` - a valid CSS selector, such as `'.some-class'`, `'#some-id'`, or `'.a-class .in-a-class'`, for Typer to grab (with `document.querySelector`) and type in.
- `element` - a single DOM element, such as `document.body` or `document.querySelector('div')`.
2. `speed` - (optional) two possibilities:
- `number` - a number (milliseconds) representing how fast each character should be typed out.
- `object` - an object specifying the speed. When you want to "humanize" the speed, supply numbers for `min` and `max` properties. This will indicate to Typer that you want to "humanize" the speed for _all_ lines (per-line speeds, if provided, override this speed).

_\* Note: Typer will default to a speed of 70 if nothing is provided._

Now you can begin calling Typer's various [methods](#methods) via simple & sexy dot-notation...

## Simple Code Examples

#### Type a single line:

```javascript
// Type in the body element.
typer('body').line('Typer.js is awesome!')

// Same example with a DOM element and humanized speed.
typer(document.body, {min: 20, max: 350}).line(
'Humanizing the speed will look more, uh, human.',
)

// Providing a DOM element and speed.
const element = document.querySelector('#some-id')
typer(element, 100).line('Using a DOM element as the 1st argument works!')
```

#### Type a single line, correct mispelling with back:

```javascript
typer('.some-class').line('This function roolz.').back(5).continue('ules!')
```

#### Type a list of frameworks with the help of pause & back:

```javascript
typer('#some-id')
.line('Backbone')
.pause(1000)
.back('all')
.continue('Angular')
.pause(1000)
.back('all')
.continue('React!!')
```

#### Multi-line typing:

```javascript
const element = document.querySelector('.my-element')
typer(element).line('How cool is this?').line('So very cool.').line('Agreed!')
```

#### Repeat automatically:

```javascript
// Repeat something forever.
typer('.some-class')
.line('I love JavaScript.')
.pause(1000)
.back('all')
.repeat(Infinity)
```

---

# Methods

## CURSOR

The `.cursor` method takes a single argument: `false` _or_ `{an: object}`. You can specify the 3 options below within the object. `.cursor` _can be omitted altogether_ which will result in the default styles mentioned below. Default options need not be given as they will take effect unless otherwise specified.

### No cursor

```javascript
.cursor(false)
```

### Options

#### block

```javascript
.cursor({ block: true })
```

- `false` - (default) The cursor will be a standard vertical line.
- `true` - The cursor will be a block, inspired from older style terminals.

#### blink

```javascript
.cursor({ blink: 'hard' });
```

- `'soft'` - (default) Smooth blinking animation.
- `'hard'` - Binary (on / off) blinking animation.

#### color

```javascript
// Examples.
.cursor({ color: 'red' })
.cursor({ color: '#ff0000' })
.cursor({ color: 'rgb(255,0,0)' })
.cursor({ color: 'rgba(255,0,0,0.7)' })
```

- You can specify any css color you want via any method (i.e. name, rgb, hsla, etc.).
- As a default, Typer will grab the color attribute of the parent element and use that for the cursor color to match the text with the cursor.

#### _all options at once_

```javascript
.cursor({ block: true, blink: 'hard', color: 'red' })
```

---

## LINE

```javascript
// Examples.
.line() // Creates a blank line.
.line('Typer.js is visual awesomeness!')
.line('Typer.js is visual awesomeness!', 100)
.line(['Type. ', 'Whole. ', 'Words.'], 200)
.line('Typer can "humanize" the speed with min & max values.', {
min: 30,
max: 350,
element: 'p',
html: false
})
.line('Typer.js is visual awesomeness!', {
speed: 150,
element: 'span'
})
.line({ // Grab content from a hidden div & type it. #SEO!!!
container: '.hidden-content',
element: 'span',
totalTime: 3500 // Take 3.5 seconds to type it all out.
})
.line('MISSION ACCOMPLISHED', { // Military typing!
military: {
chars: 5,
speed: 50
}
})
```

The `.line` method is at the heart of Typer. As the name suggests, it types out a single line.
You can feed it a `'single string'`, an `['array', 'of', 'strings']`, or an [options object](#options-1) containing at least a `container` property. `.line` defaults to parsing HTML, so you must explicitly tell it _not_ to within the [options object](#options-1).

### Arguments

1. Argument 1 - three possibilities:
- `string` - The message you want typed out, character by character (normal typing).
- `array` - The message you want typed out, _item by item_ (word by word).
- `object` - An [options object](#options-1). If this is the _only_ argument passed to `.line`, it _must_ have the `container` property.
2. Argument 2 (optional) - two possibilities:
- `number` - A speed in milliseconds. Each line can optionally have its own typing speed. If no speed is given, it defaults to the number given to the `typer` function itself or Typer's internal default of 70.
- `object` - An [options object](#options-1). This object will be ignored if you provided an options object to argument 1. This object takes all the same options as the object used in argument 1 minus the `container` property. Don't provide `container` with this object, it will be ignored.

_\* TIP: If you supply no arguments, you will create a blank line._

### Options

_\* NOTE: If you're passing in an options object to argument 1, argument 2 will be ignored._

#### container

_Values_:

- `string` - any valid CSS selector
- `element` - a DOM element

```javascript
.line({ container: '.hidden-content' }) // Valid CSS selector.
.line({ container: document.body }) // Valid DOM element.
```

**SEO** in the house! You can tell `.line` to use the contents of a pre-existing element on the page. So, for instance, you can hide a paragraph of text with CSS (`display: none`) which will still be indexed by search engines and use it to feed Typer! Amazing.

#### min / max

_Value_: `number`

```javascript
.line({ container: '.hidden-content', min: 30, max: 350 })
.line('Humanize the speed of typing stuff', { min: 30, max: 350 })
```

We all want our robot overlord's to be more, uh, human. And so Typer delivers! Typer has the ability to _"humanize"_ the typing speed. Provide `min` and `max` properties which define a _range_ within which Typer will pick a random number for each character's typing speed. Voila. It's like a real person typing. Only not.

#### speed

_Value_: `number`

```javascript
.line({ container: '.hidden-content', speed: 50 })
.line('The speed property is usually specified with other options.', { speed: 100, html: false })
.line("Just use a plain number if you're only specififying speed.", 100)
.line('However, this will work just fine.', { speed: 100 })
```

When using an options object as the 2nd argument to `.line`, the speed property is usually accompanied by other options, such as `html` or `element`.

_NOTE: the_ `speed` _option will take priority over_ `min` _and_ `max` _if they are all provided. For example, if your options look like_ `{speed: 50, min: 10, max: 300}`_, Typer will only process_ `speed`.

#### totalTime

_Value_: `number`

```javascript
.line({ container: '.hidden-content', totalTime: 4500 })
.line('This should take 3 seconds to type', { totalTime: 3000 })
.line('This line is much longer but will also only take 3 seconds to type.', { totalTime: 3000 })
.line(['Works', ' with', ' arrays.'], { totalTime: 2000 })
.line('And HTML too!', { totalTime: 1500 })
```

Instead of specifying how _fast_ you want things to type, with the `totalTime` option you specifiy how _long_ you want it to take.

_NOTE: the_ `totalTime` _option will take priority over all other speed-related options. For example, if your options look like_ `{speed: 50, min: 10, max: 300, totalTime: 3000}`_, all the other speed-related options will be ignored and Typer will only process_ `totalTime`.

#### military

_Values_:

- `number`
- `object`

```javascript
.line('A number representing speed of change', { military: 50 })
.line('Speed of change and # of characters:', { military: { speed: 50, chars: 5 } })
.line(["Doesn't", ' work', ' with', ' arrays.'], { military: 25 }) // No effect.
```

Atteeeeeeeen-tion! I geek out about this one. What the military option does is for each character that needs to be typed it first scrolls through typing out a handful of random characters in its place.

Passing a number represents the _scrolling speed_ - how fast the random characters will change.

Passing an object let's you specify the scrolling `speed` and how many random characters (`chars`) will be scrolled before typing the actual content you supplied and moving on.

_NOTE: When supplying an array to be typed, the_ `military` _option will be ignored._

_NOTE: Because it takes time to scroll through random characters before something is typed out, timing options such as_ `totalTime` _will be affected._

#### html

_Values_:

- `true` (default)
- `false`

```javascript
.line({ container: '.hidden-content', html: false })
.line('Do not process this as html.', { html: false })
.line("No need to tell Typer to process html since that's the default.")
```

Typer can handle html, unicode, and all sorts of craziness ([see below](#html--unicode)). It defaults to processing contents as html so you need to explicitly tell it _not_ to.

### HTML / Unicode

_Go nuts_. You can include `

`'s, ``'s, elements with styles (i.e. `I'm red!`), ``'s, ``'s, etc. You can also include [HTML void elements](http://www.w3.org/TR/html-markup/syntax.html#syntax-elements) (self-closing tags) such as `
`, ``, and `
`. If you're really feeling brave, start including ``'s and ``'s!.

Valid [unicode](http://dev.w3.org/html5/html-author/charref) [characters](http://unicode-table.com/en/) begin with `&` and end with `;`. Some examples:

| Character | Code | Character | Code | Character | Code |
| :-------: | ----------- | :-------: | --------- | :-------: | --------- |
| ๐Ÿ‡ | `๐Ÿ‡` | โ†’ | `โ†’` | โ˜Ž | `โ˜Ž` |
| ยฎ | `ยฎ` | โ†˜ | `โ†˜` | โ™ช | `โ™ช` |
| ยผ | `ยผ` | โ†“ | `โ†“` | โ™ฅ | `โ™ฅ` |

#### HTML / Unicode examples:

The following code...

```javascript
typer('body')
.line('How will I look?')
.line('How will I look?', {html: false})
.line('Cookies & milk')
.line('Cookies & milk')
.line('Cookies & milk', {html: false})
.line('The โœˆ flies โ†‘ in the sky.')
```

will result in this output on the screen:

> _How will I look?_
> <em>How will I look?</em>

> Cookies & milk

> Cookies & milk

> Cookies &amp; milk

> The โœˆ flies โ†‘ in the sky.

---

## BACK

:back: Erase stuff!

### Arguments

The 1st argument is mandatory and has three options. The 2nd argument is optional and has a different effect based upon the 1st argument (O.o). These arguments are order sensative. Now, stop arguing and `.continue` reading...

1. Argument 1 - three possibilities:
- `number` - number of characters to be erased / how many times you want to "hit" the "backspace button".
- Positive #'s erase that many characters.
- Negative #'s _keep_ that many characters. For example, a value of -2 will erase _all but two_ characters.
- `string` (`'all'`) - this will "backspace" the entire line, character by character, without you having to give a number. Useful for longer lines and those wanting to avoid math.
- `string` (`'empty'`) - this will empty the entire line at once. The 2nd argument can have effects on this behavior (see below).
2. Argument 2 - one type, two possibilities:
- `number` (when arg 1 is **not** `'empty'`) - the speed at which the backspace will perform. If no number is specified, it will default to the user-supplied Typer speed or Typer's internal default of 70.
- `number` (when arg 1 _*is*_ `'empty'`) - if _positive_ (i.e. `15`), the number of character to erase _at once_, else if _negative_ (i.e. `-15`), the number of characters to _leave remaining_.

Some examples to dispel confusion (hopefully):

```javascript
.back(10) // Erase 10 characters at the default speed.
.back(-10) // Erase *all-but* 10 characters at the default speed.
.back(10, 5) // Erase 10 characters at a speed of 5 milliseconds per character.
.back(-10, 5) // Erase *all-but* 10 characters at a speed of 5 milliseconds per character.
.back('all') // Erase all characters at the default speed.
.back('all', 5) // Erase all characters at a speed of 5 milliseconds per character.
.back('empty') // Erase all the character *at once*.
.back('empty', 15) // Erase 15 characters *at once*.
.back('empty', -15) // Erase *all-but* 15 characters *at once*.
```

---

## CONTINUE

```javascript
// Examples.
.continue("I'm on the same line!")
.continue(' Same line, emphasis on sloooow.', 500)
.continue(" Now let's ignore html", { html: false })
.continue(' Type more like a human would!', { min: 30, max: 350 })
.continue([' Whole sentence at once.'])
.continue({
container: '.hidden-div', // This property is mandatory when using a single options object.
speed: 500,
html: false
})
.continue({
container: document.querySelector('.hidden-div'),
min: 30,
max: 350
})
```

The `.continue` method works just like `.line` in that it accepts all the same arguments & options but it _continues_ typing on the same line, whereas `.line` creates new lines. In conjunction with the `.pause` and `.line` methods, you can create eloborate schemes. You can feed `.continue` the same content (HTML, unicode, etc.) as `.line`.

### Arguments

Same as those for `.line` ([above](#line)).

_\* NOTE: unlike_ `.line`_, calling_ `.continue` _with no arguments will produce no effect._

_\* NOTE:_ `.continue` _will ignore the_ `container` _property._

---

## PAUSE

```javascript
// Examples.
.pause() // 500ms default time.
.pause(1000)
```

The `.pause` method takes a single argument, a number in milliseconds. Typer will wait that long before proceeding to the next called method. If no argument is provided, the default is 500.

---

## EMIT

```javascript
// Examples.
let element = document
.querySelector('#some-id')
.emit('boom') // Fires off the body.
.emit('boom', '.some-class') // Fires off a specific element (string selector).
.emit('boom', element) // Fires off a specific element (element provided).
```

Emits an event on a specified DOM element or defaults to the `body`. This is useful for setting up complex automation scenarios where multiple Typer functions (or other functions on your page) are time-dependant on eachother. DOM event explosions causing mass automated awesomeness. What could be better?

### Arguments

1. Argument 1: `string` - the event name; Omitting a 2nd argument will default to the event firing from the `body`.
2. Argument 2: `string` _or_ `element` - (optional) target a DOM element that the event will be fired from. Provide a string CSS selector or an HTML element.

---

## LISTEN

```javascript
// Examples.
let element = document
.querySelector('#some-id')
.listen('boom') // Listens on the body.
.listen('boom', '.some-class') // Listens on a specific element (string selector).
.listen('boom', element) // Listens on a specific element (element provided).
```

Typer has the ability (read: super-power) to listen for events as well. The `.listen` method will stop Typer in its tracks until the specified event is fired. Once fired, Typer will proceed from where it last left off. More automation goodness.

### Arguments

1. Argument 1: `string` - the event name; Omitting a 2nd argument will default to the listener listening from the `body`.
2. Argument 2: `string` _or_ `element` - (optional) target a DOM element that the listener will be placed on. Provide a string CSS selector or an HTML element.

_\* NOTE: Typer uses **one-time event** listeners. Once the event is fired the listener is triggered and then immediately removed. See how tidy we are?_

---

## EMPTY

```javascript
.empty()
```

The `.empty` method empties the parent element (specified as the 1st argument to `typer`) and _starts over with a fresh line_.

The parent element could contain multiple lines and HTML elements, the likes of which cannot be undone with a simple `.back('all')`. Also, `.empty` will instantaneously empty the parent element as opposed to backspacing it into oblivion. Have fun.

---

## RUN

```javascript
.run(function() { /* do stuff */ })
.run(function(el) { /* do stuff with access to parent element */ })
```

To round out our automation tools, the `.run` method will do just that: run a function before proceeding with any additional methods. Feed it a function and let it fly.

#### Access to the parent element

The `.run` method exposes the parent element that Typer is currently typing in through an argument in the function you pass to `.run` (`el` in the example above).

---

## END

```javascript
.end()
.end(true) // Fire off the `typerFinished` event.
.end(true, function() { /* do stuff */ }) // Event fired.
.end(function() { /* do stuff */ })
.end(function() { /* do stuff */ }, true) // Event fired.
.end(function(el) { /* do stuff with access to parent element */ }, true) // Event fired.
```

### Arguments

The `.end` method always removes the cursor, can optionally execute a callback function, and optionally fire off the `typerFinished` event. The event can be used to trigger other things in your application. These arguments are completely optional. The order of the arguments is not strict but the callback will always be executed before firing the `typerFinished` event.

- callback - A function you want executed when `typer` is finished.
- `true` - Indicates you want the `typerFinished` event fired once Typer is finished. This event is fired from the ``. The default (if left unspecified) is false.

#### Access to the parent element

As with the `.run` method above, `.end` exposes the parent element that Typer is currently typing in through an argument in the function you pass to to `.end`.

---

## KILL

```javascript
.kill()
```

The `.kill` method will terminate an individual Typer instance. It takes no arguments. This feature is useful when you want to ensure a Typer instance is no longer running, perhaps in a single-page application when the view changes. You can also use the Kill Switch (below) to terminate _all_ instances at once. This method also cleans up any and all event listeners that the instance produced.

_\* NOTE: Chaining any other methods after_ `.kill` _will produce no effect._

```javascript
const t1 = typer('#some-id-1').line('This is the first instance of Typer.')
const t2 = typer('#some-id-2').line(
'This is the second instance of Typer that we want to kill.',
)

// after some time...

t2.kill() // <-- This instance will stop while 't1' remains unaffected.
```

---

## HALT

```javascript
.halt()
```

This method is like having a remote control that can stop Typer whenever you want. It's different than the pause method because `pause` needs to be declared at runtime. Once you've started the Typer process you can't "pause" it again with the `pause` method at will - it would have to have already been declared.

With `halt`, you can stop Typer at will. The only catch is that if Typer is in a "pause" or "listen" state, `halt` will do nothing. Other than that, feel free to have at it!

```javascript
const t1 = typer('.some-class').line(aReallyLongString)

// Wait 1 second and halt Typer in the middle of typing:
setTimeout(() => t1.halt(), 1000)
```

---

## RESUME

```javascript
.resume()
```

This method - wait for it - _resumes_ Typer from where `halt` left off! It's easy peezy. Here's an example:

```javascript
const t1 = typer('.some-class').line(aReallyLongString)

// Wait 1 second and halt Typer in the middle of typing:
setTimeout(() => t1.halt(), 1000)

// Go get a sandwich, stretch, come back...
setTimeout(() => t1.resume(), 5000)
```

Here's an example of using a button to toggle between halting & resuming Typer:

```javascript
let halted = false
document.querySelector('.my-button').addEventListener('click', () => {
halted ? t1.resume() : t1.halt()
halted = !halted
})
```

---

## REPEAT

```javascript
.repeat(Infinity) // Repeat forever.
.repeat(3) // Repeat 3 times.
.repeat(3, true) // Repeat 3 times, clearing the contents each time.
```

There are times where you want to continuously repeat a set of instructions. While you could [achieve this](https://github.com/qodesmith/typer/issues/16#issuecomment-343333356) on your own, Typer includes the `.repeat` method to allow you to do this programmatically.

_\* NOTE: Repeat is really meant to be called last. If you call it more than once in your setup, each repeat will start repeating instructions from the last repeat or the beginning - whichever comes first._

### Arguments

1. Argument 1: `number` - how many times you want to repeat the prior commands.
2. Argument 2: `boolean` - (optional) indicates wether to clear the contents before repeating or not.

---

END OF METHODS

---

## Kill Switch

Typer's kill switch feature let's you annihilate _all_ Typer instances no matter _what_ they're currently doing. This is particularly useful for single-page applications to prevent Typer from continuing in the background even after a view has been removed from the DOM. The kill switch will also remove any current listener any Typer instance has on a DOM element.

_\* NOTE: If you have multiple instances of Typer running on the page, this will **kill them all**._

### How to use:

This is an example function you can use to flip the kill switch:

```javascript
function killTyper() {
const kill = new Event('killTyper')
document.body.dispatchEvent(kill)
}
```

To activate Typer's kill switch, a `killTyper` event must be dispatched from the ``. That's it.

---

## Showcase

Have you done something cool with Typer.js? Have an awesome site / use-case you'd like to share? [Contact me!](mailto:[email protected]) I'd love to show off your awesomeness with a link here.

- [http://aaroncordova.xyz/this-isnt-real](http://aaroncordova.xyz/this-isnt-real) - awesome 404 pages (random page each time)
- [http://mihaeltomic.com/](http://mihaeltomic.com/) - cool introduction

---

## Feature Requests

> I think I thought of everything, but I thought wrong once, even though I think I'm right.

O.o
If you think of a feature you feel would be an awesome addition to Typer, raise an [issue](https://github.com/qodesmith/typer/issues) or create a [pull request](https://github.com/qodesmith/typer/pulls). I'm all ears.