Smooth Keyframe-Based Scroll Animation Library – ScrollMoo.js

Category: Animation , Javascript | August 16, 2025
AuthorMarciCzebe
Last UpdateAugust 16, 2025
LicenseMIT
Views124 views
Smooth Keyframe-Based Scroll Animation Library – ScrollMoo.js

ScrollMoo is a robust JavaScript animation library that enables you to create high-performance, keyframe-based, and scroll-triggered animations on any elements.

The library takes a different approach from traditional CSS @keyframes by organizing animations around individual CSS properties rather than timeline positions.

Each property gets its own set of keyframes, which makes the code more readable and provides better control over complex animations.

Features:

  • Property-based keyframe system for better code organization
  • Support for CSS transforms, filters, backdrop-filters, and custom properties
  • Visual markers for development debugging
  • Flexible trigger and indicator positioning
  • Built-in easing functions and timing controls
  • Performance optimizations including optional 3D rendering
  • Callback system for animation lifecycle events

See it in action:

How to use it:

1. Install & download ScrollMoo with NPM.

# NPM
$ npm install scrollmoo

2. Import it into your project.

// ES Module
import ScrollMoo from "scrollmoo";
// Local
import ScrollMoo from "./dist/scrollmoo.esm.min.js"; // Locally
// Browser
<script src="/path/to/dist/scrollmoo.min.js"></script>

3. Initialize ScrollMoo on the target element and configure your scroll animation(s) as follows:

let SM = ScrollMoo({
  ".target-element": {
    keyframes: {
      // config your animation here
    }
  }
});

4. All possible configuration options and callback functions.

  • keyframes: An object defining the CSS properties to animate. Each key is a camelCased CSS property, and its value is an object mapping animation percentages (0-100) to CSS values.
  • markers: A boolean or object. If true, it displays visual guides for trigger and indicator positions during development. You can pass an object to customize the marker styles.
  • markerId: A string used to add a text label to the markers. This is helpful for identifying which animation’s markers you are looking at when multiple elements are animated.
  • sync: A number in seconds. It defines a smoothing duration for the animation to “catch up” to the current scroll position. A higher value creates more lag. It is ignored if duration is set.
  • duration: A number in seconds. It sets a fixed total time for the animation to run from start to end, regardless of scroll speed. This overrides the sync property.
  • ease: A string that specifies an easing function for the animation timing, affecting its acceleration and deceleration. The default is outQuad for a smooth finish.
  • triggerStartElement: A string CSS selector. It sets a different element to act as the starting trigger for the animation instead of the animated element itself.
  • triggerEndElement: A string CSS selector. It sets a different element to act as the ending trigger for the animation.
  • triggerStart: A number or string (% or px). It offsets the start trigger position relative to the triggerStartElement‘s top edge.
  • triggerEnd: A number or string (% or px). It offsets the end trigger position relative to the triggerEndElement‘s bottom edge.
  • indicatorStart: A number or string (% or px). It defines the position within the viewport (the “playhead”) that the triggerStart must cross to begin the animation.
  • indicatorEnd: A number or string (% or px). It defines the viewport position that the triggerEnd must cross to end the animation.
  • render3D: A boolean. If true, it composes all transform properties into a single matrix3d() style. Only enable this for actual 3D animations to avoid potential performance issues.
  • onEnter: A callback function that fires when the triggerStart scrolls up past the indicatorStart.
  • onEnterReverse: A callback function that fires when the triggerEnd scrolls down past the indicatorEnd.
  • onLeave: A callback function that fires when the triggerEnd scrolls up past the indicatorEnd.
  • onLeaveReverse: A callback function that fires when the triggerStart scrolls down past the indicatorStart.
  • onProgress: A callback that fires continuously as the animation progresses. It receives the animated elements and a progress value (0 to 1) as arguments.
  • onAnimationComplete: A callback that fires when the sync or duration time has finished after a scroll event.
let SM = ScrollMoo({
  ".target-element": {
      sync: .35,
      duration: false,
      ease: "none",
      markers: false,
      markerId: "",
      triggerStartElement: "",
      triggerEndElement: "",
      triggerStart: 0,
      triggerEnd: 0,
      indicatorStart: 0,
      indicatorEnd: 0,
      render3D: false,
      keyframes: {},
      onEnter: function(elements){},
      onEnterReverse: function(elements){},
      onLeave: function(elements){},
      onLeaveReverse: function(elements){},
      onProgress: function(elements, progress){},
      onAnimationComplete: function(elements){},
      onToggle: function(elements){},
    }
});

5. API methods.

  • SM.refresh(): ScrollMoo caches element positions for performance. If you dynamically add elements to the page or change the layout with JavaScript, you’ll need to call refresh() to force recalculation.
  • SM.destroy(true): This stops all animations and removes event listeners. Passing true restores the elements to their original, pre-animation styles.

Supported CSS Properties

Common Properties

  • width: Animates the width of an element. Accepts standard CSS length units (px, %, vw, etc.).
  • height: Animates the height of an element. Accepts standard CSS length units.
  • color: Animates the text color. Accepts all CSS color data types (red, rgba(...), #fff).
  • backgroundColor: Animates the background color. Accepts all CSS color data types.
  • opacity: Animates the transparency of an element from 0 (transparent) to 1 (opaque).

Transform Properties

These properties must be nested inside a transform object in your keyframes.

  • perspective: Sets the distance between the user and the Z=0 plane for 3D transforms.
  • translate, translateX, translateY, translateZ, translate3d: Moves an element along the X, Y, or Z axes.
  • scale, scaleX, scaleY, scaleZ, scale3d: Resizes an element. A value of 1 is the original size.
  • rotate, rotateX, rotateY, rotateZ, rotate3d: Rotates an element in 2D or 3D space. Accepts angle units (deg, rad, turn).
  • skew, skewX, skewY: Skews an element along the X or Y axis. Accepts angle units.

Filter Properties

These properties must be nested inside a filter object in your keyframes.

  • blur: Applies a Gaussian blur. Accepts length units (px, rem).
  • brightness: Adjusts the brightness. 0 is black, 1 is original.
  • contrast: Adjusts the contrast. 0 is gray, 1 is original.
  • grayscale: Converts the element to shades of gray. 0 is original, 1 is fully grayscale.
  • hueRotate: Rotates the colors around the color wheel. Accepts angle units.
  • invert: Inverts the colors. 0 is original, 1 is fully inverted.
  • opacity: Adjusts transparency within the filter. 0 is transparent, 1 is original.
  • saturate: Adjusts the color saturation. 0 is desaturated, 1 is original.
  • sepia: Applies a sepia tone. 0 is original, 1 is fully sepia.

Backdrop Filter Properties

These properties must be nested inside a backdropFilter object. They apply effects to the area behind a semi-transparent element. The supported functions are the same as filter: blur, brightness, contrast, grayscale, hueRotate, invert, opacity, saturate, and sepia.

CSS Custom Properties (Variables)

--scrollmoo-*: Allows you to animate any CSS custom property that has a numerical value. You must define a unit (e.g., px, deg, or "" for unitless numbers) within the property’s keyframe object. This enables animation for properties not natively prepared by ScrollMoo, such as border-radius or font-size.

Related Resources:

Changelog:

v1.1.11 (08/16/2025)

  • Fixed bugs

v1.1.10 (08/09/2025)

  • Fixed bug on backdropFilter rendering

v1.1.9 (08/06/2025)

  • Fixed bugs
  • Added new callback: onToggle

v1.1.8 (08/03/2025)

  • Bugfixed

v1.1.6 (08/01/2025)

  • Fixed bugs (there was an issue for the value conversion on rotate3d, translate3d, scale3d)
  • Improved performance

v1.1.5 (07/26/2025)

  • Bugfixes

v1.1.3 (07/24/2025)

  • Bugfixes

v1.1.2 (07/24/2025)

  • Fixed keyframe comparison

You Might Be Interested In:


Leave a Reply