A smooth, animated odometer-like web component built with Lit. Display numbers with beautiful spinning digit animations that transition seamlessly between values. See the documentation for more details and a live demo.
- π― Smooth Animations: Fluid digit transitions with customizable easing
- π Multi-Direction: Can animate up, down, or the shortest path
- π¨ Customizable Styling: CSS custom properties for complete visual control
- π± Lightweight: Built with Lit for optimal performance
- π’ Flexible Formatting: Support for leading zeros and minimum digit counts
- πͺ Rich Events: Detailed animation lifecycle events
npm install digit-spinner<script type="module" src="node_modules/digit-spinner/dist/index.js"></script>
<!-- Simple counter -->
<digit-spinner value="42"></digit-spinner>The main component that displays animated numbers with spinning digit transitions.
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value |
value |
number |
0 |
The numeric value to display |
direction |
direction |
string |
'forward' |
Animation direction: 'forward', 'backward', or 'shortest' |
duration |
duration |
number |
200 |
Animation duration in milliseconds |
easing |
easing |
string |
'cubic-bezier(0.83, 0, 0.17, 1)' |
Animation easing function |
minDigits |
min-digits |
number |
0 |
Minimum number of digits (pads with leading zeros) |
| Method | Parameters | Description |
|---|---|---|
increment(num?) |
num: number = 1 |
Increase the value by the specified amount |
decrement(num?) |
num: number = 1 |
Decrease the value by the specified amount |
The <digit-spinner> element emits the following events:
| Event | Properties | Description |
|---|---|---|
digit-flip-start |
{from: number, to: number} |
Fired when digit animation begins |
digit-flip-end |
{from: number, to: number} |
Fired when digit animation completes |
digit-wrap |
{from: number, to: number, direction: string} |
Fired when digit wraps from 9 to 0, or 0 to 9 |
<!-- Basic usage -->
<digit-spinner value="123"></digit-spinner>
<!-- With leading zeros -->
<digit-spinner value="42" min-digits="4"></digit-spinner>
<!-- Shows: 0042 -->
<!-- Programmatic control -->
<digit-spinner id="counter" value="0" min-digits="3"></digit-spinner>
<button onclick="document.getElementById('counter').increment()">+</button>
<button onclick="document.getElementById('counter').decrement()">-</button>Customize the appearance using CSS custom properties:
digit-spinner {
--digit-font-size: 2rem;
--digit-font: 'Courier New', monospace;
--digit-color: #333;
--digit-background-color: #f0f0f0;
}Internal elements can also be styled using CSS parts:
digit-spinner::part(container) {
/* Style the main container */
}
digit-spinner::part(digit-wrapper) {
/* Style individual digit wrappers */
}
digit-spinner::part(digit) {
/* Style digit elements */
border-radius: 4px;
padding: 8px;
}In this example, we listen for the digit-flip-start event to log the digit that has begun flipping.
<digit-spinner id="event-demo" value="10"></digit-spinner>
<script>
document
.getElementById('event-demo')
.addEventListener('digit-flip-start', (e) => {
const origin = e.composedPath()[0]; // Reference to the digit
console.log(
`Digit ${origin} has started flipping from ${e.from} to ${e.to}`
);
});
</script><style>
digit-spinner {
--digit-font-size: 2rem;
--digit-font: 'Courier New', monospace;
--digit-color: #333;
--digit-background-color: #f0f0f0;
}
</style>
<digit-spinner value="88888"></digit-spinner>This component uses modern web standards and requires:
- ES2020+ support
- Custom Elements v1
- CSS Custom Properties
- Web Animations API
Supports all modern browsers including Chrome 80+, Firefox 75+, Safari 13.1+, and Edge 80+.
The component is built with:
- Lit - Efficient web component library
- @lit-labs/motion - Animation utilities
- TypeScript - Type safety and better development experience
- Animation mechanics inspired by the @lit-labs/motion Carousel Transition example
- Project was started using lit-element-starter-ts
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit issues and pull requests.