A high-performance, zero-dependency animation library for React/Next.js and Svelte with TypeScript support. Create smooth scroll-triggered animations with minimal setup.
npm install animate-on-view
# or
yarn add animate-on-view
# or
pnpm add animate-on-view
import { AnimateOnView } from 'animate-on-view/react';
function App() {
return (
<div>
<AnimateOnView type="fadeIn">
<h1>Hello World!</h1>
</AnimateOnView>
<AnimateOnView type="slideUp" duration={800} delay={200}>
<p>This text slides up with custom timing</p>
</AnimateOnView>
</div>
);
}
<script>
import { AnimateOnView } from 'animate-on-view/svelte';
</script>
<AnimateOnView type="fadeIn">
<h1>Hello World!</h1>
</AnimateOnView>
<AnimateOnView type="slideUp" duration={800} delay={200}>
<p>This text slides up with custom timing</p>
</AnimateOnView>
fadeIn - Simple fade infadeInUp - Fade in from bottomfadeInDown - Fade in from topfadeInLeft - Fade in from leftfadeInRight - Fade in from rightslideUp - Slide up from bottomslideDown - Slide down from topslideLeft - Slide from right to leftslideRight - Slide from left to rightscaleIn - Scale from small to normalscaleOut - Scale from large to normalscaleX - Scale horizontallyscaleY - Scale verticallyrotateIn - Rotate and scale inrotateInLeft - Rotate from leftrotateInRight - Rotate from rightflipX - Flip horizontallyflipY - Flip verticallyzoomIn - Zoom in effectzoomInUp - Zoom in from bottomzoomInDown - Zoom in from topzoomInLeft - Zoom in from leftzoomInRight - Zoom in from rightbounceIn - Bounce scale effectbounceInUp - Bounce from bottombounceInDown - Bounce from topbounceInLeft - Bounce from leftbounceInRight - Bounce from rightelasticIn - Elastic scale effectelasticInUp - Elastic from bottomelasticInDown - Elastic from topblurIn - Blur to clearblurInUp - Blur and slide upskewIn - Skew effectskewInUp - Skew and slide uprollIn - Roll in effectlightSpeedIn - Light speed effectjackInTheBox - Jack in the box effectgentle - Gentle fade and movesoft - Soft scale effectsmooth - Smooth slide effectdramatic - Dramatic rotate and scaleexplosive - Explosive scale and rotate| Prop | Type | Default | Description |
|---|---|---|---|
type |
AnimationType |
'fadeIn' |
Animation type to use |
variant |
AnimationVariant |
- | Custom animation variant |
threshold |
number |
0.1 |
Intersection threshold (0-1) |
rootMargin |
string |
'0px' |
Root margin for intersection |
triggerOnce |
boolean |
true |
Trigger animation only once |
duration |
number |
600 |
Animation duration in ms |
delay |
number |
0 |
Animation delay in ms |
easing |
string |
'ease-out' |
CSS easing function |
className |
string |
- | CSS class name |
style |
object/string |
- | Inline styles |
onInView |
function |
- | Callback when element enters view |
onOutView |
function |
- | Callback when element exits view |
Create your own animation variants:
// React
const customVariant = {
initial: {
opacity: 0,
transform: 'translateY(100px) rotate(45deg)'
},
animate: {
opacity: 1,
transform: 'translateY(0px) rotate(0deg)'
},
transition: {
duration: 1000,
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)'
}
};
<AnimateOnView variant={customVariant}>
<div>Custom animation!</div>
</AnimateOnView>
<!-- Svelte -->
<script>
const customVariant = {
initial: {
opacity: 0,
transform: 'translateY(100px) rotate(45deg)'
},
animate: {
opacity: 1,
transform: 'translateY(0px) rotate(0deg)'
},
transition: {
duration: 1000,
easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)'
}
};
</script>
<AnimateOnView variant={customVariant}>
<div>Custom animation!</div>
</AnimateOnView>
Use pre-built animated elements with the animate object:
import { animate } from 'animate-on-view/react';
function App() {
return (
<div>
{/* Basic usage */}
<animate.div type="fadeIn">
<h1>Hello World!</h1>
</animate.div>
<animate.p type="slideUp" delay={200}>
This slides up with a 200ms delay
</animate.p>
<animate.img
type="scaleIn"
src="image.jpg"
alt="Animated image"
/>
{/* Self-closing elements work perfectly */}
<animate.input
type="fadeIn"
placeholder="Animated input"
className="form-control"
/>
{/* Advanced usage with all props */}
<animate.h1
type="fadeInUp"
duration={800}
delay={100}
threshold={0.3}
>
Animated Heading
</animate.h1>
<animate.section
type="slideLeft"
className="my-section"
style={{ padding: '20px' }}
>
<p>Animated Section Content</p>
</animate.section>
{/* Custom styling */}
<animate.button
type="bounceIn"
delay={500}
onClick={() => alert('Clicked!')}
className="btn btn-primary"
>
Animated Button
</animate.button>
</div>
);
}
Available animated elements:
h1, h2, h3, h4, h5, h6, p, spandiv, section, article, aside, header, footer, main, navul, ol, liimgKey Benefits:
onClick, onMouseOver, etc.)Use pre-built animated components with all the same animation types as React:
<script>
import { AnimateH1, AnimateP, AnimateDiv } from 'animate-on-view/svelte';
</script>
{/* All 40+ animation types are available */}
<AnimateH1 type="fadeInUp">Animated Heading</AnimateH1>
<AnimateP type="slideLeft" delay={200}>Animated Paragraph</AnimateP>
<AnimateDiv type="scaleIn" duration={1000}>Animated Div</AnimateDiv>
{/* Advanced animations */}
<AnimateH1 type="bounceInDown" duration={800}>Bouncy Title</AnimateH1>
<AnimateP type="blurInUp" delay={300}>Blur Effect Text</AnimateP>
<AnimateDiv type="jackInTheBox" delay={500}>Surprise Box</AnimateDiv>
{/* Dramatic effects */}
<AnimateH1 type="dramatic">Dramatic Entrance</AnimateH1>
<AnimateP type="lightSpeedIn">Lightning Fast</AnimateP>
Available Components:
AnimateH1, AnimateH2 - Animated headingsAnimateP - Animated paragraphs AnimateDiv - Animated containersAnimateOnView - Base component for custom elementsAll Animation Types Supported: Svelte now supports all 40+ animation types available in React, including fadeIn, slideUp, bounceIn, dramatic, explosive, and many more!
Fine-tune when animations trigger:
<AnimateOnView
type="fadeIn"
threshold={0.5} // Trigger when 50% visible
rootMargin="100px" // Trigger 100px before entering viewport
triggerOnce={false} // Re-trigger when scrolling back
>
<div>Content</div>
</AnimateOnView>
Handle animation events:
<AnimateOnView
type="slideUp"
onInView={() => console.log('Element entered view!')}
onOutView={() => console.log('Element left view!')}
>
<div>Content with callbacks</div>
</AnimateOnView>
triggerOnce={true} (default) for better performancethreshold based on your needs (lower values trigger earlier)rootMargin to pre-load animations before they're visibleUses Intersection Observer API with automatic fallback for older browsers.
Full TypeScript support with comprehensive type definitions:
import type { AnimateProps, AnimationVariant } from 'animate-on-view/react';
const MyComponent: React.FC<AnimateProps> = (props) => {
// Your component logic
};
const items = ['Item 1', 'Item 2', 'Item 3'];
return (
<div>
{items.map((item, index) => (
<AnimateOnView
key={item}
type="slideUp"
delay={index * 100}
>
<div>{item}</div>
</AnimateOnView>
))}
</div>
);
<div>
<AnimateOnView type="fadeInDown" duration={600}>
<h1>Welcome</h1>
</AnimateOnView>
<AnimateOnView type="slideUp" delay={300} duration={800}>
<p>This is a subtitle that appears after the title</p>
</AnimateOnView>
<AnimateOnView type="scaleIn" delay={600} duration={1000}>
<button>Get Started</button>
</AnimateOnView>
</div>
Contributions are welcome! Please feel free to submit a Pull Request.
MIT Ā© 2025 denisetiya