๐จ๐ณ ็ฎไฝไธญๆ | ๐ฌ๐ง English
High-Performance Text Diff Motion Component based on Levenshtein diff algorithm. Make your text flow like water. Live Demo >
Supports any characters
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 dev
When 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.,'
0 to 9 in Presets.NUMBER), they will scroll.Presets.ALPHANUMERIC to support most alphanumeric scrolling.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 dev
cd examples/vue-demo
npm install
npm run dev
cd examples/svelte-demo
npm install
npm run dev
smart-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
See CHANGELOG_EN.md for version history.
MIT