@proto-cool/cascade
A lightweight TypeScript library for easily defining smooth, performant animations when elements enter the viewport.
Features
- 🚀 Zero Configuration - Add a single data attribute to any element and it animates when scrolled into view
- ⚡ Performant - Built on the Motion animation library with optimized viewport detection
- 🎨 Versatile - Multiple animation types including fade, slide, scale, and custom spring physics
- 🔧 Customizable - Configure animations globally or per-element using data attributes
- 📱 Responsive - Works perfectly across all device sizes
- ♿ Accessible - Includes fallbacks for users with JavaScript disabled
- 🧩 Modular - Use only what you need, minimal bundle size
Installation
# Using pnpm (recommended)
pnpm add @proto-cool/cascade
# Using npm
npm install @proto-cool/cascade
# Using yarn
yarn add @proto-cool/cascade
Quick Start
- Import and enable the library:
//Import the CSS to have items invisible by default
import "@proto-cool/cascade/cascade.css";
// Import the `cascade` object for access to enable() and noscript
import cascade from "@proto-cool/cascade";
// Initialize Cascade with default settings
cascade.enable();
- Add the data attribute to any HTML element:
<!-- Basic fade animation when element enters viewport -->
<div data-cascade="fadeIn">I'll fade in when visible</div>
<!-- Slide animation with custom delay -->
<div data-cascade="fadeInUp" data-cascade-delay="0.5">
I'll fade in, sliding upwards, after a delay of half a second
</div>
- Add noscript fallback for accessibility:
Add this to your HTML <head>
for users with JavaScript disabled:
<!-- Copy this noscript tag to your head section -->
<noscript>
<style>
/* Show all elements with data-cascade attribute when JS is disabled */
[data-cascade] {
opacity: 1 !important;
}
</style>
</noscript>
<!-- Or use the provided noscript string: -->
<head>
<!-- your other head content -->
<script>
document.write(cascade.noscript);
</script>
</head>
Configuration
Global Configuration
Customize the default behavior for all animations:
cascade.enable({
// Animation timing defaults
duration: 0.8, // Animation duration in seconds
delay: 0, // Delay before animation starts
// Animation type default
type: "spring", // 'spring' | 'tween' | 'keyframes' | 'decay' | 'inertia'
// Intersection observer defaults
margin: "0px", // Root margin (e.g. '50px' or '10% 20px')
amount: 0.2, // Trigger when 20% visible (0-1, 'some', or 'all')
// Spring physics defaults (when type = 'spring')
bounce: 0.25, // Spring bounciness
damping: 10, // Spring damping
stiffness: 100, // Spring stiffness
// Tween easing defaults (when type = 'tween')
ease: "easeInOut", // Easing function
// Animation repeat defaults
repeat: 0, // Number of repeats (0 = no repeat)
repeatType: "loop", // 'loop' | 'reverse' | 'mirror'
repeatDelay: 0, // Delay between repeats
});
Per-Element Configuration
Override settings on individual elements using data attributes:
<div
data-cascade="bounceIn"
data-cascade-duration="1.2"
data-cascade-delay="0.3"
data-cascade-bounce="0.4"
data-cascade-ease="easeInOut"
>
Customized animation
</div>
Available Animations
This package offers a variety of ready-to-use animation presets designed for common UI effects.
Below is a summary of each animation and what it does:
Name | Description |
---|---|
fadeIn | Fades in an element from transparent to visible. |
fadeInZoom | Fades in while zooming in from 80% to full size. |
fadeInUp | Fades in while moving upward into place. |
fadeInDown | Fades in while moving downward into place. |
fadeInLeft | Fades in while moving in from the right. |
fadeInRight | Fades in while moving in from the left. |
fadeOut | Fades out an element from visible to transparent. |
fadeOutZoom | Fades out while shrinking (zooming out to 70%). |
fadeOutUp | Fades out while moving upward out of view. |
fadeOutDown | Fades out while moving downward out of view. |
fadeOutLeft | Fades out while moving leftward out of view. |
fadeOutRight | Fades out while moving rightward out of view. |
bounceIn | Bounces in, scaling up and settling to full size. |
bounceOut | Bounces out, expanding slightly then shrinking away. |
flipIn | Flips in along the Y axis, rotating from 90° to 0°. |
flipOut | Flips out along the Y axis, rotating from 0° to 90°. |
rotateIn | Rotates in, spinning from -180° to 0° while fading in. |
rotateOut | Rotates out, spinning from 0° to 180° while fading out. |
Example usage:
<div data-cascade="fadeIn">Fade in</div>
<div data-cascade="fadeInZoom">Zoom in</div>
<div data-cascade="FadeInUp">Slide up in</div>
<div data-cascade="flipIn">Flip in</div>
<div data-cascade="bounceIn">Bounce in</div>
Advanced Usage
Custom Intersection Margins
Adjust when animations trigger relative to the viewport:
<!-- Animation starts when element is 100px away from entering viewport -->
<div data-cascade="fadeIn" data-cascade-margin="100px"></div>
<!-- Different margins for each side (top, right, bottom, left) -->
<div data-cascade="fadeIn" data-cascade-margin="50px 0px 0px 0px"></div>
Animation Amount Threshold
Control how much of the element must be visible to trigger the animation:
<!-- Trigger when 50% of element is visible -->
<div data-cascade="fadeIn" data-cascade-amount="0.5"></div>
<!-- Trigger when any part of element is visible -->
<div data-cascade="fadeIn" data-cascade-amount="some"></div>
<!-- Trigger when element is fully visible -->
<div data-cascade="FadeIn" data-cascade-amount="all"></div>
Custom Animation Physics
Fine-tune spring animations with custom physics parameters:
<!-- Extra bouncy spring animation -->
<div
data-cascade="bounceIn"
data-cascade-bounce="0.8"
data-cascade-stiffness="200"
data-cascade-damping="5"
>
Bouncy content
</div>
Browser Support
Cascade works in all modern browsers that support the Intersection Observer API (Chrome, Firefox, Safari, Edge).
Development
# Install dependencies
pnpm install
# Build the library
pnpm run build
# Format code with Prettier
pnpm run format
TypeScript Support
Cascade is written in TypeScript and includes full type definitions:
import cascade from "@proto-cool/cascade";
import type { AnimationOptions } from "@proto-cool/cascade";
const options: Partial<AnimationOptions> = {
duration: 1.2,
type: "spring",
bounce: 0.3,
};
cascade.enable(options);
License
MIT © protocol7