Sheldon  Grant

Sheldon Grant

1644914400

Ora: Elegant Terminal Spinner

ora

Elegant terminal spinner



 

Install

$ npm install ora

Usage

import ora from 'ora';

const spinner = ora('Loading unicorns').start();

setTimeout(() => {
	spinner.color = 'yellow';
	spinner.text = 'Loading rainbows';
}, 1000);

API

ora(text)

ora(options)

If a string is provided, it is treated as a shortcut for options.text.

options

Type: object

text

Type: string

Text to display after the spinner.

prefixText

Type: string | () => string

Text or a function that returns text to display before the spinner. No prefix text will be displayed if set to an empty string.

spinner

Type: string | object
Default: 'dots'

Name of one of the provided spinners. See example.js in this repo if you want to test out different spinners. On Windows, it will always use the line spinner as the Windows command-line doesn't have proper Unicode support.

Or an object like:

{
	interval: 80, // Optional
	frames: ['-', '+', '-']
}

color

Type: string
Default: 'cyan'
Values: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray'

Color of the spinner.

hideCursor

Type: boolean
Default: true

Set to false to stop Ora from hiding the cursor.

indent

Type: number
Default: 0

Indent the spinner with the given number of spaces.

interval

Type: number
Default: Provided by the spinner or 100

Interval between each frame.

Spinners provide their own recommended interval, so you don't really need to specify this.

stream

Type: stream.Writable
Default: process.stderr

Stream to write the output.

You could for example set this to process.stdout instead.

isEnabled

Type: boolean

Force enable/disable the spinner. If not specified, the spinner will be enabled if the stream is being run inside a TTY context (not spawned or piped) and/or not in a CI environment.

Note that {isEnabled: false} doesn't mean it won't output anything. It just means it won't output the spinner, colors, and other ansi escape codes. It will still log text.

isSilent

Type: boolean
Default: false

Disable the spinner and all log text. All output is suppressed and isEnabled will be considered false.

discardStdin

Type: boolean
Default: true

Discard stdin input (except Ctrl+C) while running if it's TTY. This prevents the spinner from twitching on input, outputting broken lines on Enter key presses, and prevents buffering of input while the spinner is running.

This has no effect on Windows as there's no good way to implement discarding stdin properly there.

Instance

.start(text?)

Start the spinner. Returns the instance. Set the current text if text is provided.

.stop()

Stop and clear the spinner. Returns the instance.

.succeed(text?)

Stop the spinner, change it to a green โœ” and persist the current text, or text if provided. Returns the instance. See the GIF below.

.fail(text?)

Stop the spinner, change it to a red โœ– and persist the current text, or text if provided. Returns the instance. See the GIF below.

.warn(text?)

Stop the spinner, change it to a yellow โš  and persist the current text, or text if provided. Returns the instance.

.info(text?)

Stop the spinner, change it to a blue โ„น and persist the current text, or text if provided. Returns the instance.

.isSpinning

A boolean of whether the instance is currently spinning.

.stopAndPersist(options?)

Stop the spinner and change the symbol or text. Returns the instance. See the GIF below.

options

Type: object

symbol

Type: string
Default: ' '

Symbol to replace the spinner with.

text

Type: string
Default: Current 'text'

Text to be persisted after the symbol

prefixText

Type: string
Default: Current prefixText

Text to be persisted before the symbol. No prefix text will be displayed if set to an empty string.

.clear()

Clear the spinner. Returns the instance.

.render()

Manually render a new frame. Returns the instance.

.frame()

Get a new frame.

.text

Change the text after the spinner.

.prefixText

Change the text before the spinner. No prefix text will be displayed if set to an empty string.

.color

Change the spinner color.

.spinner

Change the spinner.

.indent

Change the spinner indent.

oraPromise(action, text)

oraPromise(action, options)

Starts a spinner for a promise or promise-returning function. The spinner is stopped with .succeed() if the promise fulfills or with .fail() if it rejects. Returns the promise.

import {oraPromise} from 'ora';

await oraPromise(somePromise);

action

Type: Promise | ((spinner: ora.Ora) => Promise)

options

Type: object

All of the options plus the following:

successText

Type: string | ((result: T) => string) | undefined

The new text of the spinner when the promise is resolved.

Keeps the existing text if undefined.

failText

Type: string | ((error: Error) => string) | undefined

The new text of the spinner when the promise is rejected.

Keeps the existing text if undefined.

FAQ

How do I change the color of the text?

Use Chalk:

import ora from 'ora';
import chalk from 'chalk';

const spinner = ora(`Loading ${chalk.red('unicorns')}`).start();

Why does the spinner freeze?

JavaScript is single-threaded, so synchronous operations blocks the thread, including the spinner animation. Prefer asynchronous operations whenever possible.

Related

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/ora 
License: MIT License

#node 

What is GEEK

Buddha Community

Ora: Elegant Terminal Spinner
Arvel  Parker

Arvel Parker

1591627260

How to Use the Screen Command in Linux

Screen is a terminal program in Linux which allows us to use a virtual (VT100 terminal) as full-screen window manager which multiplexes an open physical terminal between multiple processes, which are typically, interactive shells. It allows us to access multiple terminal sessions within a single terminal or a remote terminal session. It is most useful when addressing multiple Linux shell commands on the command line, as well as separating commands from the shell that started the commands.

Screen also allows a user to initiate a command from one terminal, disconnect from that terminal, and then reconnect from a different location to that same terminal, while using a different terminal without having to restart the command. This simply lets a user better control multiple and separate command windows.

Screen also lets multiple remote computers connect to the same screen session at once. This allows multiple users to connect to the same screen session allowing a second user to follow along with another administrator working on a server.

#tutorials #attach #cli #command line #detach #key bindings #logging #multiplex #multiuser #multiuser mode #remote access #remote management #remote session #remote terminal #screen #screen logging #screen session #screenlog #screens #scrollback #shell #terminal #terminal session #terminal window #tty #vt100

Lawrence  Lesch

Lawrence Lesch

1660909980

Terminal-snazzy: Elegant Terminal Theme with Bright Colors

terminal-snazzy

Elegant Terminal theme with bright colors

Install

  • Right-click Snazzy.terminal and choose Save Link Asโ€ฆ.
  • Double-click the downloaded file.
  • Go to Preferencesโ€ฆ, then Profiles, click Snazzy, and then click the Default button.

Tip

To get the exact same look as in the screenshot, you need to use the Pure prompt, Menlo font, and the zsh-syntax-highlighting plugin to have commands highlighted.

Related

Download Details:

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/terminal-snazzy 
License: MIT license

#javascript #macos #terminal 

Spinner: Go Package to Easily Provide A Terminal Spinner with Options

Spinner

spinner is a simple package to add a spinner / progress indicator to any terminal application. Examples can be found below as well as full examples in the examples directory.

For more detail about the library and its features, reference your local godoc once installed.

Contributions welcome!

Installation

go get github.com/briandowns/spinner

Available Character Sets

90 Character Sets. Some examples below:

(Numbered by their slice index)

indexcharacter setsample gif
0โ†โ†–โ†‘โ†—โ†’โ†˜โ†“โ†™Sample Gif
1โ–โ–ƒโ–„โ–…โ–†โ–‡โ–ˆโ–‡โ–†โ–…โ–„โ–ƒโ–Sample Gif
2โ––โ–˜โ–โ–—Sample Gif
3โ”คโ”˜โ”ดโ””โ”œโ”Œโ”ฌโ”Sample Gif
4โ—ขโ—ฃโ—คโ—ฅSample Gif
5โ—ฐโ—ณโ—ฒโ—ฑSample Gif
6โ—ดโ—ทโ—ถโ—ตSample Gif
7โ—โ—“โ—‘โ—’Sample Gif
8.oO@*Sample Gif
9|/-\Sample Gif
10โ—กโ—กโŠ™โŠ™โ— โ— Sample Gif
11โฃพโฃฝโฃปโขฟโกฟโฃŸโฃฏโฃทSample Gif
12>))'> >))'> >))'> >))'> >))'> <'((< <'((< <'((<Sample Gif
13โ โ ‚โ „โก€โข€โ  โ โ ˆSample Gif
14โ ‹โ ™โ นโ ธโ ผโ ดโ ฆโ งโ ‡โ Sample Gif
15abcdefghijklmnopqrstuvwxyzSample Gif
16โ–‰โ–Šโ–‹โ–Œโ–โ–Žโ–โ–Žโ–โ–Œโ–‹โ–Šโ–‰Sample Gif
17โ– โ–กโ–ชโ–ซSample Gif
18โ†โ†‘โ†’โ†“Sample Gif
19โ•ซโ•ชSample Gif
20โ‡โ‡–โ‡‘โ‡—โ‡’โ‡˜โ‡“โ‡™Sample Gif
21โ โ โ ‰โ ™โ šโ ’โ ‚โ ‚โ ’โ ฒโ ดโ คโ „โ „โ คโ  โ  โ คโ ฆโ –โ ’โ โ โ ’โ “โ ‹โ ‰โ ˆโ ˆSample Gif
22โ ˆโ ‰โ ‹โ “โ ’โ โ โ ’โ –โ ฆโ คโ  โ  โ คโ ฆโ –โ ’โ โ โ ’โ “โ ‹โ ‰โ ˆSample Gif
23โ โ ‰โ ™โ šโ ’โ ‚โ ‚โ ’โ ฒโ ดโ คโ „โ „โ คโ ดโ ฒโ ’โ ‚โ ‚โ ’โ šโ ™โ ‰โ Sample Gif
24โ ‹โ ™โ šโ ’โ ‚โ ‚โ ’โ ฒโ ดโ ฆโ –โ ’โ โ โ ’โ “โ ‹Sample Gif
25๏ฝฆ๏ฝง๏ฝจ๏ฝฉ๏ฝช๏ฝซ๏ฝฌ๏ฝญ๏ฝฎ๏ฝฏ๏ฝฑ๏ฝฒ๏ฝณ๏ฝด๏ฝต๏ฝถ๏ฝท๏ฝธ๏ฝน๏ฝบ๏ฝป๏ฝผ๏ฝฝ๏ฝพ๏ฝฟ๏พ€๏พ๏พ‚๏พƒ๏พ„๏พ…๏พ†๏พ‡๏พˆ๏พ‰๏พŠ๏พ‹๏พŒ๏พ๏พŽ๏พ๏พ๏พ‘๏พ’๏พ“๏พ”๏พ•๏พ–๏พ—๏พ˜๏พ™๏พš๏พ›๏พœ๏พSample Gif
26. .. ...Sample Gif
27โ–โ–‚โ–ƒโ–„โ–…โ–†โ–‡โ–ˆโ–‰โ–Šโ–‹โ–Œโ–โ–Žโ–โ–โ–Žโ–โ–Œโ–‹โ–Šโ–‰โ–ˆโ–‡โ–†โ–…โ–„โ–ƒโ–‚โ–Sample Gif
28.oOยฐOo.Sample Gif
29+xSample Gif
30v<^>Sample Gif
31>>---> >>---> >>---> >>---> >>---> <---<< <---<< <---<< <---<< <---<<Sample Gif
32| || ||| |||| ||||| |||||| ||||| |||| ||| || |Sample Gif
33[] [=] [==] [===] [====] [=====] [======] [=======] [========] [=========] [==========]Sample Gif
34(*---------) (-*--------) (--*-------) (---*------) (----*-----) (-----*----) (------*---) (-------*--) (--------*-) (---------*)Sample Gif
35โ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ โ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆSample Gif
36[ ] [=> ] [===> ] [=====> ] [======> ] [========> ] [==========> ] [============> ] [==============> ] [================> ] [==================> ] [===================>]Sample Gif
37๐Ÿ• ๐Ÿ•‘ ๐Ÿ•’ ๐Ÿ•“ ๐Ÿ•” ๐Ÿ•• ๐Ÿ•– ๐Ÿ•— ๐Ÿ•˜ ๐Ÿ•™ ๐Ÿ•š ๐Ÿ•›Sample Gif
38๐Ÿ• ๐Ÿ•œ ๐Ÿ•‘ ๐Ÿ• ๐Ÿ•’ ๐Ÿ•ž ๐Ÿ•“ ๐Ÿ•Ÿ ๐Ÿ•” ๐Ÿ•  ๐Ÿ•• ๐Ÿ•ก ๐Ÿ•– ๐Ÿ•ข ๐Ÿ•— ๐Ÿ•ฃ ๐Ÿ•˜ ๐Ÿ•ค ๐Ÿ•™ ๐Ÿ•ฅ ๐Ÿ•š ๐Ÿ•ฆ ๐Ÿ•› ๐Ÿ•งSample Gif
39๐ŸŒ ๐ŸŒŽ ๐ŸŒSample Gif
40โ—œ โ— โ—ž โ—ŸSample Gif
41โฌ’ โฌ” โฌ“ โฌ•Sample Gif
42โฌ– โฌ˜ โฌ— โฌ™Sample Gif
43[>>> >] []>>>> [] [] >>>> [] [] >>>> [] [] >>>> [] [] >>>>[] [>> >>]Sample Gif

Features

  • Start
  • Stop
  • Restart
  • Reverse direction
  • Update the spinner character set
  • Update the spinner speed
  • Prefix or append text
  • Change spinner color, background, and text attributes such as bold / italics
  • Get spinner status
  • Chain, pipe, redirect output
  • Output final string on spinner/indicator completion

Examples

package main

import (
	"github.com/briandowns/spinner"
	"time"
)

func main() {
	s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)  // Build our new spinner
	s.Start()                                                    // Start the spinner
	time.Sleep(4 * time.Second)                                  // Run for some time to simulate work
	s.Stop()
}

Update the character set and restart the spinner

s.UpdateCharSet(spinner.CharSets[1])  // Update spinner to use a different character set
s.Restart()                           // Restart the spinner
time.Sleep(4 * time.Second)
s.Stop()

Update spin speed and restart the spinner

s.UpdateSpeed(200 * time.Millisecond) // Update the speed the spinner spins at
s.Restart()
time.Sleep(4 * time.Second)
s.Stop()

Reverse the direction of the spinner

s.Reverse() // Reverse the direction the spinner is spinning
s.Restart()
time.Sleep(4 * time.Second)
s.Stop()

Provide your own spinner

(or send me an issue or pull request to add to the project)

someSet := []string{"+", "-"}
s := spinner.New(someSet, 100*time.Millisecond)

Prefix or append text to the spinner

s.Prefix = "prefixed text: " // Prefix text before the spinner
s.Suffix = "  :appended text" // Append text after the spinner

Set or change the color of the spinner. Default color is white. The spinner will need to be restarted to pick up the change.

s.Color("red") // Set the spinner color to red

You can specify both the background and foreground color, as well as additional attributes such as bold or underline.

s.Color("red", "bold") // Set the spinner color to a bold red

To set the background to black, the foreground to a bold red:

s.Color("bgBlack", "bold", "fgRed")

Below is the full color and attribute list:

// default colors
red
black
green
yellow
blue
magenta
cyan
white

// attributes
reset
bold
faint
italic
underline
blinkslow
blinkrapid
reversevideo
concealed
crossedout

// foreground text
fgBlack
fgRed
fgGreen
fgYellow
fgBlue
fgMagenta
fgCyan
fgWhite

// foreground Hi-Intensity text
fgHiBlack
fgHiRed
fgHiGreen
fgHiYellow
fgHiBlue
fgHiMagenta
fgHiCyan
fgHiWhite

// background text
bgBlack
bgRed
bgGreen
bgYellow
bgBlue
bgMagenta
bgCyan
bgWhite

// background Hi-Intensity text
bgHiBlack
bgHiRed
bgHiGreen
bgHiYellow
bgHiBlue
bgHiMagenta
bgHiCyan
bgHiWhite

Generate a sequence of numbers

setOfDigits := spinner.GenerateNumberSequence(25)    // Generate a 25 digit string of numbers
s := spinner.New(setOfDigits, 100*time.Millisecond)

Get spinner status

fmt.Println(s.Active())

Unix pipe and redirect

Feature suggested and write up by dekz

Setting the Spinner Writer to Stderr helps show progress to the user, with the enhancement to chain, pipe or redirect the output.

This is the preferred method of setting a Writer at this time.

s := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(os.Stderr))
s.Suffix = " Encrypting data..."
s.Start()
// Encrypt the data into ciphertext
fmt.Println(os.Stdout, ciphertext)
> myprog encrypt "Secret text" > encrypted.txt
โฃฏ Encrypting data...
> cat encrypted.txt
1243hjkbas23i9ah27sj39jghv237n2oa93hg83

Final String Output

Add additional output when the spinner/indicator has completed. The "final" output string can be multi-lined and will be written to wherever the io.Writer has been configured for.

s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.FinalMSG = "Complete!\nNew line!\nAnother one!\n"
s.Start()                 
time.Sleep(4 * time.Second)
s.Stop()                   

Output

Complete!
New line!
Another one!

Author: Briandowns
Source Code: https://github.com/briandowns/spinner 
License: Apache-2.0 License

#go #golang #cli #terminal 

Sheldon  Grant

Sheldon Grant

1644914400

Ora: Elegant Terminal Spinner

ora

Elegant terminal spinner



 

Install

$ npm install ora

Usage

import ora from 'ora';

const spinner = ora('Loading unicorns').start();

setTimeout(() => {
	spinner.color = 'yellow';
	spinner.text = 'Loading rainbows';
}, 1000);

API

ora(text)

ora(options)

If a string is provided, it is treated as a shortcut for options.text.

options

Type: object

text

Type: string

Text to display after the spinner.

prefixText

Type: string | () => string

Text or a function that returns text to display before the spinner. No prefix text will be displayed if set to an empty string.

spinner

Type: string | object
Default: 'dots'

Name of one of the provided spinners. See example.js in this repo if you want to test out different spinners. On Windows, it will always use the line spinner as the Windows command-line doesn't have proper Unicode support.

Or an object like:

{
	interval: 80, // Optional
	frames: ['-', '+', '-']
}

color

Type: string
Default: 'cyan'
Values: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray'

Color of the spinner.

hideCursor

Type: boolean
Default: true

Set to false to stop Ora from hiding the cursor.

indent

Type: number
Default: 0

Indent the spinner with the given number of spaces.

interval

Type: number
Default: Provided by the spinner or 100

Interval between each frame.

Spinners provide their own recommended interval, so you don't really need to specify this.

stream

Type: stream.Writable
Default: process.stderr

Stream to write the output.

You could for example set this to process.stdout instead.

isEnabled

Type: boolean

Force enable/disable the spinner. If not specified, the spinner will be enabled if the stream is being run inside a TTY context (not spawned or piped) and/or not in a CI environment.

Note that {isEnabled: false} doesn't mean it won't output anything. It just means it won't output the spinner, colors, and other ansi escape codes. It will still log text.

isSilent

Type: boolean
Default: false

Disable the spinner and all log text. All output is suppressed and isEnabled will be considered false.

discardStdin

Type: boolean
Default: true

Discard stdin input (except Ctrl+C) while running if it's TTY. This prevents the spinner from twitching on input, outputting broken lines on Enter key presses, and prevents buffering of input while the spinner is running.

This has no effect on Windows as there's no good way to implement discarding stdin properly there.

Instance

.start(text?)

Start the spinner. Returns the instance. Set the current text if text is provided.

.stop()

Stop and clear the spinner. Returns the instance.

.succeed(text?)

Stop the spinner, change it to a green โœ” and persist the current text, or text if provided. Returns the instance. See the GIF below.

.fail(text?)

Stop the spinner, change it to a red โœ– and persist the current text, or text if provided. Returns the instance. See the GIF below.

.warn(text?)

Stop the spinner, change it to a yellow โš  and persist the current text, or text if provided. Returns the instance.

.info(text?)

Stop the spinner, change it to a blue โ„น and persist the current text, or text if provided. Returns the instance.

.isSpinning

A boolean of whether the instance is currently spinning.

.stopAndPersist(options?)

Stop the spinner and change the symbol or text. Returns the instance. See the GIF below.

options

Type: object

symbol

Type: string
Default: ' '

Symbol to replace the spinner with.

text

Type: string
Default: Current 'text'

Text to be persisted after the symbol

prefixText

Type: string
Default: Current prefixText

Text to be persisted before the symbol. No prefix text will be displayed if set to an empty string.

.clear()

Clear the spinner. Returns the instance.

.render()

Manually render a new frame. Returns the instance.

.frame()

Get a new frame.

.text

Change the text after the spinner.

.prefixText

Change the text before the spinner. No prefix text will be displayed if set to an empty string.

.color

Change the spinner color.

.spinner

Change the spinner.

.indent

Change the spinner indent.

oraPromise(action, text)

oraPromise(action, options)

Starts a spinner for a promise or promise-returning function. The spinner is stopped with .succeed() if the promise fulfills or with .fail() if it rejects. Returns the promise.

import {oraPromise} from 'ora';

await oraPromise(somePromise);

action

Type: Promise | ((spinner: ora.Ora) => Promise)

options

Type: object

All of the options plus the following:

successText

Type: string | ((result: T) => string) | undefined

The new text of the spinner when the promise is resolved.

Keeps the existing text if undefined.

failText

Type: string | ((error: Error) => string) | undefined

The new text of the spinner when the promise is rejected.

Keeps the existing text if undefined.

FAQ

How do I change the color of the text?

Use Chalk:

import ora from 'ora';
import chalk from 'chalk';

const spinner = ora(`Loading ${chalk.red('unicorns')}`).start();

Why does the spinner freeze?

JavaScript is single-threaded, so synchronous operations blocks the thread, including the spinner animation. Prefer asynchronous operations whenever possible.

Related

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/ora 
License: MIT License

#node 

Rupert  Beatty

Rupert Beatty

1669886009

Getting Started with The Web Animation API

Getting Started With The JavaScript Web Animation API

Adding animations to web interfaces makes pages and apps feel more responsive and interactive. A side menu that smoothly slides out of view provides a much better user experience then a menu that just disappears when you close it.

So far creating web animations was done either via CSS transitions, CSS keyframes, or an external library such as Animate.css or Velocity. Thanks to a new native JavaScript API, we are now able to freely animate any HTML element without ever having to leave our .js file.

Creating Animations

To showcase the awesomeness of the new API, let's build a super simple example, once the old-fashioned CSS way, then with JavaScript Web Animations.

The editor below contains two HTML divs that when clicked on move to the right and then change their color. The square is animated via CSS code>@keyframes, and the circle via the Web Animations API.

<h4>Click on the shapes to animate them.</h4>

<p>CSS keyframes</p>
<div id="square"></div>

<p>JS Web Animation API</p>
<div id="circle"></div>
#square,
#circle {
    width: 100px;
    height: 100px;
    margin: 10px 10px 30px;
    background-color: #2196F3;
}

#circle {
    border-radius: 50%;
}

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}
var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});

The code>@keyframes animation should be familiar to most developers so let's look at that first.

The CSS Approach

Our CSS animation is defined in a code>@keyframes block that represents a timeline of all the transitions. Once we have our choreography defined, we can map it to a selector via the animation property and it's options.

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}

We want the animation to start on user interaction so we will also have to create an on-click event listener that adds a CSS class to the desired element:

var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});

Although it works pretty well, the CSS approach seems rather non-intuitive as we define what happens in the stylesheets, but actually start it in the JavaScript. We also have very limited control over the animation once it has been invoked. Both these problems can be solved by switching to the Web Animation API.

The JavaScript Approach

We can describe our JavaScript animation using almost the exact same transitions we used in the CSS example:

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];

Each object in the array represents a state of the animation. The states are evenly distributed in time (3 states - 0%, 50%, 100%) unless we change the timing using the offset option, as we've done with the middle state.

After we've defined our animation array, we can invoke it using the animate() method. It takes as a second argument an object with the same options as the CSS animation property, although with slightly different names (e.g. animation-fill-mode is fill, animation-iteration-count is iteration, etc).

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});

As you can see, the JavaScript approach is much more organized with the animation stored in a variable and the animate() method used for invoking it whenever we need to.

Controlling Animations

The Web Animation API also makes it possible to easily control the playback of an animation in a number of ways. The animate() method returns an Animation object which we can save in a variable and use to refer to that animation later on.

var animation = elem.animate(transitions, options);

The interface provides us with the following methods:

  • pause() - Freezes the animation in its current state.
  • play() - Resumes the animation or restarts it if it has finished.
  • reverse() - Plays the transitions backwards.
  • finish() - Goes to the end of the animation (or the beginning if reversed).
  • cancel() - Stops playback and returns to starting state.

Below is a tiny demo with a loading indicator that loops infinitely. We've setup buttons for the different events so that you can try them out:

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('pause').addEventListener('click', function() { 
  spinnerAnimation.pause();
});
document.getElementById('play').addEventListener('click', function() { 
  spinnerAnimation.play(); 
});
document.getElementById('reverse').addEventListener('click', function() { 
  spinnerAnimation.reverse(); 
});
document.getElementById('cancel').addEventListener('click', function() { 
  spinnerAnimation.cancel(); 
});
<div id="spinner"></div>

<p>Try controlling the animation:</p>
<button id="pause">Pause</button>
<button id="play">Play</button>
<button id="reverse">Reverse</button>
<button id="cancel">Cancel</button>
#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

Properties and Events Listeners

The Animation object returned from animate() holds several useful properties that give us access to options like the current time, the playback rate, and others. Although some are read-only, most of the properties can be used as setters and getters.

You can view the JS code in the editor below to get a sense of how they work. For the full list of properties visit MDN.

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('half').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 0.5; 
});
document.getElementById('normal').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 1; 
});
document.getElementById('double').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 2; 
});
document.getElementById('triple').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 3; 
});
<div id="spinner"></div>

<p>Set Playback Speed:</p>
<button id="half">0.5</button>
<button id="normal">Normal</button>
<button id="double">2</button>
<button id="triple">3</button>
#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

In addition to that, the Web Animation API provides us with two useful event handlers for when the animation has finished or has been canceled:

spinnerAnimation.addEventListener('finish', function() {
    // Animation has completed or .finish() has been called.
    doSomething();
});

spinnerAnimation.addEventListener('cancel', function() {
    // Animation has been canceled.    
    doSomething();
});

Support and Performance

Most of the Web Animation features are freely available in Chrome and Firefox, with Edge and Safari implementations in the working (caniuse). There is also a well maintained open-source polyfill which can be used while waiting for full browser coverage.

When it comes to performance, there shouldn't be any difference compared to regular CSS transitions, as browsers use the same engine for both. If you stick to animating only properties that don't cause redraws, such as transform and opacity, animations should keep a steady 60fps rate.

Conclusion

The Web Animation API gives developers an awesome new way to create and control web animations using nothing but pure JavaScript. For animations that are invoked on user interaction or other dynamic events, this is great news since the whole animation can be done in the controller code, without having to jump to a CSS file for the actual transitions.

This article covered most of the features of the new API, but if you want to learn more here are a couple of excellent resources we highly recommend:

Original article source at: https://tutorialzine.com/

#javascript #web #animation