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

@laubloch/scrolly-motion

v1.1.0

Published

Advanced scroll animation library with breakpoint support, timeline presets.

Readme

@laubloch/scrolly-motion

npm version

Performant and advanced scroll animation system with modular architecture, breakpoint support, timeline presets, and stagger animations.

🚀 Try it out! Live Demo 🚀

Modular Architecture - Load Only What You Need

ScrollyMotion now features a modular system that allows you to import only the features you need, significantly reducing bundle size:

  • Minimal Core: ~15 KB (just progress tracking and basic animations)
  • With Timeline: ~25 KB (adds complex timeline animations)
  • Full Featured: ~37 KB (all modules included)

Installation

npm install @laubloch/scrolly-motion

Modular Usage Examples

🎯 Minimal Setup (Smallest Bundle)

Perfect for simple scroll progress tracking and basic up/down detection:

import { ScrollyMotion } from "@laubloch/scrolly-motion";

// Only provides --element-progress CSS variable and basic scroll detection
const scrolly = new ScrollyMotion();

What you get:

  • --element-progress CSS variable (0-1)
  • ✅ Basic scroll enter/exit detection
  • ✅ Element classes (enterClass/leaveClass)
  • ❌ No timeline animations
  • ❌ No stagger effects

🎬 With Timeline Support

Add complex timeline animations with keyframes:

import { ScrollyMotion, timeline } from "@laubloch/scrolly-motion";

// Adds timeline animation parsing and execution
const scrolly = new ScrollyMotion(timeline);

What you get:

  • ✅ Everything from minimal core
  • ✅ Timeline animations (from:, to:, via-50%:)
  • ✅ Animation presets
  • ✅ Complex keyframe animations
  • ❌ No stagger effects

🎭 With Stagger Effects

Add staggered animations for child elements:

import { ScrollyMotion, timeline, stagger } from "@laubloch/scrolly-motion";

// Adds stagger animation support
const scrolly = new ScrollyMotion(timeline, stagger);

What you get:

  • ✅ Everything from timeline
  • ✅ Stagger animations ([&>li]: syntax)
  • ✅ Child element animations with delays

🎨 With Theme Support

Add dynamic theme switching based on scroll position:

import { ScrollyMotion, timeline, theme } from "@laubloch/scrolly-motion";

// Adds theme switching capabilities
const scrolly = new ScrollyMotion(timeline, theme);

What you get:

  • ✅ Everything from timeline
  • ✅ Dynamic theme switching
  • ✅ Body attribute management
  • ❌ No stagger

🧩 With Web Components

Add support for custom web component integration:

import {
  ScrollyMotion,
  timeline,
  webComponents,
} from "@laubloch/scrolly-motion";

// Adds web component progress API
const scrolly = new ScrollyMotion(timeline, webComponents);

What you get:

  • ✅ Everything from timeline
  • ✅ Web component progress() method calls
  • ✅ Custom element integration
  • ❌ No stagger

🚀 Full Featured Setup

Include all modules for maximum functionality:

import {
  ScrollyMotion,
  timeline,
  stagger,
  themes,
  webcomponents,
} from "@laubloch/scrolly-motion";

// Full-featured ScrollyMotion with all capabilities
const scrolly = new ScrollyMotion(timeline, stagger, themes, webcomponents);

What you get:

  • ✅ All features enabled
  • ✅ Maximum flexibility
  • ✅ Complete animation system

Legacy Configuration Support

The traditional configuration object is still fully supported:

import { ScrollyMotion, timeline } from "@laubloch/scrolly-motion";

const scrolly = new ScrollyMotion(timeline, {
  selector: "[data-scroll], [data-animation]",
  defaultEnter: "50vh",
  breakpoints: {
    mobile: "(max-width: 767px)",
    tablet: "(min-width: 768px) and (max-width: 1023px)",
    desktop: "(min-width: 1024px)",
  },
  presets: {
    fadeInUp: [
      { at: 0, properties: { opacity: 0, translateY: 50 } },
      { at: 1, properties: { opacity: 1, translateY: 0 } },
    ],
  },
});

Basic Usage Examples

Simple Progress Tracking (Minimal Core)

<!-- Works with minimal core -->
<div data-scroll="enter: 50vh;">
  <div
    class="progress-bar"
    style="transform: scaleX(var(--element-progress))"
  ></div>
</div>

Timeline Animations (Requires Timeline Module)

<!-- Requires timeline module -->
<div data-animation="from:opacity-0|translateY-50 to:opacity-100|translateY-0">
  Fade in from bottom
</div>

<!-- Complex timeline -->
<div data-animation="timeline:from:scale-0; via-50%:scale-1.2; to:scale-1">
  Bounce scale effect
</div>

Stagger Animations (Requires Stagger Module)

<!-- Requires stagger module -->
<div
  data-animation="[&>li]:from:opacity-0|translateY-20; to:opacity-100|translateY-0|stagger-0.1;"
>
  <ul>
    <li>Item 1 (animates first)</li>
    <li>Item 2 (animates 0.1s later)</li>
    <li>Item 3 (animates 0.2s later)</li>
  </ul>
</div>

Theme Switching (Requires Theme Module)

<!-- Requires theme module -->
<div data-scroll="theme: dark;">
  When this element is in view, body gets data-theme="dark"
</div>

Web Component Integration (Requires WebComponents Module)

<!-- Requires webComponents module -->
<div data-scroll="wc:my-progress-card;">
  <my-progress-card></my-progress-card>
</div>
// Your web component
class MyProgressCard extends HTMLElement {
  progress(value) {
    // Called automatically with scroll progress (0-1)
    this.style.setProperty("--progress", value);
  }
}

Breakpoint Animations

<!-- Different animations for different screen sizes -->
<div
  data-animation="
  @desktop:from:opacity-0|translateX-100; to:opacity-100|translateX-0;
  @mobile:from:opacity-0|translateY-20; to:opacity-100|translateY-0; 
"
>
  Mobile: slides up, Desktop: slides from right
</div>

Animation Properties

Transform Properties

  • translateX, translateY, translateZ: Movement (supports px, %, vh, vw, rem, em)
  • scale, scaleX, scaleY: Scaling (0-9999)
  • rotate, rotateX, rotateY, rotateZ: Rotation (degrees)
  • skewX, skewY: Skewing (degrees)
  • perspective: Perspective (px)

Filter and Other Properties

  • opacity: (0-100 range)
  • blur: (px)
  • grayscale: (0-100 range)
  • letter-spacing: (px)

Value Formats

Tailwind-style Values

<!-- Tailwind spacing: number * 4px -->
<div data-animation="from:translateY-12; to:translateY-0;">
  <!-- translateY: 48px to 0px -->
</div>

<!-- Tailwind opacity: number * 0.01 -->
<div data-animation="from:opacity-50; to:opacity-100;">
  <!-- opacity: 0.5 to 1.0 -->
</div>

Arbitrary Values

<!-- Custom values with units -->
<div data-animation="from:translateY-[100px]; to:translateY-[0px];">
  Custom pixel values
</div>

<div data-animation="from:translateY-[50vh]; to:translateY-[0vh];">
  Viewport height values
</div>

Configuration Options

Element Configuration (data-scroll)

<div
  data-scroll="
  enter: 50vh;        <!-- Enter offset -->
  exit: 0vh;          <!-- Exit offset -->
  distance: 200px;    <!-- Animation distance -->
  once: true;         <!-- Animate only once -->
  enterClass: fade-in;     <!-- Enter class -->
  leaveClass: fade-out;    <!-- Leave class -->
  theme: dark;        <!-- Body theme (requires theme module) -->
  wc: my-component;   <!-- Web component selector (requires webComponents module) -->
"
></div>

Advanced Features

Custom Timeline Presets

import { ScrollyMotion, timeline } from "@laubloch/scrolly-motion";

const scrolly = new ScrollyMotion(timeline, {
  presets: {
    bounceIn: [
      { at: 0, properties: { opacity: 0, scale: 0.3 } },
      { at: 0.5, properties: { opacity: 1, scale: 1.05 } },
      { at: 0.7, properties: { scale: 0.9 } },
      { at: 1, properties: { scale: 1 } },
    ],
    slideInLeft: [
      { at: 0, properties: { opacity: 0, translateX: -100 } },
      { at: 1, properties: { opacity: 1, translateX: 0 } },
    ],
  },
});
<!-- Use custom presets -->
<div data-animation="preset:bounceIn">Bounce animation</div>
<div data-animation="preset:slideInLeft">Slide from left</div>

Performance Monitoring

// Get performance metrics
const metrics = scrolly.getMetrics();
console.log("FPS:", metrics.fps);
console.log("Active elements:", metrics.activeElements);
console.log("Memory usage:", metrics.memoryUsage, "MB");

Event System

scrolly.on("elementEnter", (element) => {
  console.log("Element entered:", element);
});

scrolly.on("elementLeave", (element) => {
  console.log("Element left:", element);
});

Plugin System

ScrollyMotion has a plugin system for custom animation properties:

const bouncePlugin = {
  name: "bounceEffects",
  parse: (property, value) => {
    if (property === "bounceY") {
      const intensity = parseFloat(value) || 10;
      return intensity;
    }
    return undefined;
  },
};

// Register the plugin
scrolly.registerPlugin(bouncePlugin);
<!-- Use custom property -->
<div data-animation="from:bounceY-20|opacity-0 to:bounceY-0|opacity-100">
  Custom bounce animation
</div>

Bundle Size Comparison

| Setup | Size (minified) | Size (gzipped) | Features | | --------------- | --------------- | -------------- | ----------------------------------------- | | Minimal Core | ~15 KB | ~5 KB | Progress tracking, basic scroll detection | | + Timeline | ~25 KB | ~7 KB | + Complex animations, presets | | + Stagger | ~28 KB | ~8 KB | + Child element animations | | + Theme | ~30 KB | ~8.5 KB | + Dynamic theme switching | | + WebComponents | ~32 KB | ~9 KB | + Web component integration | | Full Featured | ~35 KB | ~9.5 KB | All features |

Browser Support

  • Chrome 51+
  • Firefox 55+
  • Safari 12.1+
  • Edge 79+