Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Implement Flutter animations: implicit, explicit, hero, staggered, and physics-based with a decision tree guide.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/curves.md
1# Curves Reference23Curves define the easing function for animations, controlling how values interpolate from start to end.45## Core Concept67A curve takes an input `t` (0.0 to 1.0, representing time) and outputs a value (typically 0.0 to 1.0, representing progress).89## Built-in Curves1011### Linear1213```dart14Curves.linear15```1617No easing - straight line from 0 to 1. Use when you want constant speed.1819### Ease (Sigmoid)2021```dart22Curves.ease23Curves.easeIn24Curves.easeOut25Curves.easeInOut26```2728**Curves.ease** - Slow start and end, fast middle (most common)2930**Curves.easeIn** - Slow start, fast end (accelerating)3132**Curves.easeOut** - Fast start, slow end (decelerating)3334**Curves.easeInOut** - Slow start and end, fast middle (combination)3536### Cubic (Stronger Ease)3738```dart39Curves.easeInCubic40Curves.easeOutCubic41Curves.easeInOutCubic42```4344Stronger easing than basic ease. More dramatic slow/fast zones.4546### Elastic (Bouncy)4748```dart49Curves.elasticIn50Curves.elasticOut51Curves.elasticInOut52```5354**Curves.elasticIn** - Bounces in (starts behind, shoots forward)5556**Curves.elasticOut** - Bounces out (goes past, comes back)5758**Curves.elasticInOut** - Bounces in and out5960Example: Good for playful UI, notifications6162### Bounce6364```dart65Curves.bounceIn66Curves.bounceOut67Curves.bounceInOut68```6970**Curves.bounceIn** - Bounces in (less bouncy than elastic)7172**Curves.bounceOut** - Bounces out (less bouncy than elastic)7374**Curves.bounceInOut** - Bounces in and out7576Example: Good for feedback animations7778### Back (Overshoot)7980```dart81Curves.backIn82Curves.backOut83Curves.backInOut84```8586**Curves.backIn** - Backs up before going in8788**Curves.backOut** - Backs up before coming out8990**Curves.backInOut** - Backs up on both ends9192Example: Good for revealing content9394### Decelerate (Fast then Slow)9596```dart97Curves.decelerate98```99100Fast start, very slow end. Similar to easeOut but more dramatic.101102### Fast Out Slow In103104```dart105Curves.fastOutSlowIn106```107108Very fast start, very slow middle, very fast end. Dramatic.109110### Custom Curves in Flutter API111112Flutter includes specialized curves:113114```dart115// Material design curves116Curves.fastLinearToSlowEaseIn117Curves.slowMiddle118119// Specific curves for certain transitions120Curves.ease121```122123## Using Curves124125### With Implicit Animation126127```dart128AnimatedContainer(129duration: const Duration(milliseconds: 300),130curve: Curves.easeInOut,131width: _expanded ? 200 : 100,132child: const FlutterLogo(),133)134```135136### With Explicit Animation (CurvedAnimation)137138```dart139animation = CurvedAnimation(140parent: _controller,141curve: Curves.easeInOut,142);143```144145### With Interval146147```dart148animation = CurvedAnimation(149parent: _controller,150curve: const Interval(1510.0,1520.5,153curve: Curves.easeIn,154),155);156```157158### With Curves.elasticOut159160```dart161AnimatedContainer(162duration: const Duration(milliseconds: 1000),163curve: Curves.elasticOut,164transform: Matrix4.rotationZ(_rotated ? 0.5 : 0),165child: const FlutterLogo(),166)167```168169## Custom Curves170171### Creating a Custom Curve172173```dart174import 'dart:math' as math;175176class CustomCurve extends Curve {177@override178double transform(double t) {179// t is 0.0 to 1.0180// Return 0.0 to 1.0181return math.pow(t, 2); // Quadratic ease in182}183}184```185186**Usage:**187```dart188AnimatedContainer(189curve: CustomCurve(),190duration: const Duration(milliseconds: 300),191width: _expanded ? 200 : 100,192child: const FlutterLogo(),193)194```195196### Shake Curve197198```dart199class ShakeCurve extends Curve {200@override201double transform(double t) {202return sin(t * pi * 2);203}204}205```206207### Smooth Step Curve208209```dart210class SmoothStep extends Curve {211final double steps;212213const SmoothStep({this.steps = 5});214215@override216double transform(double t) {217return (t * steps).floor() / steps;218}219}220```221222### Exponential Curve223224```dart225class ExponentialCurve extends Curve {226final double exponent;227228const ExponentialCurve({this.exponent = 2});229230@override231double transform(double t) {232return math.pow(t, exponent);233}234}235```236237## Curve Composition238239### Cubic Bezier240241Flutter doesn't have built-in cubic bezier, but you can approximate:242243```dart244class CubicBezier extends Curve {245final double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y;246247const CubicBezier({248required this.p0x,249required this.p0y,250required this.p1x,251required this.p1y,252required this.p2x,253required this.p2y,254required this.p3x,255required this.p3y,256});257258@override259double transform(double t) {260// Simplified cubic bezier formula261final u = 1 - t;262return (u * u * u * p0y +2633 * u * u * t * p1y +2643 * u * t * t * p2y +265t * t * t * p3y);266}267}268```269270### Combining Curves271272```dart273class CombinedCurve extends Curve {274final Curve first;275final Curve second;276final double threshold;277278const CombinedCurve({279required this.first,280required this.second,281required this.threshold,282});283284@override285double transform(double t) {286if (t < threshold) {287return first.transform(t / threshold) * threshold;288}289return threshold +290second.transform((t - threshold) / (1 - threshold)) * (1 - threshold);291}292}293```294295**Usage:**296```dart297AnimatedContainer(298curve: CombinedCurve(299first: Curves.easeIn,300second: Curves.easeOut,301threshold: 0.5,302),303duration: const Duration(milliseconds: 500),304width: _expanded ? 200 : 100,305child: const FlutterLogo(),306)307```308309## Choosing the Right Curve310311### Motion Design Guidelines312313| Animation Type | Recommended Curve | Why |314|---------------|-------------------|-----|315| Fade in/out | easeInOut | Natural opacity change |316| Size change | easeOut | Decelerate feels natural for growth |317| Position slide | easeInOut | Smooth start and stop |318| Rotation | easeInOut | Natural angular acceleration |319| Color change | linear | Uniform color transition |320| Scale | elasticOut | Playful, bouncy feel |321| Reveal | backOut | Dramatic reveal effect |322| Loading | linear or ease | Consistent speed |323| Success | elasticOut | Celebratory feel |324325### Platform Conventions326327**iOS:**328- Prefers subtle curves (ease, easeInOut)329- Limited use of elastic/bounce330- Consistent with system animations331332**Android:**333- Wider variety of curves334- More use of elastic/bounce for feedback335- Material design curves (easeIn, fastOutSlowIn)336337**Web:**338- CSS-like curves (ease, ease-in, ease-out, ease-in-out)339- Limited use of complex curves340341## Curve Combinations342343### Multi-Stage Animation344345```dart346// Stage 1: Ease in (0.0 - 0.5)347// Stage 2: Ease out (0.5 - 1.0)348349animation1 = CurvedAnimation(350parent: _controller,351curve: const Interval(0.0, 0.5, curve: Curves.easeIn),352);353354animation2 = CurvedAnimation(355parent: _controller,356curve: const Interval(0.5, 1.0, curve: Curves.easeOut),357);358```359360### Staggered with Different Curves361362```dart363// Item 1: Bouncy364item1Animation = CurvedAnimation(365parent: _controller,366curve: const Interval(0.0, 0.3, curve: Curves.elasticOut),367);368369// Item 2: Smooth370item2Animation = CurvedAnimation(371parent: _controller,372curve: const Interval(0.1, 0.4, curve: Curves.easeInOut),373);374375// Item 3: Linear376item3Animation = CurvedAnimation(377parent: _controller,378curve: const Interval(0.2, 0.5, curve: Curves.linear),379);380```381382## Performance Considerations383384### Curve Complexity385386Simple curves (linear, ease) are faster:387- Fewer calculations388- Less GPU work389- Consistent timing390391Complex curves (elastic, bounce) are slower:392- More calculations393- Potential for frame drops394- Variable timing395396### Optimization Tips397398- Use simpler curves on low-end devices399- Cache curve calculations if needed400- Test performance on target devices401- Profile with Flutter DevTools402403## Debugging Curves404405### Visualize Curve406407```dart408class CurveVisualizer extends StatelessWidget {409final Curve curve;410411const CurveVisualizer({super.key, required this.curve});412413@override414Widget build(BuildContext context) {415return CustomPaint(416painter: _CurvePainter(curve: curve),417);418}419}420421class _CurvePainter extends CustomPainter {422final Curve curve;423424const CurvePainter({required this.curve});425426@override427void paint(Canvas canvas, Size size) {428final paint = Paint()429..color = Colors.blue430..strokeWidth = 2431..style = PaintingStyle.stroke;432433final path = Path();434for (double t = 0; t <= 1; t += 0.01) {435final x = t * size.width;436final y = size.height - (curve.transform(t) * size.height);437if (t == 0) {438path.moveTo(x, y);439} else {440path.lineTo(x, y);441}442}443canvas.drawPath(path, paint);444}445446@override447bool shouldRepaint(_CurvePainter oldDelegate) => false;448}449```450451### Print Curve Values452453```dart454void printCurveValues(Curve curve) {455print('Curve: $curve');456for (double t = 0; t <= 1; t += 0.1) {457print('t=$t, output=${curve.transform(t)}');458}459}460461// Usage462printCurveValues(Curves.easeInOut);463```464465## Accessibility466467### Respecting User Preferences468469```dart470Curve getAdaptiveCurve(BuildContext context) {471if (MediaQuery.of(context).disableAnimations) {472return Curves.linear; // No easing when animations disabled473}474return Curves.easeInOut;475}476```477478### Reduced Motion479480```dart481AnimatedContainer(482duration: MediaQuery.of(context).disableAnimations483? Duration.zero484: const Duration(milliseconds: 300),485curve: getAdaptiveCurve(context),486width: _expanded ? 200 : 100,487child: const FlutterLogo(),488)489```490491## Common Patterns492493### Loading Spinner494495```dart496_animation = CurvedAnimation(497parent: _controller,498curve: Curves.linear, // Constant speed499);500```501502### Success Checkmark503504```dart505_animation = CurvedAnimation(506parent: _controller,507curve: Curves.elasticOut, // Bouncy celebration508);509```510511### Page Transition512513```dart514_enterAnimation = CurvedAnimation(515parent: _controller,516curve: Curves.easeIn, // Accelerate in517);518519_exitAnimation = CurvedAnimation(520parent: _controller,521curve: Curves.easeOut, // Decelerate out522);523```524525### Modal Popup526527```dart528_animation = CurvedAnimation(529parent: _controller,530curve: Curves.easeOutBack, // Dramatic reveal531);532```533534## Curve Comparison535536| Curve | Start | Middle | End | Feel |537|-------|-------|--------|-----|------|538| linear | Fast | Fast | Fast | Mechanical |539| ease | Slow | Fast | Slow | Natural |540| easeIn | Slow | Fast | Fast | Accelerating |541| easeOut | Fast | Slow | Slow | Decelerating |542| easeInOut | Slow | Fast | Slow | Smooth |543| elasticIn | Back | Fast | Normal | Bouncy start |544| elasticOut | Normal | Fast | Back | Bouncy end |545| bounceIn | Bounce | Fast | Normal | Bouncy start |546| bounceOut | Normal | Fast | Bounce | Bouncy end |547| backIn | Back | Fast | Normal | Overshoot start |548| backOut | Normal | Fast | Back | Overshoot end |549550## Best Practices551552### DO553554- Use appropriate curves for animation type555- Test on real devices556- Consider platform conventions557- Respect accessibility settings558- Profile performance with DevTools559560### DON'T561562- Use elastic/bounce for everything (distracting)563- Over-combine curves (confusing motion)564- Ignore device performance565- Use same curve for all animations (boring)566- Forget to handle edge cases (t < 0 or t > 1)567