flip_counter_plus

Pub Package PRs Welcome YouTube Demo

An ultra-premium, high-performance implicit animation widget that flips numbers with style. Engineered for pixel-perfect accuracy, zero-latency rendering, and fluid kinetics.

🎬 Watch the Live Video Demo on YouTube

Donate with PayPal button

📸 Showcase

Counter Animation Custom Styling & Transitions Stock Market Ticker
Counter Demo Style Demo Stock Market Demo

⚡ Engineered for Performance & Visual Excellence

Behind the fluid mechanical aesthetics lies a highly optimized rendering engine designed for production-critical performance (e.g., real-time dashboards, tickers, stock markets):

  • Zero GC / Repaint Isolation: Uses isolated rendering trees (RepaintBoundary) to contain redraws only to changing digits, preventing global screen rebuilds and eliminating Garbage Collection (GC) pauses during fast scrolls.
  • Tabular Figure (Monospace) Alignment: Locks numeral layouts using native font tabular alignments to prevent layout shifting or "wobbly" UI adjustments.
  • Tactile Kinetics: Supports staggered wave animations, direction-specific color shifts, and native mechanical dial haptic ticks.
  • Custom Widget Injection: Supply any custom widget (icons, badges) as separators, prefixes, suffixes, or custom digit wrappers (e.g., neon slots, cardboard cards).

📊 Performance Benchmarks

In widget pipeline testing (simulating rapid real-time updates over 200 consecutive pumps), flip_counter_plus consistently maintains frame render times well below the standard frame budgets (16.6ms for 60 FPS, 8.3ms for 120 FPS):

Benchmark Case Iterations Total Time Avg Frame Time FPS Equivalent
Standard Integer 200 ~950ms 2.3 ms 420+ FPS
Decimal & Separators 200 ~870ms 2.1 ms 450+ FPS
Staggered Cascade 200 ~540ms 1.3 ms 730+ FPS
Blur Transition 200 ~740ms 1.8 ms 540+ FPS
Compact Notation 200 ~510ms 1.2 ms 770+ FPS

Run benchmarks locally: flutter test test/performance_benchmark_test.dart


📱 Showcase App (Dashboard)

The package includes a comprehensive dashboard app in the example folder showing off the following tabs:

  • Visual Sandbox: Tweak speed multipliers, stagger wave delays, and transition style pickers in real-time.
  • Formatting & Localizations: View presets for major currencies (USD, EUR, GBP, JPY), percentages, compact notations, and regional digits.
  • Custom Stylings: Custom card widgets for Retro Flip Clock, Cyberpunk Neon, Glass Nixie Tube, Wood Game Tile, Pill Capsule, and Morph.
  • Lifecycle & Controller: Control the counter programmatically (play, pause, resume, reverse, loop, and reset).
  • Stock Market Ticker: Real-time high-frequency stock quotes simulation, trend biases, and a mock order execution terminal.

🚀 Usage

Simple Counter

AnimatedFlipCounter(
  value: 2026,
  duration: Duration(milliseconds: 500),
)

Decimals & Custom Separators

AnimatedFlipCounter(
  value: _value, // e.g., 1234.56
  fractionDigits: 2,
  thousandSeparator: ',', // displays "1,234.56"
  decimalSeparator: '.',
  textStyle: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
)

Financial Display & Tinting

Auto-applies colors based on values and shows positive sign.

AnimatedFlipCounter(
  value: _value,
  showPositiveSign: true,
  increasingColor: Colors.green,
  decreasingColor: Colors.red,
)

🛠️ Advanced Customization

1. Custom Transitions & Wrapper Slots

AnimatedFlipCounter(
  value: _value,
  // Wrap each digit inside a custom card decoration
  digitWrapperBuilder: (context, index, child) => Container(
    margin: const EdgeInsets.symmetric(horizontal: 2),
    padding: const EdgeInsets.all(4),
    decoration: BoxDecoration(
      color: Colors.grey[900],
      borderRadius: BorderRadius.circular(4),
    ),
    child: child,
  ),
  // Override transition animation (e.g., Fade & Scale instead of Roll)
  digitTransitionBuilder: (context, current, next, progress, size) => Stack(
    alignment: Alignment.center,
    children: [
      Opacity(opacity: 1.0 - progress, child: Transform.scale(scale: 1.0 - progress, child: current)),
      Opacity(opacity: progress, child: Transform.scale(scale: progress, child: next)),
    ],
  ),
)

2. Staggered Cascades & Horizontal Tapes

AnimatedFlipCounter(
  value: _value,
  staggerDelay: Duration(milliseconds: 80),
  staggerDirection: StaggerDirection.rightToLeft, // rolls digits like a wave
  flipDirection: AxisDirection.left,             // scroll horizontally instead of vertical
)

3. Tactile Haptics & Programmatic Control

final controller = CounterController(initialValue: 100);

AnimatedFlipCounter(
  controller: controller,
  triggerHaptics: true, // system haptic ticks on every digit rollover
)

// Control from anywhere:
controller.animateTo(250);
controller.jumpTo(0); // instant update with no transition

4. Built-in Transition Styles & Preset Constructors

Choose premium preset transitions (roll, fade, scale, fadeScale, rotate, flip, blur) directly:

AnimatedFlipCounter(
  value: _value,
  transitionType: CounterTransitionType.blur, // motion blur transition
)

// Preconfigured factory constructors
AnimatedFlipCounter.usd(value: 1234.56)      // "$1,234.56"
AnimatedFlipCounter.eur(value: 1234.56)      // "1.234,56 €"
AnimatedFlipCounter.percentage(value: 99)   // "99%"
AnimatedFlipCounter.compact(value: 1250000)  // "1.3M"

⚙️ Key API Reference

Parameter Type Default Description
value num? null The value to display. Changes animate automatically.
controller CounterController? null Controller for programmatic control / jumps.
duration Duration 300ms Duration of the digit flip animations.
fractionDigits int 0 Number of decimal places to show.
thousandSeparator String? null Group separators (e.g., ,).
decimalSeparator String '.' Decimal point symbol.
useTabularFigures bool true Forces monospace digits to prevent layout jumps.
showPositiveSign bool false Shows a + sign for positive numbers.
transitionType CounterTransitionType .roll Preset transitions (roll, blur, rotate, flip, scale...).
staggerDelay Duration? null Sequential delay between changing digits.
triggerHaptics bool false Haptic ticks on digit rollover boundaries.
compactNotation bool false Abbreviates numbers (e.g., 1.2M, 5K).
increasingColor Color? null Temporary text color when value increases.
decreasingColor Color? null Temporary text color when value decreases.

Full parameters, custom builders, and listeners are fully documented in flip_counter_plus.dart.


📱 Platform Support

Supports Android, iOS, Web, macOS, Windows, and Linux out of the box with zero native configuration (100% pure Dart & Flutter).


👤 Maintainer

Hadi

Libraries

flip_counter_plus