npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

masoneffect

v2.0.19

Published

A collection of animation effects library. Supports React, Vue, Svelte, and vanilla JavaScript with Tree-shaking support.

Readme

MasonEffect npm

Release version 2.0.19

A collection of animation effects library. Supports React, Vue, Svelte, and vanilla JavaScript with Tree-shaking support.

🤖 For AI Agents: If you are an AI agent (Cursor, GitHub Copilot, ChatGPT, etc.) setting up this package, please read llms.txt first for automatic environment detection and configuration.

✨ Features

  • 🎯 Tree-shaking Support: Import only the effects you need
  • 🎨 Multiple Effects: Various animation effects in one package
  • 🔧 Framework Agnostic: Works with React, Vue, Svelte, and vanilla JS
  • 📦 TypeScript: Full TypeScript support
  • Optimized: Automatic code splitting and optimization

📦 Installation

npm install masoneffect

🤖 AI Agent Guide

⚠️ IMPORTANT FOR AI AGENTS: Before using this package, read llms.txt (primary AI guide) for:

  • Automatic environment detection (framework, TypeScript, build tool)
  • Framework-specific setup guides
  • Effect recommendation logic based on user requests
  • Complete code templates for all frameworks
  • Tree-shaking optimization rules

This guide is optimized for AI agents to automatically configure MasonEffect correctly in any project.

🎯 Available Effects

  1. TextToParticle - Converts text into animated particles with morphing effects
  2. Count - Animated number counting with intersection observer support
  3. Typing - Typing animation effect with Korean character decomposition
  4. ScrollFadeIn - Scroll-triggered fade-in animation effect
  5. TextSpin - Text animation that splits text into characters and reveals them randomly with a spin effect

🚀 Quick Start

Tree-shaking (Recommended)

// ✅ Recommended: Import only what you need
import { TextToParticle } from 'masoneffect/textToParticle';
import { Count } from 'masoneffect/count';

Framework-specific imports

// React
import TextToParticle from 'masoneffect/react/textToParticle';
import Count from 'masoneffect/react/count';

// Vue
import TextToParticle from 'masoneffect/vue/textToParticle';
import Count from 'masoneffect/vue/count';

// Svelte
import TextToParticle from 'masoneffect/svelte/textToParticle';
import Count from 'masoneffect/svelte/count';

📖 Usage Examples

TextToParticle

Vanilla JavaScript

import { TextToParticle } from 'masoneffect/textToParticle';

const container = document.getElementById('my-container');
const effect = new TextToParticle(container, {
  text: 'Hello World',
  particleColor: '#00ff88',
  maxParticles: 2000,
});

effect.morph({ text: 'New Text' });
effect.scatter();

React

import React, { useRef } from 'react';
import TextToParticle from 'masoneffect/react/textToParticle';
import type { TextToParticleRef } from 'masoneffect/react/textToParticle';

function App() {
  const effectRef = useRef<TextToParticleRef>(null);

  return (
    <div style={{ width: '100%', height: '70vh', background: '#000' }}>
      <TextToParticle
        ref={effectRef}
        text="Hello React"
        particleColor="#00ff88"
        maxParticles={2000}
      />
      <button onClick={() => effectRef.current?.morph({ text: 'Morphed!' })}>
        Morph
      </button>
    </div>
  );
}

Count

Vanilla JavaScript

import { Count, easingFunctions } from 'masoneffect/count';

const container = document.getElementById('count-container');
const count = new Count(container, {
  targetValue: 1000,
  duration: 2000,
  easing: easingFunctions.easeOutCubic,
});

count.start();

React

import React from 'react';
import Count from 'masoneffect/react/count';
import { easingFunctions } from 'masoneffect/react/count';

function App() {
  return (
    <Count
      targetValue={1000}
      duration={2000}
      easing={easingFunctions.easeOutCubic}
      style={{ fontSize: '3rem', fontWeight: 'bold' }}
    />
  );
}

ScrollFadeIn

Vanilla JavaScript

import { ScrollFadeIn } from 'masoneffect/scrollFadeIn';

const container = document.querySelector('#scroll-fade-in-container');
const scrollFadeIn = new ScrollFadeIn(container, {
  direction: 'bottom',
  distance: '50px',
  duration: 800,
});

// For internal scroll container
const scrollContainer = document.querySelector('.scroll-container');
const scrollFadeInInContainer = new ScrollFadeIn(container, {
  direction: 'bottom',
  distance: '50px',
  root: scrollContainer, // Specify scroll container element
});

React

import React from 'react';
import { ScrollFadeIn } from 'masoneffect/react/scrollFadeIn';

function App() {
  return (
    <ScrollFadeIn direction="bottom" distance="50px" duration={800}>
      <div>Content that fades in on scroll</div>
    </ScrollFadeIn>
  );
}

TextSpin

Vanilla JavaScript

import { TextSpin } from 'masoneffect/textSpin';

const container = document.querySelector('#text-spin-container');
const textSpin = new TextSpin(container, {
  text: 'Hello World',
  delay: 0.2,
  duration: 0.6,
  randomDelay: 2,
});

textSpin.updateText('New Text');

React

import React from 'react';
import { TextSpin } from 'masoneffect/react/textSpin';

function App() {
  return (
    <TextSpin
      text="Hello World"
      delay={0.2}
      duration={0.6}
      randomDelay={2}
      style={{ fontSize: '2rem', color: '#fff' }}
    />
  );
}

💡 Note: For Vue and Svelte examples, see llms.txt or check the framework-specific import paths above.


📚 API Reference

TextToParticle

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | text | string | 'mason effect' | Text to display (use \n for line breaks) | | densityStep | number | 2 | Particle sampling density (smaller = denser) | | maxParticles | number | 3200 | Maximum number of particles | | pointSize | number | 0.5 | Particle point size | | ease | number | 0.05 | Movement acceleration | | repelRadius | number | 150 | Mouse repel radius | | repelStrength | number | 1 | Mouse repel strength | | particleColor | string | '#fff' | Particle color | | fontFamily | string | 'Inter, system-ui, Arial' | Font family | | fontSize | number \| null | null | Font size (auto-adjusts if null) | | width | number \| null | null | Canvas width (container size if null) | | height | number \| null | null | Canvas height (container size if null) | | devicePixelRatio | number \| null | null | Device pixel ratio (auto if null) | | debounceDelay | number | 150 | Debounce delay in milliseconds | | onReady | function | null | Initialization complete callback | | onUpdate | function | null | Update callback |

Methods

  • morph(textOrOptions?: string | Partial<TextToParticleOptions>) - Morph particles into text
  • scatter() - Return particles to initial position
  • updateConfig(config: Partial<TextToParticleOptions>) - Update configuration
  • destroy() - Destroy instance and cleanup

Count

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | targetValue | number | required | Target number to count to | | duration | number | 2000 | Animation duration in milliseconds | | startValue | number | 0 | Starting number | | enabled | boolean | true | Enable/disable animation | | easing | function | linear | Easing function | | threshold | number | 0.2 | IntersectionObserver threshold | | rootMargin | string | '0px 0px -100px 0px' | IntersectionObserver rootMargin | | triggerOnce | boolean | false | Trigger animation only once | | onUpdate | function | null | Update callback (receives current value) | | onComplete | function | null | Animation complete callback |

Methods

  • start() - Start animation
  • stop() - Stop animation
  • reset() - Reset to start value
  • getValue() - Get current value
  • updateConfig(config: Partial<CountOptions>) - Update configuration
  • destroy() - Destroy instance and cleanup

Easing Functions

import { easingFunctions } from 'masoneffect/count';

// Available: linear, easeInQuad, easeOutQuad, easeInOutQuad, easeOutCubic
easingFunctions.easeOutCubic

ScrollFadeIn

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | direction | 'top' \| 'right' \| 'bottom' \| 'left' | 'bottom' | Animation direction | | distance | string | '50px' | Animation distance (supports px, rem, em, %, vh, vw) | | duration | number | 800 | Animation duration in milliseconds | | threshold | number | 0.1 | IntersectionObserver threshold | | rootMargin | string | '0px' | IntersectionObserver rootMargin | | root | HTMLElement \| null | null | IntersectionObserver root element (for internal scroll containers) | | triggerOnce | boolean | false | Trigger animation only once | | enabled | boolean | true | Enable/disable animation | | onStart | function | null | Animation start callback | | onComplete | function | null | Animation complete callback |

Methods

  • start() - Start animation
  • stop() - Stop animation
  • reset() - Reset to initial position
  • updateConfig(config: Partial<ScrollFadeInOptions>) - Update configuration
  • destroy() - Destroy instance and cleanup

TextSpin

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | text | string | required | Text to animate | | delay | number | 0.2 | Base delay in seconds before animation starts | | duration | number | 0.6 | Animation duration in seconds for each character | | randomDelay | number | 2 | Random delay range in seconds (0 to randomDelay) | | threshold | number | 0.1 | IntersectionObserver threshold | | rootMargin | string | '0px' | IntersectionObserver rootMargin | | root | HTMLElement \| null | null | IntersectionObserver root element (for internal scroll containers) | | triggerOnce | boolean | false | Trigger animation only once | | enabled | boolean | true | Enable/disable animation | | onStart | function | null | Animation start callback | | onComplete | function | null | Animation complete callback |

Methods

  • start() - Start animation
  • stop() - Stop animation
  • reset() - Reset animation state
  • updateText(text: string) - Update text and restart animation
  • updateConfig(config: Partial<TextSpinOptions>) - Update configuration
  • destroy() - Destroy instance and cleanup

Note: TextSpin inherits parent styles by default. The container element will maintain the parent's font size, color, and other text styles.


🌳 Tree-shaking

MasonEffect supports Tree-shaking, allowing you to import only the effects you need:

// ✅ Recommended: Only imports Count (smaller bundle)
import { Count } from 'masoneffect/count';

// ❌ Not recommended: Imports all effects (larger bundle)
import { Count } from 'masoneffect';

🔄 Backward Compatibility

For backward compatibility, the old API still works:

// Old API (still works)
import { MasonEffect } from 'masoneffect';
import MasonEffect from 'masoneffect/react';

// MasonEffect is an alias for TextToParticle
const effect = new MasonEffect(container, { text: 'Hello' });

However, we recommend using the new Tree-shaking-friendly imports for better performance.


🛠️ Development

# Install dependencies
npm install

# Development mode (watch)
npm run dev

# Build (generate production files)
npm run build

# Example test server
npm run serve

📦 CDN Usage (UMD)

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.umd.min.js"></script>
<script>
  // TextToParticle (MasonEffect alias for backward compatibility)
  const container = document.getElementById('my-container');
  const effect = new MasonEffect(container, {
    text: 'Hello World',
    particleColor: '#00ff88',
  });
</script>

Note: CDN version includes all effects. For Tree-shaking, use npm package.


📄 License

MIT


🔗 Links