🇨🇳 简体中文 | 🇬🇧 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

