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

@lordicon/web

v2.1.0

Published

Player for animated Lordicon icons: states, segments, colours and stroke on top of a small Lottie renderer.

Readme

Lordicon Web Player

Plays an animated Lordicon icon from JavaScript, in any element: its states, colours and stroke.

npm install @lordicon/web
import { Player } from '@lordicon/web';

const data = await (await fetch('/icons/lock.json')).json();
const player = new Player(container, data);

container.addEventListener('pointerenter', () => player.play());

data is the icon's Lottie JSON. The icon plays its default state, usually a hover.

States

An icon holds several animations, its states: in-reveal, hover-jump, morph-unlocked.

player.states; // [{ name: 'in-reveal', time: 0, duration: 120, ... }, ...]
player.play({ state: 'in-reveal' }); // load a state and play it from its start
player.state = 'hover-jump'; // or only load it
player.currentState; // { name: 'hover-jump', time: 160, ... }, for the helpers below
player.state = '*'; // the whole file

A morph goes to a second look and back. With a ratio in its marker (morph-select:0.5) the state is two animations in a row, the way there and the way back, so play one half at a time: play({ state }) would play both, and reverse would run both backwards. Without a ratio, the state is the way there, and the way back is the same frames played backwards:

import { splitSegment, stateSegment } from '@lordicon/web';

player.state = 'morph-select';
const morph = player.currentState;
const halves = splitSegment(morph); // null without a ratio

if (halves) player.play({ segment: on ? halves[0] : halves[1] });
else player.play({ segment: stateSegment(morph), reverse: !on });

Colours and stroke

player.colors.primary = 'red'; // any hex value or CSS colour name
delete player.colors.primary; // the icon's own again
player.colors = { secondary: '#08a88a' }; // replace them all; null resets
player.stroke = 'bold'; // 'light', 'regular', 'bold', or 1, 2, 3; null resets

To swap one of the icon's colours wherever it is used, whatever its name:

import { colorsByName } from '@lordicon/web';

player.colors = colorsByName(player.defaultColors, { '#121331': '#ffffff' });

State, colours and stroke can also be given to the constructor: new Player(container, data, { state: 'hover-jump', colors: { primary: 'red' }, stroke: 3 }).

Playback

player.pause();
player.stop(); // back to the first frame
player.seek('end'); // a frame, 'start' or 'end', and pause
player.progress = 0.5; // halfway
player.loop = true;
player.speed = 2;
player.direction = -1; // backwards

player.play({ from: 'start' }); // restart
player.play({ reverse: true }); // backwards, from the end
player.play({ segment: [130, 191] }); // some frames

play() returns a promise: true when the animation plays to its end, false when something cuts it short: another play() with options, stop(), a new state, destroy(). It never rejects.

if (await player.play({ state: 'in-reveal' })) player.play({ state: 'hover-jump' });

Events

player.addEventListener('complete', (event) => {
    const { segment, direction, state } = event.detail;
});

| Event | When | | ---------- | -------------------------------------------------------------------- | | ready | The animation exists. A listener added later still gets it. | | play | Playback started or resumed: playing turned true. | | pause | Playback stopped (paused, sought, finished, destroyed): false again. | | complete | The animation played to its end, or its start when backwards. | | loop | A round of a looping animation ended; complete does not fire then. | | frame | A frame was drawn. | | refresh | Colours or stroke changed. | | destroy | destroy() ran. |

play and pause come only when playing changes: a new state or play() with options while it plays, or a loop's next round, sends neither. At the end, pause comes before complete. Playback through renderer goes around them.

The player is an EventTarget: { once: true } and { signal } work.

Many icons on a page

A player holds an animation and a copy of the icon data. With many icons on a page, create a player when its icon comes into view and destroy it when the icon leaves:

const player = new Player(container, data, null, { autoInit: false });

player.init(); // when the icon is needed
player.destroy(); // when it is not
  • autoInit: false leaves rendering to init(). What is set before applies then.
  • destroy() empties the container. Keep one player per container: destroy the old one before creating the next.
  • init() and destroy() can run more than once; a destroyed player does nothing.
  • { copy: false } skips the copy of data when it was fetched for this player alone; the renderer then changes it.

API

new Player(container, data, properties?, options?), with properties { state, colors, stroke } and options { autoInit, copy }.

| Member | What it does | | ------------------------------------- | ----------------------------------------------------------------------- | | play(options?) | Plays. { state, segment, from: 'start', reverse }. | | pause() | Pauses where it is. | | stop() | Pauses on the first frame. | | seek(frame) | Shows a frame, 'start' or 'end', and pauses. | | init(), destroy() | Create and remove the animation. | | ready, readyPromise | Ready now; a promise of true when ready, false if destroyed first. | | playing | Whether it plays. | | state | The state's name. null sets the default one, '*' the whole file. | | currentState | The state as an object, null for the whole file. | | states | The icon's states. | | segment | The loaded frames, [start, end). null goes back to the state's. | | frame | The frame on screen. | | frameCount, frameRate, duration | Frames in the segment, frames per second, seconds at the current speed. | | progress | 0 to 1 through the segment. Setting it seeks. | | direction, speed, loop | How it plays: 1 or -1, 1 by default, false by default. | | colors, defaultColors | The colours by name; the icon's own. | | stroke | 1, 2 or 3; null when the icon has no stroke setting. | | properties | State, colours and stroke at once. What is left out resets. | | renderer, controls | The animation and its effect controls, for what the player lacks. |

Also exported, from @lordicon/utils-lottie: findState, defaultState, stateType, stateSegment, stateRatio, splitSegment, stateEndFrame, colorsByName, parseColors, parseStroke, resolveColor, strokeName, isIconData.

Details

Frames are absolute, as in the icon's markers: a state at frame 130 starts at 130, whatever is loaded. A state's segment is [tm, tm + dr + 1): its last keyframes sit on tm + dr, and that frame has to play for the state to reach its final pose. The last frame of a segment is segment[1] - 1.

play() without options resumes where the icon is, and starts over once the segment has finished. With options it starts a new playback, and the previous promise gets false.

The default state plays when none is given; null or an unknown name picks it too. An icon without one plays the whole file, from its first state to the end of its last. A file without markers has no states, and plays its own frames, ip to op.

Subclassing. Every playback goes through play(), a state change during play included, so overriding that one method wraps them all.

Before init(), state, speed, direction, loop, colours and stroke can be set; they apply when it runs. play() resolves false.

Upgrading

What changed from 1.x, and what to write instead: CHANGELOG.md.

Development

npm install
npm start          # the examples
npm test           # Vitest, on the real renderer in happy-dom
npm run check      # types, lint, formatting
npm run build

License

MIT