mirror of
https://github.com/hanzoai/gui.git
synced 2026-11-03 00:13:54 +00:00
4.5 KiB
4.5 KiB
Animations Reference
Animation Drivers
Gui supports multiple animation drivers. Choose based on your platform:
| Driver | Package | Best For |
|---|---|---|
| CSS | @hanzogui/animations-css |
Web-only apps, smallest bundle |
| React Native | @hanzogui/animations-react-native |
Native apps, basic animations |
| Reanimated | @hanzogui/animations-reanimated |
Native apps, best performance |
| Motion | @hanzogui/animations-motion |
Cross-platform spring physics |
Configuration
// v5 config - import driver separately
import { defaultConfig } from '@hanzogui/config/v5'
import { animations } from '@hanzogui/config/v5-css'
// or: '@hanzogui/config/v5-motion'
// or: '@hanzogui/config/v5-rn'
// or: '@hanzogui/config/v5-reanimated'
export const config = createGui({
...defaultConfig,
animations,
})
Defining Animations
CSS Driver
Uses CSS transition strings:
import { createAnimations } from '@hanzogui/animations-css'
const animations = createAnimations({
fast: 'ease-in 150ms',
medium: 'ease-in-out 300ms',
slow: 'ease-out 500ms',
bouncy: 'cubic-bezier(0.68, -0.55, 0.265, 1.55) 400ms',
})
Spring-Based Drivers (RN, Reanimated, Motion)
Use spring physics config:
import { createAnimations } from '@hanzogui/animations-react-native'
const animations = createAnimations({
fast: {
type: 'spring',
damping: 20,
stiffness: 300,
},
medium: {
type: 'spring',
damping: 15,
stiffness: 200,
},
bouncy: {
type: 'spring',
damping: 8,
mass: 0.8,
stiffness: 100,
},
})
Using Animations
Basic Animation
<View animation="medium" opacity={isVisible ? 1 : 0} y={isVisible ? 0 : 10} />
Enter/Exit Styles
<View
animation="fast"
enterStyle={{
opacity: 0,
y: -20,
scale: 0.9,
}}
exitStyle={{
opacity: 0,
y: 20,
scale: 0.9,
}}
opacity={1}
y={0}
scale={1}
/>
AnimatePresence (Required for Exit)
Exit animations only work inside AnimatePresence:
import { AnimatePresence } from '@hanzo/gui'
;<AnimatePresence>
{show && (
<View
key="unique-key" // key is required
animation="medium"
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
opacity={1}
/>
)}
</AnimatePresence>
Per-Property Animation
Override animation for specific properties:
<View
animation={[
'fast',
{
opacity: { type: 'timing', duration: 500 },
scale: { overshootClamping: true },
},
]}
opacity={1}
scale={1}
/>
Animatable Properties
Common animatable style properties:
opacityx,y(translateX/Y)scale,scaleX,scaleYrotate,rotateX,rotateY,rotateZwidth,heightbackgroundColorborderColorborderRadius
Hover/Press States
State-based animations:
<Button
animation="fast"
hoverStyle={{
scale: 1.05,
backgroundColor: '$blue9',
}}
pressStyle={{
scale: 0.95,
backgroundColor: '$blue11',
}}
/>
Animation with Variants
const AnimatedCard = styled(View, {
animation: 'medium',
variants: {
visible: {
true: {
opacity: 1,
y: 0,
},
false: {
opacity: 0,
y: 20,
},
},
} as const,
})
<AnimatedCard visible={isVisible} />
Common Patterns
Fade In
<View animation="medium" enterStyle={{ opacity: 0 }} opacity={1} />
Slide Up
<View animation="fast" enterStyle={{ opacity: 0, y: 20 }} opacity={1} y={0} />
Scale In
<View animation="bouncy" enterStyle={{ opacity: 0, scale: 0.8 }} opacity={1} scale={1} />
Modal Overlay
<Dialog.Overlay
animation="fast"
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
opacity={0.5}
/>
Modal Content
<Dialog.Content
animation={['medium', { opacity: { overshootClamping: true } }]}
enterStyle={{ opacity: 0, y: -20, scale: 0.95 }}
exitStyle={{ opacity: 0, y: 10, scale: 0.98 }}
opacity={1}
y={0}
scale={1}
/>
Tips
- Always provide key in AnimatePresence children
- Set final values on the component, not just in enterStyle
- Use overshootClamping for opacity to prevent negative values
- CSS driver doesn't support spring physics - use easing strings
- Test on device - animation feel differs between web and native