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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@small-tech/spinners

v2.0.1

Published

Two indeterminate progress spinners, one with lines and the other with dots (available in animated SVG, animated PNG, JavaScript, and Svelte).

Downloads

40

Readme

Spinners

This package has two indeterminate progress spinners, one with lines:

…and the other with dots:

They are two of the spinners from Ionic Framework.

Why?

Because sometimes you just need a simple spinner without a 5-tonne framework attached.

Usage

Note on accessibility

When including a spinner in your site or app, the element that contains your spinner should be set as an ARIA live region and provide meaningful, app-specific feedback on its current state.

Learn more: “It’s alive!”: Apps That Feed Back Accessibly, More Accessible Skeletons

Just the SVGs

If you just want the SVGs, you can grab them below (right click and save):

Lines:

<svg stroke="currentColor" height="1em" viewBox="0 0 64 64"><g stroke-width="4" stroke-linecap="round"><line y1="12" y2="20" transform="translate(32,32) rotate(180)"><animate attributeName="stroke-opacity" dur="750ms" values="1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(210)"><animate attributeName="stroke-opacity" dur="750ms" values="0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(240)"><animate attributeName="stroke-opacity" dur="750ms" values=".1;0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(270)"><animate attributeName="stroke-opacity" dur="750ms" values=".15;.1;0;1;.85;.7;.65;.55;.45;.35;.25;.15" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(300)"><animate attributeName="stroke-opacity" dur="750ms" values=".25;.15;.1;0;1;.85;.7;.65;.55;.45;.35;.25" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(330)"><animate attributeName="stroke-opacity" dur="750ms" values=".35;.25;.15;.1;0;1;.85;.7;.65;.55;.45;.35" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(0)"><animate attributeName="stroke-opacity" dur="750ms" values=".45;.35;.25;.15;.1;0;1;.85;.7;.65;.55;.45" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(30)"><animate attributeName="stroke-opacity" dur="750ms" values=".55;.45;.35;.25;.15;.1;0;1;.85;.7;.65;.55" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(60)"><animate attributeName="stroke-opacity" dur="750ms" values=".65;.55;.45;.35;.25;.15;.1;0;1;.85;.7;.65" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(90)"><animate attributeName="stroke-opacity" dur="750ms" values=".7;.65;.55;.45;.35;.25;.15;.1;0;1;.85;.7" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(120)"><animate attributeName="stroke-opacity" dur="750ms" values=".85;.7;.65;.55;.45;.35;.25;.15;.1;0;1;.85" repeatCount="indefinite"></animate></line><line y1="12" y2="20" transform="translate(32,32) rotate(150)"><animate attributeName="stroke-opacity" dur="750ms" values="1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1" repeatCount="indefinite"></animate></line></g></svg>

Dots:

<svg height="1em" fill="currentColor" viewBox="0 0 64 64"><g><circle cx="16" cy="32" stroke-width="0"><animate attributeName="fill-opacity" dur="750ms" values=".5;.6;.8;1;.8;.6;.5;.5" repeatCount="indefinite"></animate><animate attributeName="r" dur="750ms" values="3;3;4;5;6;5;4;3" repeatCount="indefinite"></animate></circle><circle cx="32" cy="32" stroke-width="0"><animate attributeName="fill-opacity" dur="750ms" values=".5;.5;.6;.8;1;.8;.6;.5" repeatCount="indefinite"></animate><animate attributeName="r" dur="750ms" values="4;3;3;4;5;6;5;4" repeatCount="indefinite"></animate></circle><circle cx="48" cy="32" stroke-width="0"><animate attributeName="fill-opacity" dur="750ms" values=".6;.5;.5;.6;.8;1;.8;.6" repeatCount="indefinite"></animate><animate attributeName="r" dur="750ms" values="5;4;3;3;4;5;6;5" repeatCount="indefinite"></animate></circle></g></svg>

Plain old JavaScript

You can also use the spinners via plain old JavaScript:

  1. require() or import() the spinner you want in your project.

  2. Instantiate the class and pass it an options object that contains the DOM element that you want the class to bind to any properties you want to include. Valid properties are:

    • size: the size of the spinner (height; width is auto-calculated). Default: 1em. You can use any CSS sizing unit.
    • colour: the colour of the spinner (default: uses the colour of the surrounding context). You can use any valid CSS colour value.
    • show: a boolean indicating whether the spinner is visible. Default: true.

Example (JavaScript)

<main>
  <div id='spinner'></div>

  <script type='module'>
    import { Lines } from 'https://unpkg.com/@small-tech/[email protected]/dist/index.mjs'

    const lines = new Lines({
      target: document.getElementById('spinner'),
      props: {
        size: '2em',
        colour: 'SlateGrey'
      }
    })
  </script>
</main>

You can find a version of this example in the examples/javascript folder.

Svelte

Finally, you can also use the spinners in your Svelte projects.

The example below is functionally identical to the plain old JavaScript one, above.

<script>
  import { Lines } from '@small-tech/spinners'
</script>

<Lines size='2em' colour='SlateGrey' />

You can find a version of this example in the examples/svelte folder.

Generate PNGs

In an ideal world, animated SVGs (yes, even those that use SMIL animations – which are great, by the way) should be supported everywhere. Sadly, we don’t live in an ideal world. We live in a world where GitHub can mass-violate the copyright of free and open source projects implement “AI pair programming” but cannot render a simple animated SVG properly.

So, if you’re viewing this readme on GitHub, what you’re seeing above are bitmap versions (animated PNGs) of the spinners exported using tiny scripts I wrote for that purpose. The reason they’re a shade of blue is because, unlike the SVGs which default to using the currentColor of their context, I had to export a colour that would work with acceptable contrast on both light and dark mode.

They’re embedded as fallbacks within <foreignObject> tags inside of the inline SVGs in the readme (so, for example, if you’re viewing them in VSCodium, you will only see the SVG spinners, not two sets of spinners).

You can also use these scripts to generate your own animated PNG versions of the spinners, should you so desire.

First, clone this repository. Then, install the dependencies:

cd png
npm install
cd ..

And run the scripts:

node png/lines
node png/dots

You can customise the size, colour, and frame multiplier (animation resolution) via options.

To see all options:

node png/lines --help
node png/dots --help

If you’re interested in the nitty gritties of image manipulation, view the source of the lines.js and dots.js scripts to see an example of how to convert SVGs to animated PNGs in Node.js using the svg-png-converter and node-apng modules.

(Yes, I know I should refactor the redundancies between those two scripts. No, I don’t have the time to do that now. And yes, I’ve already spent far more time than on this than any reasonable person should have.)

Like this? Fund us!

Small Technology Foundation is a tiny, independent not-for-profit.

We exist in part thanks to patronage by people like you. If you share our vision and want to support our work, please become a patron or donate to us today and help us continue to exist.

License

ISC (Ionic Framework’s spinners are under MIT)