🇨🇳 简体中文 | 🇬🇧 English
High-Performance Text Diff Motion Component based on Levenshtein diff algorithm. Make your text flow like water. Live Demo >
Supports Prefix/Suffix, Intl Formatting, Auto-Scale, Fading Edges
| 🌏 Multi-Charset Support Supports CJK, Numbers, Emojis, and mixed text rolling. Auto-adjusts spacing based on Unicode width. |
🧠 Smart Diff Animation Uses Levenshtein algorithm to find the shortest change path; identical characters remain static. |
| ⚡ Smooth Interruption Seamlessly transitions to new targets if the value changes dynamically during animation. |
📈 Rich Motion Built-in variety of easings.Supports custom easing function. Supports charWidth fine-tuning. |
| 🦄 Multi-Framework React (Hooks), Vue 3 (Composition), and Svelte 4+ components with a unified API. |
🚀 High Performance Powered by RAF, supporting Auto-scale, Fading Edge, and Disable Animation. |
npm install @tombcato/smart-ticker# Clone repository
git clone https://github.com/tombcato/smart-ticker.git
# Install dependencies
cd smart-ticker
npm install
# Start dev server
npm run devWhen using NPM, you MUST explicitly import the style file for the component to work.
import '@tombcato/smart-ticker/style.css'Source Integration: If copying source code, ensure React version imports
Ticker.cssand Vue version uses the built-in styles.
// NPM Usage
import { Ticker } from '@tombcato/smart-ticker';
import '@tombcato/smart-ticker/style.css';
// Source Usage
// import { Ticker } from './components/Ticker';
function App() {
const [price, setPrice] = useState(73.18);
return (
<Ticker
value={price.toFixed(2)}
duration={800}
easing="easeInOut"
charWidth={1}
characterLists={['0123456789.,']}
/>
);
}<script setup>
// NPM Usage
import { Ticker } from '@tombcato/smart-ticker/vue';
import '@tombcato/smart-ticker/style.css';
// Source Usage
// import Ticker from './components/vue/Ticker.vue';
import { ref } from 'vue';
const price = ref('73.18');
</script>
<template>
<Ticker
:value="price"
:duration="800"
easing="easeInOut"
:char-width="1"
:character-lists="['0123456789.,']"
/>
</template><script>
// NPM Usage
import { Ticker } from '@tombcato/smart-ticker/svelte';
import '@tombcato/smart-ticker/style.css';
let price = 73.18;
</script>
<Ticker
value={price.toFixed(2)}
duration={800}
easing="easeInOut"
charWidth={1}
characterLists={['0123456789.,']}
/>The component uses the system monospace stack by default. To use a custom font (e.g., JetBrains Mono), ensure it is monospace and override via CSS:
/* In global styles or component styles */
.ticker {
font-family: 'JetBrains Mono', monospace !important;
}Note: Must be a monospace font, otherwise alignment issues may occur during scrolling animations.
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string|number |
- | The text value to display (Required) |
duration |
number |
500 |
Animation duration (ms) |
easing |
EasingName | function |
'easeInOut' |
Easing: linear, easeIn, easeOut, easeInOut, bounce, or custom (t: number) => number |
direction |
string |
'ANY' |
Scroll direction: UP, DOWN, ANY (shortest path) |
charWidth |
number |
1 |
Character width multiplier (base 0.8em) |
characterLists |
string[] |
['0123456789'] |
Allowed character sets |
className |
string |
'' |
Custom CSS class name |
animateOnMount |
boolean |
false |
Animate on initial render |
disableAnimation |
boolean |
false |
Disable animation, show final value immediately |
autoScale |
boolean |
false |
Enable auto-scaling to fit container width |
fadingEdge |
boolean |
false |
Enable top/bottom fading edge effect |
prefix |
string |
- | Static prefix (not animated) |
suffix |
string |
- | Static suffix (not animated) |
numberFormat |
Intl.NumberFormat |
- | Intl formatter number value |
onAnimationEnd |
() => void |
- | Callback when animation ends (Vue: @animation-end) |
characterLists controls the core animation logic. It accepts an array of strings, where each string represents a group of characters that can scroll into each other.
For convenience, we provide built-in constants for common character sets:
import { Presets } from '@tombcato/smart-ticker';
Presets.NUMBER // '0123456789'
Presets.ALPHABET // 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
Presets.ALPHANUMERIC // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
Presets.CURRENCY // '0123456789.,'- Scroll: If both the old and new characters belong to the same group string (e.g.,
0to9inPresets.NUMBER), they will scroll. - Switch: If they are in different groups, or if a character is not in any list (e.g., Chinese characters), they will switch instantly (fade/flip) without scrolling.
- Common Use Case: Simply use
Presets.ALPHANUMERICto support most alphanumeric scrolling. - Case Isolation: To prevent scrolling between cases (e.g.,
a->A), list them as separate groups:[Presets.NUMBER, 'abc...', 'ABC...'].
Code Example:
<Ticker
value={val}
characterLists={[
Presets.NUMBER, // Numbers
'abcdefghijklmnopqrstuvwxyz', // Lowercase Group
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', // Uppercase Group
'.,!@#$%^&*' // Symbols
]}
/>This project includes complete NPM-based user examples for React, Vue, and Svelte in the examples directory.
cd examples/react-demo
npm install
npm run devcd examples/vue-demo
npm install
npm run devcd examples/svelte-demo
npm install
npm run devsmart-ticker/
├── src/
│ ├── components/
│ │ ├── Ticker.tsx # React Component
│ │ ├── Ticker.css # Core Styles
│ │ ├── vue/
│ │ │ └── Ticker.vue # Vue Component
│ │ └── svelte/
│ │ └── Ticker.svelte # Svelte Component
│ ├── core/
│ │ └── TickerCore.ts # Core Logic (Levenshtein diff algo)
│ └── ...
├── examples/ # Standalone Example Projects
│ ├── react-demo/ # React Demo (Vite + React + TS)
│ ├── vue-demo/ # Vue Demo (Vite + Vue + TS)
│ └── svelte-demo/ # Svelte Demo (Vite + Svelte + TS)
└── package.json
- Financial Data - Stock prices, crypto rates
- Counters - Page views, likes
- Scoreboards - Real-time sports scores
- Airport Info - Flight numbers, gates
- Privacy Mode - Balance hide/show toggle
- Build Tool: Vite
- Language: TypeScript
- Frameworks: React 18 / Vue 3 / Svelte 4+
- Styling: CSS Variables + Responsive Design
See CHANGELOG_EN.md for version history.
MIT

