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

mason-sprite

v0.1.8

Published

Lightweight sprite sheet animation for React, Vue, and Svelte

Readme

mason-sprite

npm version License: MIT

Latest release: v0.1.8

Lightweight sprite sheet animation for React, Vue, and Svelte.

Drop in a uniform-grid PNG or WebP sheet, set rows, cols, and fps — CSS or Canvas rendering with no timeline editor. Framework components are exported as MasonSprite to avoid clashing with other Sprite components.

Docs & demo: mason-sprite.com

When to use

  • Loop only → animated WebP <img> (simpler, no JS)
  • play / pause / segments / frame control → mason-sprite

Preview

| Sprite sheet (2 × 5) | Rendered | | :---: | :---: | | | |

Install

npm install mason-sprite

| Framework | Peer dependencies | | --- | --- | | React | react, react-dom | | Vue 3 | vue | | Svelte | svelte |

Usage

React

import { useRef } from 'react';
import { MasonSprite, type MasonSpriteHandle } from 'mason-sprite/react';

const ref = useRef<MasonSpriteHandle>(null);

<MasonSprite
  ref={ref}
  src="/sprites/cat-run.webp"
  rows={2}
  cols={5}
  fps={10}
  loop
  width="8rem"
  height="8rem"
/>

// ref.current?.playAnimation('walk');

Vue

<script setup>
import { MasonSprite } from 'mason-sprite/vue';
</script>

<template>
  <MasonSprite
    src="/sprites/cat-run.webp"
    :rows="2"
    :cols="5"
    :fps="10"
    loop
    width="8rem"
    height="8rem"
  />
</template>

Svelte

<script>
  import { MasonSprite } from 'mason-sprite/svelte';
</script>

<MasonSprite
  src="/sprites/cat-run.webp"
  rows={2}
  cols={5}
  fps={10}
  loop
  width="8rem"
  height="8rem"
/>

Vanilla JS

import { SpriteAnimator } from 'mason-sprite';

const animator = new SpriteAnimator({
  src: '/sprites/cat-run.webp',
  rows: 2,
  cols: 5,
  fps: 10,
  loop: true,
  width: '8rem',
  height: '8rem',
});

animator.attach(document.getElementById('sprite')!);

// Play a frame range
animator.playSegment({ start: 0, end: 4 });

// Or use a named clip map
const walk = new SpriteAnimator({
  src: '/sprites/hero.webp',
  rows: 4,
  cols: 5,
  animations: {
    idle: { start: 0, end: 3 },
    walk: { start: 5, end: 9 },
  },
});
walk.attach(document.getElementById('hero')!);
walk.playAnimation('walk');

// Reverse playback
animator.updateOptions({ reverse: true });

Rendering

mason-sprite supports two renderers. The default CSS renderer is optimized for compositor-friendly updates; use canvas when you need pixel-level control or off-screen export.

| Renderer | How it works | Best for | | --- | --- | --- | | css (default) | A viewport (overflow: hidden) clips a full-sheet <img>; each frame updates only transform: translate3d(...) | Most UI sprites — GPU-friendly, no repaint per frame | | canvas | drawImage onto <canvas> | Custom drawing, filters, or CORS-controlled bitmap access |

CSS renderer (transform + overflow)

Instead of shifting background-position every frame, the CSS renderer:

  1. Sizes the container to one frame (width × height)
  2. Places the full sprite sheet inside as an <img>
  3. Moves the sheet with translate3d to reveal the active frame

Only transform changes between frames, which keeps work on the compositor and avoids repainting the background layer.

<MasonSprite
  src="/sprites/cat-run.webp"
  rows={2}
  cols={5}
  renderer="css" // default
/>

Reverse playback

Set reverse to play frames from last → first. On a full sheet, playback starts at the final frame; with playSegment / playAnimation, it starts at the clip's end frame.

<MasonSprite
  src="/sprites/cat-run.webp"
  rows={2}
  cols={5}
  reverse
  loop={false}
/>

// Or toggle at runtime
ref.current?.stop();
animator.updateOptions({ reverse: true });
animator.play();

Controls

Available on SpriteAnimator and via ref / defineExpose / Svelte exports on <MasonSprite>.

| Method | Description | | --- | --- | | play() | Start or resume playback | | pause() | Pause playback | | stop() | Pause and reset to the clip start (or frame 0) | | goToFrame(n) | Jump to a frame index | | playSegment({ start, end, loop? }) | Play a frame range | | playAnimation(name) | Play a clip from animations |

React hook: useMasonSprite() returns the same controls plus ref and state.

Props

Shared by <MasonSprite> (React / Vue / Svelte) and SpriteAnimator.

| Prop | Type | Default | Description | | --- | --- | --- | --- | | src | string | — | Sprite sheet image URL (PNG, WebP, etc.) | | rows | number | — | Number of rows in the sheet | | cols | number | — | Number of columns in the sheet | | fps | number | 12 | Frames per second | | loop | boolean | true | Loop the animation | | reverse | boolean | false | Play frames in reverse (last → first) | | animations | Record<string, SpriteAnimationClip> | — | Named clips ({ start, end, loop? }) | | width | number \| string | 128 | Display width — px number or CSS length (rem, %, vw, …) | | height | number \| string | 128 | Display height — px number or CSS length | | autoPlay | boolean | true | Start playing on attach | | renderer | 'css' \| 'canvas' | 'css' | Rendering mode | | crossOrigin | '' \| 'anonymous' \| 'use-credentials' | CSS: unset; Canvas: 'anonymous' | crossOrigin for the sprite sheet image | | onLoad | () => void | — | Called when the image loads and the first frame is rendered | | onError | (error: Event) => void | — | Called when the image fails to load | | onComplete | () => void | — | Called when a non-looping animation finishes | | onFrameChange | (frame: number) => void | — | Called on each frame change |

Framework-specific props:

| Framework | Extra props | | --- | --- | | React | className, style | | Vue | class | | Svelte | class |

Canvas renderer & CORS

The canvas renderer draws the sprite sheet to a <canvas> via drawImage, which requires the image to be CORS-enabled when the sheet is loaded from another origin. By default, crossOrigin is set to 'anonymous' only when renderer is 'canvas'.

The CSS renderer places the sheet in an <img> inside an overflow: hidden viewport and shifts it with transform. It does not set crossOrigin on that image by default, so same-origin sheets without CORS headers still work.

Override explicitly when needed:

new SpriteAnimator({
  src: '/sprites/hero.png',
  rows: 4,
  cols: 5,
  renderer: 'canvas',
  crossOrigin: 'anonymous', // or '' to omit
});

Exports

| Import path | Contents | | --- | --- | | mason-sprite | SpriteAnimator, types, utilities | | mason-sprite/react | MasonSprite, useMasonSprite | | mason-sprite/vue | MasonSprite | | mason-sprite/svelte | MasonSprite |

Migration

| v0.1.5 | v0.1.6+ | | --- | --- | | Sprite | MasonSprite | | useSprite | useMasonSprite | | SpriteProps / SpriteHandle | MasonSpriteProps / MasonSpriteHandle |

Changelog

v0.1.8

No breaking API changes.

  • Fix autoPlay race when the sprite sheet is not cached: playback now starts after the image loads, from frame 0.
  • Do not advance frames or fire onFrameChange / onComplete before the image is loaded.
  • src changes pause playback, ignore stale loads, and reset to frame 0.
  • crossOrigin is optional; default is unset for CSS and 'anonymous' for canvas.
  • CSS renderer uses transform + overflow + <img> instead of background-position for better compositor performance.
  • Fix reverse playback to start from the last frame (or clip end); toggling reverse resets to the correct start frame.
  • React useMasonSprite keeps onComplete, onFrameChange, onLoad, and onError callbacks up to date.
  • Add optional onLoad and onError callbacks on SpriteAnimationOptions.

License

MIT