Skip to content
ย 
ย 

Latest commit

ย 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

ScrollCounter โœจ

Live Demo

Check out the live site: https://spiddyyy.github.io/counter-scroll/

A powerful, lightweight, and highly customizable JavaScript library for animated scroll counters. Perfect for showcasing statistics, metrics, and numbers with smooth scroll-triggered animations.

๐Ÿš€ Features

  • ๐ŸŽฏ Scroll-triggered animations - IntersectionObserver with fallback support
  • ๐Ÿ’ฐ Currency formatting - Built-in currency symbols and separators
  • ๐Ÿ“ˆ Smart abbreviations - Automatic K/M/B/T formatting for large numbers
  • ๐Ÿ”ข Decimal precision - Support for any number of decimal places
  • ๐ŸŒŠ Advanced easing - 15+ easing functions including bounce, back, and elastic
  • ๐ŸŽฎ Manual controls - Programmatic trigger, reset, and control
  • ๐Ÿ“ฑ Performance optimized - Throttled events and memory cleanup
  • ๐Ÿ”ง Developer friendly - TypeScript ready, callbacks, and flexible configuration
  • ๐Ÿ“ฆ Zero dependencies - Pure vanilla JavaScript
  • ๐ŸŒ Universal support - Works with all module systems (ES6, CommonJS, AMD, Global)

๐Ÿ“ฆ Installation

CDN (Quick Start)

<script src="https://cdn.jsdelivr.net/gh/Spiddyyy/counter-scroll@1.0.0v/scroll-counter.min.js"></script>

NPM

npm install scrollcounter

Yarn

yarn add scrollcounter

๐ŸŽฏ Quick Start

HTML

<div class="counter-value" data-count="1250">0</div>
<div class="counter-value" data-count="99.9" data-decimals="1" data-suffix="%">0%</div>
<div class="counter-value" data-count="1500000" data-currency="true" data-abbreviate="true">$0</div>

JavaScript

// Simple initialization
const counter = new ScrollCounter();

// Advanced configuration
const counter = new ScrollCounter('.counter-value', {
    duration: 2000,
    easing: 'easeOutQuart',
    decimals: 0,
    currency: false,
    onComplete: (element, value) => {
        console.log('Animation completed!', value);
    }
});

๐Ÿ› ๏ธ Configuration Options

Option Type Default Description
duration Number 2000 Animation duration in milliseconds
easing String 'easeOutQuart' Animation easing function
once Boolean true Animate only once when scrolled into view
replay Boolean false Re-animate when scrolling back into view
decimals Number 0 Number of decimal places to show
separator String ',' Thousands separator character
decimal String '.' Decimal point character
prefix String '' Text to prepend to the number
suffix String '' Text to append to the number
currency Boolean false Enable currency formatting
currencySymbol String '$' Currency symbol to use
abbreviate Boolean false Use K/M/B/T abbreviations for large numbers
useGrouping Boolean true Add thousand separators
step Number 1 Increment step (e.g., count by 5s, 10s)
onStart Function null Callback when animation starts
onUpdate Function null Callback during animation
onComplete Function null Callback when animation completes

๐ŸŽจ Available Easing Functions

'linear', 'easeIn', 'easeOut', 'easeInOut',
'easeInQuad', 'easeOutQuad', 'easeInOutQuad',
'easeInCubic', 'easeOutCubic', 'easeInOutCubic',
'easeInQuart', 'easeOutQuart', 'easeInOutQuart',
'easeInQuint', 'easeOutQuint', 'easeInOutQuint',
'easeInSine', 'easeOutSine', 'easeInOutSine',
'easeInExpo', 'easeOutExpo', 'easeInOutExpo',
'easeInBack', 'easeOutBack', 'easeInOutBack',
'bounce'

๐Ÿ“Š Data Attributes

Override global options with HTML data attributes:

Attribute Example Description
data-count data-count="1250" Target number to count to
data-duration data-duration="3000" Animation duration
data-easing data-easing="bounce" Easing function
data-decimals data-decimals="2" Decimal places
data-prefix data-prefix="$" Prefix text
data-suffix data-suffix="%" Suffix text
data-separator data-separator="." Thousands separator
data-decimal data-decimal="," Decimal point
data-currency data-currency="true" Enable currency mode
data-currency-symbol data-currency-symbol="โ‚ฌ" Currency symbol
data-abbreviate data-abbreviate="true" Enable abbreviations
data-grouping data-grouping="false" Disable grouping
data-step data-step="5" Count increment
data-threshold data-threshold="0.8" Visibility threshold (0-1)

๐Ÿ’ก Usage Examples

Basic Counter

<div class="counter-value" data-count="1250">0</div>

Currency with Decimals

<div class="counter-value" 
     data-count="1599.99" 
     data-currency="true" 
     data-decimals="2">$0.00</div>

Large Numbers with Abbreviations

<div class="counter-value" 
     data-count="1500000" 
     data-abbreviate="true" 
     data-currency="true">$0</div>
<!-- Result: $1.5M -->

Percentage with Custom Easing

<div class="counter-value" 
     data-count="95" 
     data-suffix="%" 
     data-easing="bounce" 
     data-duration="3000">0%</div>

European Formatting

<div class="counter-value" 
     data-count="1234.56" 
     data-separator="." 
     data-decimal="," 
     data-decimals="2">0,00</div>
<!-- Result: 1.234,56 -->

Custom Step Counting

<div class="counter-value" 
     data-count="100" 
     data-step="5">0</div>
<!-- Counts: 0, 5, 10, 15, 20... 100 -->

๐ŸŽฎ API Methods

Manual Control

const counter = new ScrollCounter();

// Trigger all counters
counter.trigger();

// Trigger specific counters
counter.trigger('.stats-counter');

// Reset all counters
counter.reset();

// Reset specific counters
counter.reset('.stats-counter');

// Cleanup (remove observers and events)
counter.destroy();

Static Initialization

// One-liner initialization
const counter = ScrollCounter.init('.counter-value', {
    duration: 3000,
    easing: 'easeOutBack'
});

๐Ÿ”ง Advanced Configuration

With Callbacks

const counter = new ScrollCounter('.counter-value', {
    duration: 2000,
    easing: 'easeOutQuart',
    onStart: (element, startValue, targetValue) => {
        element.style.color = '#007bff';
        console.log(`Starting animation from ${startValue} to ${targetValue}`);
    },
    onUpdate: (element, currentValue, progress) => {
        // Update progress bar, change colors, etc.
        const opacity = 0.5 + (progress * 0.5);
        element.style.opacity = opacity;
    },
    onComplete: (element, finalValue) => {
        element.style.color = '#28a745';
        console.log(`Animation completed! Final value: ${finalValue}`);
    }
});

Multiple Instances

// Different configurations for different sections
const statsCounters = new ScrollCounter('.stats-counter', {
    duration: 3000,
    easing: 'easeOutBack',
    currency: true,
    abbreviate: true
});

const achievementCounters = new ScrollCounter('.achievement-counter', {
    duration: 1500,
    easing: 'bounce',
    suffix: '%'
});

๐ŸŒ Module System Support

ES6 Modules

import ScrollCounter from 'scrollcounter';
const counter = new ScrollCounter();

CommonJS

const ScrollCounter = require('scrollcounter');
const counter = new ScrollCounter();

AMD

define(['scrollcounter'], function(ScrollCounter) {
    const counter = new ScrollCounter();
});

โšก Performance Features

  • IntersectionObserver - Efficient scroll detection with automatic fallback
  • Throttled events - Optimized scroll event handling
  • Memory management - Proper cleanup of observers and event listeners
  • Animation prevention - Prevents overlapping animations on same elements
  • Minimal DOM queries - Cached selectors and optimized queries

๐ŸŽฏ Browser Support

  • Modern browsers - Full IntersectionObserver support
  • Legacy browsers - Automatic fallback to scroll events
  • Mobile optimized - Touch-friendly and performant on mobile devices
  • IE11+ - With polyfill for IntersectionObserver

๐Ÿ“ฑ Framework Integration

React Hook

import { useEffect, useRef } from 'react';
import ScrollCounter from 'scrollcounter';

function useScrollCounter(options = {}) {
    const ref = useRef();
    
    useEffect(() => {
        if (ref.current) {
            const counter = new ScrollCounter(ref.current, options);
            return () => counter.destroy();
        }
    }, []);
    
    return ref;
}

// Usage
function StatsComponent() {
    const counterRef = useScrollCounter({ duration: 3000 });
    
    return (
        <div ref={counterRef} className="counter-value" data-count="1250">
            0
        </div>
    );
}

Vue.js Directive

// Vue directive
app.directive('scroll-counter', {
    mounted(el, binding) {
        new ScrollCounter(el, binding.value || {});
    }
});

// Usage in template
<div v-scroll-counter="{ duration: 3000 }" class="counter-value" data-count="1250">0</div>

๐Ÿš€ CDN Quick Setup

For immediate use without installation:

<!DOCTYPE html>
<html>
<head>
    <title>ScrollCounter Demo</title>
</head>
<body>
    <!-- Your counter elements -->
    <div class="counter-value" data-count="1250">0</div>
    <div class="counter-value" data-count="99" data-suffix="%">0%</div>
    
    <!-- Include library -->
    <script src="https://cdn.jsdelivr.net/gh/Spiddyyy/counter-scroll@1.0.0v/scroll-counter.min.js"></script>
    
    <!-- Initialize -->
    <script>
        const counter = new ScrollCounter();
    </script>
</body>
</html>

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ†˜ Support

๐ŸŽ‰ Examples & Demos


โญ If you found ScrollCounter helpful, please give it a star on GitHub! โญ

Made with โค๏ธ for the developer community

Demo โ€ข Documentation โ€ข GitHub

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages