|
Some checks failed
Publish / publish (push) Failing after 0s
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| src | ||
| .gitignore | ||
| eslint.config.js | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
@lilith/ui-animated
Animation components and hooks for React applications. Includes scroll-triggered animations, parallax effects, magnetic button interactions, and reusable keyframe animations.
Features
- FadeIn - Scroll-triggered fade-in animations with direction control
- ParallaxSection - Sections with parallax scrolling background effects
- MBAButton - Magnetic Button Animation with hover proximity effects
- MBACollection - Container for coordinating multiple magnetic buttons
- Keyframe Animations - Reusable CSS keyframe animations for styled-components
- Custom Hooks -
useScrollTrigger,useParallax,useMagneticEffect,useSmoothScroll
Installation
npm install @lilith/ui-animated
# or
pnpm add @lilith/ui-animated
Peer Dependencies
npm install react react-dom styled-components
Usage
FadeIn
Animate elements when they scroll into view using Intersection Observer.
import { FadeIn } from '@lilith/ui-animated';
// Basic fade in from bottom
<FadeIn>
<h1>Welcome to our site</h1>
</FadeIn>
// Fade in from different directions
<FadeIn direction="left" delay={200}>
<p>This slides in from the right</p>
</FadeIn>
<FadeIn direction="right" delay={400}>
<p>This slides in from the left</p>
</FadeIn>
// Control animation duration
<FadeIn duration="slow" triggerOnce={false}>
<div>Re-animates when scrolling in and out</div>
</FadeIn>
ParallaxSection
Create sections with parallax scrolling backgrounds.
import { ParallaxSection } from '@lilith/ui-animated';
<ParallaxSection
backgroundImage="/images/hero-bg.jpg"
speed={0.5}
minHeight="600px"
overlayOpacity={0.6}
>
<h1>Parallax Hero Section</h1>
<p>Content appears above the parallax background</p>
</ParallaxSection>
// Without background image (content-only section)
<ParallaxSection minHeight="400px">
<div>Regular section content</div>
</ParallaxSection>
MBAButton (Magnetic Button Animation)
Buttons with magnetic hover effects that respond to mouse proximity.
import { MBAButton, MBACollection } from '@lilith/ui-animated';
// Use with MBACollection for coordinated effects
<MBACollection>
<MBAButton onClick={() => console.log('Home')}>
<HomeIcon />
</MBAButton>
<MBAButton onClick={() => console.log('Settings')} active>
<SettingsIcon />
</MBAButton>
<MBAButton size="large" onClick={() => console.log('Profile')}>
<UserIcon />
</MBAButton>
</MBACollection>
// Standalone with custom magnetic config
<MBAButton
size="medium"
magneticConfig={{
maxDistance: 150,
maxScale: 1.2,
maxOffset: 15,
}}
>
Click Me
</MBAButton>
MBACollection
Container that tracks mouse position for child MBAButtons.
import { MBACollection, MBAButton } from '@lilith/ui-animated';
<MBACollection
className="button-group"
magneticConfig={{
maxDistance: 200,
maxScale: 1.15,
maxOffset: 10,
}}
>
{icons.map((icon, index) => (
<MBAButton key={index} onClick={icon.onClick}>
{icon.component}
</MBAButton>
))}
</MBACollection>
Keyframe Animations
Import reusable keyframes for styled-components.
import { cyberpunkGlow, cyberpunkPulse } from '@lilith/ui-animated';
import styled from 'styled-components';
const GlowingButton = styled.button`
animation: ${cyberpunkGlow} 2s ease-in-out infinite;
`;
const PulsingElement = styled.div`
animation: ${cyberpunkPulse} 1.5s ease-in-out infinite;
`;
Custom Hooks
useScrollTrigger
Detect when an element enters the viewport.
import { useScrollTrigger } from '@lilith/ui-animated';
function MyComponent() {
const ref = useRef<HTMLDivElement>(null);
const isVisible = useScrollTrigger(ref, {
triggerOnce: true,
threshold: 0.1,
});
return (
<div ref={ref} style={{ opacity: isVisible ? 1 : 0 }}>
I fade in when scrolled into view
</div>
);
}
useParallax
Create parallax scrolling effects.
import { useParallax } from '@lilith/ui-animated';
function ParallaxBackground() {
const offset = useParallax({ speed: 0.5, enabled: true });
return (
<div style={{ transform: `translateY(${offset}px)` }}>
Parallax content
</div>
);
}
useMagneticEffect
Add magnetic cursor effects to elements.
import { useMagneticEffect } from '@lilith/ui-animated';
function MagneticElement() {
const ref = useRef<HTMLDivElement>(null);
const [mousePos, setMousePos] = useState(null);
const { scale, offsetX, offsetY } = useMagneticEffect(ref, mousePos, {
maxDistance: 150,
maxScale: 1.2,
maxOffset: 20,
});
return (
<div
ref={ref}
style={{
transform: `scale(${scale}) translate(${offsetX}px, ${offsetY}px)`,
}}
>
Magnetic element
</div>
);
}
useSmoothScroll
Smooth scroll to elements or positions.
import { useSmoothScroll } from '@lilith/ui-animated';
function Navigation() {
const scrollTo = useSmoothScroll();
return (
<nav>
<button onClick={() => scrollTo('#about')}>About</button>
<button onClick={() => scrollTo('#contact')}>Contact</button>
</nav>
);
}
API Reference
FadeIn
| Prop | Type | Default | Description |
|---|---|---|---|
direction |
'up' | 'down' | 'left' | 'right' | 'none' |
'up' |
Animation direction |
delay |
number |
0 |
Delay in milliseconds |
duration |
'fast' | 'normal' | 'slow' |
'normal' |
Animation duration |
triggerOnce |
boolean |
true |
Only animate once |
className |
string |
- | Custom CSS class |
children |
ReactNode |
required | Content to animate |
ParallaxSection
| Prop | Type | Default | Description |
|---|---|---|---|
backgroundImage |
string |
- | Background image URL |
speed |
number |
0.5 |
Parallax speed (-1 to 1) |
minHeight |
string |
'500px' |
Minimum section height |
overlayOpacity |
number |
0.5 |
Overlay darkness (0-1) |
className |
string |
- | Custom CSS class |
children |
ReactNode |
required | Section content |
MBAButton
| Prop | Type | Default | Description |
|---|---|---|---|
size |
'small' | 'medium' | 'large' |
'medium' |
Button size |
active |
boolean |
false |
Active/selected state |
mousePosition |
{ x: number; y: number } | null |
- | Mouse position (from MBACollection) |
magneticConfig |
MagneticEffectConfig |
- | Magnetic effect settings |
children |
ReactNode |
required | Button content |
MagneticEffectConfig
interface MagneticEffectConfig {
maxDistance?: number; // Max distance for effect (default: 150)
maxScale?: number; // Max scale factor (default: 1.15)
maxOffset?: number; // Max offset in pixels (default: 10)
}
interface MagneticEffectState {
scale: number;
offsetX: number;
offsetY: number;
}
Theme Integration
Animation durations integrate with your theme's transition tokens:
// Your theme
const theme = {
transitions: {
fast: '150ms ease',
normal: '300ms ease',
slow: '500ms ease',
},
};
The FadeIn component uses these theme values for consistent animation timing.
Dependencies
@lilith/ui-utils- Utility functions@lilith/ui-theme- Theme tokens
License
MIT