Description:
Smart Ticker is a text animation component that renders smooth value transitions for React and Vue applications.
It implements the Levenshtein difference algorithm to calculate the shortest edit path between two strings. This keeps identical characters static and restricts movement to only the changing elements.
Features
- 🌏 Multi-Charset Support: Handles CJK, numbers, emojis, and mixed text with automatic spacing adjustments based on Unicode width.
- 🧠 Smart Diff Algorithm: Applies Levenshtein distance calculation to identify the minimal character changes between old and new values.
- ⚡ Smooth Interruption Handling: Recalculates animation paths when values change mid-transition without visual glitches.
- 📈 Multiple Easing Functions: Includes linear, bounce, easeIn, easeOut, and easeInOut timing functions.
- 🦄 Framework Support: Comes with separate React Hooks and Vue 3 Composition API packages with unified prop interfaces.
- 🚀 RAF-Based Performance: Runs animation loops through requestAnimationFrame for optimal frame timing.
- 📏 Character Width Control: Exposes a
charWidthmultiplier to fine-tune character spacing for different fonts. - 🎯 Direction Control: Supports UP, DOWN, or ANY (shortest path) scroll directions.
See It In Action
Use Cases
- Financial Dashboards: Display real-time stock prices, cryptocurrency rates, or forex values with smooth number transitions.
- Analytics Counters: Animate page view counts, like counts, or user statistics that update frequently.
- Sports Scoreboards: Show live game scores, player statistics, or countdown timers with dynamic updates.
- Airport Information Displays: Render flight numbers, gate assignments, or departure times with classic split-flap board aesthetics.
Installation
npm install @tombcato/smart-tickerReact Implementation
Import the component and required styles in your React application:
import { Ticker } from '@tombcato/smart-ticker';
import '@tombcato/smart-ticker/style.css';
import { useState } from 'react';
function PriceDisplay() {
const [price, setPrice] = useState(73.18);
// Simulate price updates
const updatePrice = () => {
setPrice(prev => prev + (Math.random() - 0.5) * 10);
};
return (
<div>
<Ticker
value={price.toFixed(2)}
duration={800}
easing="easeInOut"
charWidth={1}
characterLists={['0123456789.,']}
/>
<button onClick={updatePrice}>Update Price</button>
</div>
);
}Vue Implementation
Import the Vue-specific component in your Vue 3 application:
<script setup>
import { Ticker } from '@tombcato/smart-ticker/vue';
import '@tombcato/smart-ticker/style.css';
import { ref } from 'vue';
const counter = ref('1234');
const increment = () => {
counter.value = String(Number(counter.value) + 1);
};
</script>
<template>
<div>
<Ticker
:value="counter"
:duration="600"
easing="bounce"
:char-width="1.2"
:character-lists="['0123456789']"
/>
<button @click="increment">Increment</button>
</div>
</template>Character List Configuration
The characterLists prop controls which characters can scroll into each other. Characters within the same string will animate through scrolling. Characters in different strings or not in any list will switch instantly.
import { Ticker, TickerUtils } from '@tombcato/smart-ticker';
<Ticker
value="ABC123"
characterLists={[
TickerUtils.provideNumberList(), // '0123456789'
TickerUtils.provideAlphabeticalList(), // 'a-z' and 'A-Z'
'.,!@#$%' // Custom symbols
]}
/>To prevent scrolling between uppercase and lowercase letters, separate them into different strings:
characterLists={[
'abcdefghijklmnopqrstuvwxyz', // Lowercase group
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', // Uppercase group
'0123456789' // Numbers
]}Custom Font Styling
The component uses monospace system fonts by default. Override this with custom monospace fonts through CSS:
.ticker {
font-family: 'JetBrains Mono', 'Fira Code', monospace !important;
font-size: 24px;
color: #00ff00;
}You must use monospace fonts to maintain proper character alignment during animations. Proportional fonts will cause visual misalignment.
Available component props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | Required | The text content to display and animate |
duration | number | 500 | Animation duration in milliseconds |
easing | string | 'easeInOut' | Timing function: linear, easeIn, easeOut, easeInOut, or bounce |
direction | string | 'ANY' | Scroll direction: UP (upward), DOWN (downward), or ANY (shortest path) |
charWidth | number | 1 | Character width multiplier based on 0.8em base width |
characterLists | string[] | ['0123456789'] | Array of character groups that can scroll into each other |
className | string | '' | Custom CSS class applied to the root element |
Utility Functions
The TickerUtils object exports helper functions for common character sets:
TickerUtils.provideNumberList(): Returns '0123456789' for numeric animations.
TickerUtils.provideAlphabeticalList(): Returns combined uppercase and lowercase letters 'abc...zABC...Z'.
Related Resources
- React CountUp: A React component that animates number counting with extensive configuration options.
FAQs
Q: Can I use proportional fonts with this component?
A: No. The component requires monospace fonts to maintain proper character alignment during scroll animations. Proportional fonts will cause visual misalignment between characters.
Q: How do I prevent scrolling between certain characters?
A: Place characters in separate strings within the characterLists array. Characters in different strings will switch instantly instead of scrolling. For example, use ['abc', 'ABC'] to prevent lowercase-to-uppercase scrolling.
Q: What happens if I update the value during an active animation?
A: The component recalculates the diff path and smoothly transitions to the new target value. The animation continues without visual glitches or resets.
Q: Why do some characters switch instantly instead of scrolling?
A: Characters not included in any characterLists string will switch instantly. CJK characters, special symbols, and other non-configured characters use instant switching by default.
Q: How do I adjust animation speed for different character types?
A: Use the duration prop to control animation length in milliseconds. Combine this with the easing prop to adjust acceleration curves. The charWidth prop adjusts spacing but does not affect speed.