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 rotateProp | 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
, span
div
, section
, article
, aside
, header
, footer
, main
, nav
ul
, ol
, li
img
Key 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