Functions for defining CSS styles and timing parameters that control how animations appear and behave.
Defines CSS property-value pairs for use in animations.
/**
* Defines CSS styles for animations
* @param tokens - CSS properties as object, wildcard '*', or array of styles
* @returns AnimationStyleMetadata for use in animation steps
*/
function style(
tokens: '*' | { [key: string]: string | number } | Array<'*' | { [key: string]: string | number }>
): AnimationStyleMetadata;
interface AnimationStyleMetadata extends AnimationMetadata {
styles: '*' | { [key: string]: string | number } | Array<'*' | { [key: string]: string | number }>;
offset: number | null;
}Usage Examples:
import { style } from '@angular/animations';
// Basic CSS styles
const basicStyle = style({
opacity: 1,
transform: 'translateX(0)',
backgroundColor: 'blue'
});
// Numeric values (pixels assumed for layout properties)
const numericStyle = style({
width: 200,
height: 100,
fontSize: 16
});
// Wildcard/AUTO_STYLE - use computed styles
const autoStyle = style({
height: '*', // Use current computed height
width: '*' // Use current computed width
});
// Array of styles for keyframes
const multiStyle = style([
{ offset: 0, opacity: 0 },
{ offset: 0.5, opacity: 0.5 },
{ offset: 1, opacity: 1 }
]);Defines an animation step combining timing and style information.
/**
* Defines animation step with timing and styling
* @param timings - Duration, delay, and easing as string or number
* @param styles - Optional target styles or keyframes
* @returns AnimationAnimateMetadata for the animation step
*/
function animate(
timings: string | number,
styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata | null
): AnimationAnimateMetadata;
interface AnimationAnimateMetadata extends AnimationMetadata {
timings: string | number;
styles: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata | null;
}Timing Formats:
300 - Duration in milliseconds'300ms' - Duration with unit'300ms 100ms' - Duration and delay'300ms 100ms ease-in' - Duration, delay, and easing'300ms ease-out' - Duration and easing (no delay)Usage Examples:
import { animate, style } from '@angular/animations';
// Simple duration only
const simpleAnimate = animate(300);
// Duration with target style
const animateWithStyle = animate('300ms', style({ opacity: 0 }));
// Full timing specification
const fullTiming = animate('300ms 100ms ease-in-out', style({
transform: 'translateX(100px)',
opacity: 0.5
}));
// Complex easing functions
const customEasing = animate('500ms cubic-bezier(0.25, 0.46, 0.45, 0.94)',
style({ transform: 'scale(1.2)' })
);Defines multi-step animations with precise timing control.
/**
* Creates keyframe-based animation sequence
* @param steps - Array of style metadata for each keyframe
* @returns AnimationKeyframesSequenceMetadata for keyframe animation
*/
function keyframes(steps: AnimationStyleMetadata[]): AnimationKeyframesSequenceMetadata;
interface AnimationKeyframesSequenceMetadata extends AnimationMetadata {
steps: AnimationStyleMetadata[];
}Usage Examples:
import { keyframes, style, animate } from '@angular/animations';
// Basic keyframe animation
const pulseKeyframes = keyframes([
style({ transform: 'scale(1)', offset: 0 }),
style({ transform: 'scale(1.2)', offset: 0.5 }),
style({ transform: 'scale(1)', offset: 1 })
]);
// Complex keyframe sequence
const complexKeyframes = keyframes([
style({
opacity: 0,
transform: 'translateX(-100%) rotate(0deg)',
offset: 0
}),
style({
opacity: 0.5,
transform: 'translateX(0) rotate(180deg)',
offset: 0.3
}),
style({
opacity: 1,
transform: 'translateX(50px) rotate(360deg)',
offset: 1
})
]);
// Use with animate
const keyframeAnimation = animate('1s ease-in-out', complexKeyframes);Wildcard value for using computed CSS styles.
/**
* Constant representing automatic/computed styling
* Equivalent to '*' - uses the element's current computed styles
*/
const AUTO_STYLE = '*';Usage Examples:
import { AUTO_STYLE, style, animate } from '@angular/animations';
// Animate from current computed height to 0
const collapseAnimation = animate('300ms', style({
height: 0,
opacity: 0
}));
// Animate from 0 to computed height
const expandAnimation = [
style({ height: 0, opacity: 0 }),
animate('300ms', style({
height: AUTO_STYLE, // Use computed height
opacity: 1
}))
];// Milliseconds (number)
animate(300)
animate(1500)
// String with units
animate('300ms')
animate('1.5s')
animate('0.3s')// Duration and delay
animate('300ms 100ms') // 300ms duration, 100ms delay
animate('1s 500ms') // 1s duration, 500ms delay// Built-in easing
animate('300ms ease-in')
animate('300ms ease-out')
animate('300ms ease-in-out')
animate('300ms linear')
// Cubic bezier curves
animate('300ms cubic-bezier(0.25, 0.46, 0.45, 0.94)')
animate('500ms cubic-bezier(0.68, -0.55, 0.265, 1.55)') // Back easing
// Steps function for discrete animations
animate('1s steps(5, end)')// Basic fade
animate('300ms ease-out', style({ opacity: 0 }))
// Slide with bounce
animate('500ms cubic-bezier(0.68, -0.55, 0.265, 1.55)', style({
transform: 'translateX(100px)'
}))
// Multi-property animation
animate('400ms 200ms ease-in-out', style({
opacity: 0,
transform: 'scale(0.8) translateY(-20px)',
backgroundColor: 'red'
}))style({
transform: 'translateX(100px)', // Translate
transform: 'translateY(-50px)',
transform: 'translate(50px, -25px)',
transform: 'scale(1.5)', // Scale
transform: 'scaleX(2)',
transform: 'rotate(45deg)', // Rotate
transform: 'skew(10deg, 5deg)', // Skew
transform: 'matrix(1, 0, 0, 1, 50, 100)' // Matrix
})
// Combined transforms
style({
transform: 'translateX(50px) rotate(45deg) scale(1.2)'
})style({
// Opacity
opacity: 0,
opacity: 1,
// Colors
backgroundColor: 'red',
color: '#ff0000',
borderColor: 'rgba(255, 0, 0, 0.5)',
// Dimensions
width: '100px',
height: 200, // Numbers default to px
maxWidth: '50%',
// Position
left: '10px',
top: 0,
zIndex: 1000,
// Filters
filter: 'blur(5px)',
filter: 'brightness(1.5)',
// Box properties
borderRadius: '10px',
boxShadow: '0 4px 8px rgba(0,0,0,0.2)'
})style({
width: '50%',
height: 'calc(100vh - 50px)',
transform: 'translateX(calc(100% - 20px))',
left: '25vw',
fontSize: '1.2em'
})trigger('fadeInOut', [
transition(':enter', [
style({ opacity: 0 }),
animate('300ms ease-in', style({ opacity: 1 }))
]),
transition(':leave', [
animate('300ms ease-out', style({ opacity: 0 }))
])
])trigger('slideIn', [
transition(':enter', [
style({ transform: 'translateX(-100%)', opacity: 0 }),
animate('400ms cubic-bezier(0.25, 0.46, 0.45, 0.94)',
style({ transform: 'translateX(0)', opacity: 1 })
)
])
])trigger('pulse', [
transition('* => *', [
animate('1s', keyframes([
style({ transform: 'scale(1)', offset: 0 }),
style({ transform: 'scale(1.1)', offset: 0.2 }),
style({ transform: 'scale(1)', offset: 0.4 }),
style({ transform: 'scale(1.1)', offset: 0.6 }),
style({ transform: 'scale(1)', offset: 1 })
]))
])
])