curves.dart 37.1 KB
Newer Older
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'dart:math' as math;

7 8
import 'package:flutter/foundation.dart';

9 10 11 12 13
/// An easing curve, i.e. a mapping of the unit interval to the unit interval.
///
/// Easing curves are used to adjust the rate of change of an animation over
/// time, allowing them to speed up and slow down, rather than moving at a
/// constant rate.
14
///
15
/// A curve must map t=0.0 to 0.0 and t=1.0 to 1.0.
16
///
17 18 19 20 21 22 23 24
/// See also:
///
///  * [Curves], a collection of common animation easing curves.
///  * [CurveTween], which can be used to apply a [Curve] to an [Animation].
///  * [Canvas.drawArc], which draws an arc, and has nothing to do with easing
///    curves.
///  * [Animatable], for a more flexible interface that maps fractions to
///    arbitrary values.
25
@immutable
26
abstract class Curve {
27 28
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
29 30
  const Curve();

31
  /// Returns the value of the curve at point `t`.
32
  ///
33 34 35 36
  /// This function must ensure the following:
  /// - The value of `t` must be between 0.0 and 1.0
  /// - Values of `t`=0.0 and `t`=1.0 must be mapped to 0.0 and 1.0,
  /// respectively.
37
  ///
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  /// It is recommended that subclasses override [transformInternal] instead of
  /// this function, as the above cases are already handled in the default
  /// implementation of [transform], which delegates the remaining logic to
  /// [transformInternal].
  double transform(double t) {
    assert(t >= 0.0 && t <= 1.0);
    if (t == 0.0 || t == 1.0) {
      return t;
    }
    return transformInternal(t);
  }

  /// Returns the value of the curve at point `t`, in cases where
  /// 1.0 > `t` > 0.0.
  @protected
  double transformInternal(double t) {
    throw UnimplementedError();
  }
56 57

  /// Returns a new curve that is the reversed inversion of this one.
58 59
  ///
  /// This is often useful with [CurvedAnimation.reverseCurve].
60
  ///
61 62
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_flipped.mp4}
63 64 65 66
  ///
  /// See also:
  ///
  ///  * [FlippedCurve], the class that is used to implement this getter.
67 68
  ///  * [ReverseAnimation], which reverses an [Animation] rather than a [Curve].
  ///  * [CurvedAnimation], which can take a separate curve and reverse curve.
69
  Curve get flipped => FlippedCurve(this);
70 71 72 73 74

  @override
  String toString() {
    return '$runtimeType';
  }
75 76
}

Florian Loitsch's avatar
Florian Loitsch committed
77
/// The identity map over the unit interval.
78 79
///
/// See [Curves.linear] for an instance of this class.
80 81
class _Linear extends Curve {
  const _Linear._();
82 83

  @override
84
  double transformInternal(double t) => t;
85 86
}

Hixie's avatar
Hixie committed
87
/// A sawtooth curve that repeats a given number of times over the unit interval.
88 89 90
///
/// The curve rises linearly from 0.0 to 1.0 and then falls discontinuously back
/// to 0.0 each iteration.
91
///
92
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_sawtooth.mp4}
93
class SawTooth extends Curve {
94 95 96
  /// Creates a sawtooth curve.
  ///
  /// The [count] argument must not be null.
97
  const SawTooth(this.count) : assert(count != null);
98

99
  /// The number of repetitions of the sawtooth pattern in the unit interval.
Hixie's avatar
Hixie committed
100
  final int count;
101 102

  @override
103
  double transformInternal(double t) {
Hixie's avatar
Hixie committed
104 105 106
    t *= count;
    return t - t.truncateToDouble();
  }
107 108 109 110 111

  @override
  String toString() {
    return '$runtimeType($count)';
  }
Hixie's avatar
Hixie committed
112 113
}

114 115
/// A curve that is 0.0 until [begin], then curved (according to [curve]) from
/// 0.0 at [begin] to 1.0 at [end], then remains 1.0 past [end].
116 117 118 119 120
///
/// An [Interval] can be used to delay an animation. For example, a six second
/// animation that uses an [Interval] with its [begin] set to 0.5 and its [end]
/// set to 1.0 will essentially become a three-second animation that starts
/// three seconds later.
121
///
122
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_interval.mp4}
123
class Interval extends Curve {
124 125
  /// Creates an interval curve.
  ///
126
  /// The arguments must not be null.
127
  const Interval(this.begin, this.end, { this.curve = Curves.linear })
128 129 130
    : assert(begin != null),
      assert(end != null),
      assert(curve != null);
131

132 133 134
  /// The largest value for which this interval is 0.0.
  ///
  /// From t=0.0 to t=`begin`, the interval's value is 0.0.
135
  final double begin;
136

Florian Loitsch's avatar
Florian Loitsch committed
137
  /// The smallest value for which this interval is 1.0.
138 139
  ///
  /// From t=`end` to t=1.0, the interval's value is 1.0.
140 141
  final double end;

142
  /// The curve to apply between [begin] and [end].
143 144
  final Curve curve;

145
  @override
146
  double transformInternal(double t) {
147 148
    assert(begin >= 0.0);
    assert(begin <= 1.0);
149 150
    assert(end >= 0.0);
    assert(end <= 1.0);
151 152
    assert(end >= begin);
    t = ((t - begin) / (end - begin)).clamp(0.0, 1.0);
153 154 155
    if (t == 0.0 || t == 1.0)
      return t;
    return curve.transform(t);
156
  }
157 158 159

  @override
  String toString() {
160
    if (curve is! _Linear)
161 162
      return '$runtimeType($begin\u22EF$end)\u27A9$curve';
    return '$runtimeType($begin\u22EF$end)';
163
  }
164 165
}

166
/// A curve that is 0.0 until it hits the threshold, then it jumps to 1.0.
167
///
168
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_threshold.mp4}
169 170
class Threshold extends Curve {
  /// Creates a threshold curve.
171 172
  ///
  /// The [threshold] argument must not be null.
173
  const Threshold(this.threshold) : assert(threshold != null);
174 175 176

  /// The value before which the curve is 0.0 and after which the curve is 1.0.
  ///
177
  /// When t is exactly [threshold], the curve has the value 1.0.
178 179 180
  final double threshold;

  @override
181
  double transformInternal(double t) {
182 183 184 185 186 187
    assert(threshold >= 0.0);
    assert(threshold <= 1.0);
    return t < threshold ? 0.0 : 1.0;
  }
}

Florian Loitsch's avatar
Florian Loitsch committed
188
/// A cubic polynomial mapping of the unit interval.
189
///
190
/// The [Curves] class contains some commonly used cubic curves:
191 192 193 194 195
///
///  * [Curves.ease]
///  * [Curves.easeIn]
///  * [Curves.easeOut]
///  * [Curves.easeInOut]
196
///
197 198 199 200
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out.mp4}
201 202
///
/// The [Cubic] class implements third-order Bézier curves.
203
class Cubic extends Curve {
204 205 206 207 208 209
  /// Creates a cubic curve.
  ///
  /// Rather than creating a new instance, consider using one of the common
  /// cubic curves in [Curves].
  ///
  /// The [a], [b], [c], and [d] arguments must not be null.
210
  const Cubic(this.a, this.b, this.c, this.d)
211 212 213 214
    : assert(a != null),
      assert(b != null),
      assert(c != null),
      assert(d != null);
215

216 217 218 219
  /// The x coordinate of the first control point.
  ///
  /// The line through the point (0, 0) and the first control point is tangent
  /// to the curve at the point (0, 0).
220
  final double a;
221 222 223 224 225

  /// The y coordinate of the first control point.
  ///
  /// The line through the point (0, 0) and the first control point is tangent
  /// to the curve at the point (0, 0).
226
  final double b;
227 228 229 230 231

  /// The x coordinate of the second control point.
  ///
  /// The line through the point (1, 1) and the second control point is tangent
  /// to the curve at the point (1, 1).
232
  final double c;
233 234 235 236 237

  /// The y coordinate of the second control point.
  ///
  /// The line through the point (1, 1) and the second control point is tangent
  /// to the curve at the point (1, 1).
238 239
  final double d;

240
  static const double _cubicErrorBound = 0.001;
241 242 243 244 245 246 247

  double _evaluateCubic(double a, double b, double m) {
    return 3 * a * (1 - m) * (1 - m) * m +
           3 * b * (1 - m) *           m * m +
                                       m * m * m;
  }

248
  @override
249
  double transformInternal(double t) {
250 251 252
    double start = 0.0;
    double end = 1.0;
    while (true) {
253 254
      final double midpoint = (start + end) / 2;
      final double estimate = _evaluateCubic(a, c, midpoint);
255
      if ((t - estimate).abs() < _cubicErrorBound)
256 257 258 259 260 261 262
        return _evaluateCubic(b, d, midpoint);
      if (estimate < t)
        start = midpoint;
      else
        end = midpoint;
    }
  }
263 264 265 266 267

  @override
  String toString() {
    return '$runtimeType(${a.toStringAsFixed(2)}, ${b.toStringAsFixed(2)}, ${c.toStringAsFixed(2)}, ${d.toStringAsFixed(2)})';
  }
268 269
}

270
/// A curve that is the reversed inversion of its given curve.
271
///
272
/// This curve evaluates the given curve in reverse (i.e., from 1.0 to 0.0 as t
273 274
/// increases from 0.0 to 1.0) and returns the inverse of the given curve's
/// value (i.e., 1.0 minus the given curve's value).
275 276 277
///
/// This is the class used to implement the [flipped] getter on curves.
///
278 279
/// This is often useful with [CurvedAnimation.reverseCurve].
///
280
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
281 282 283 284 285 286 287
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_flipped.mp4}
///
/// See also:
///
///  * [Curve.flipped], which provides the [FlippedCurve] of a [Curve].
///  * [ReverseAnimation], which reverses an [Animation] rather than a [Curve].
///  * [CurvedAnimation], which can take a separate curve and reverse curve.
288
class FlippedCurve extends Curve {
289 290 291
  /// Creates a flipped curve.
  ///
  /// The [curve] argument must not be null.
292
  const FlippedCurve(this.curve) : assert(curve != null);
293

294
  /// The curve that is being flipped.
295
  final Curve curve;
296 297

  @override
298
  double transformInternal(double t) => 1.0 - curve.transform(1.0 - t);
299 300 301 302 303

  @override
  String toString() {
    return '$runtimeType($curve)';
  }
304 305
}

306 307 308 309 310 311 312 313 314 315 316
/// A curve where the rate of change starts out quickly and then decelerates; an
/// upside-down `f(t) = t²` parabola.
///
/// This is equivalent to the Android `DecelerateInterpolator` class with a unit
/// factor (the default factor).
///
/// See [Curves.decelerate] for an instance of this class.
class _DecelerateCurve extends Curve {
  const _DecelerateCurve._();

  @override
317
  double transformInternal(double t) {
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
    // Intended to match the behavior of:
    // https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/animation/DecelerateInterpolator.java
    // ...as of December 2016.
    t = 1.0 - t;
    return 1.0 - t * t;
  }
}

// BOUNCE CURVES

double _bounce(double t) {
  if (t < 1.0 / 2.75) {
    return 7.5625 * t * t;
  } else if (t < 2 / 2.75) {
    t -= 1.5 / 2.75;
    return 7.5625 * t * t + 0.75;
  } else if (t < 2.5 / 2.75) {
    t -= 2.25 / 2.75;
    return 7.5625 * t * t + 0.9375;
  }
  t -= 2.625 / 2.75;
  return 7.5625 * t * t + 0.984375;
}

Florian Loitsch's avatar
Florian Loitsch committed
342
/// An oscillating curve that grows in magnitude.
343 344
///
/// See [Curves.bounceIn] for an instance of this class.
345 346
class _BounceInCurve extends Curve {
  const _BounceInCurve._();
347 348

  @override
349
  double transformInternal(double t) {
350 351 352 353
    return 1.0 - _bounce(1.0 - t);
  }
}

Florian Loitsch's avatar
Florian Loitsch committed
354
/// An oscillating curve that shrink in magnitude.
355 356
///
/// See [Curves.bounceOut] for an instance of this class.
357 358
class _BounceOutCurve extends Curve {
  const _BounceOutCurve._();
359 360

  @override
361
  double transformInternal(double t) {
362 363 364 365
    return _bounce(t);
  }
}

Florian Loitsch's avatar
Florian Loitsch committed
366
/// An oscillating curve that first grows and then shrink in magnitude.
367 368
///
/// See [Curves.bounceInOut] for an instance of this class.
369 370
class _BounceInOutCurve extends Curve {
  const _BounceInOutCurve._();
371 372

  @override
373
  double transformInternal(double t) {
374
    if (t < 0.5)
375
      return (1.0 - _bounce(1.0 - t * 2.0)) * 0.5;
376 377 378 379 380
    else
      return _bounce(t * 2.0 - 1.0) * 0.5 + 0.5;
  }
}

381 382 383

// ELASTIC CURVES

Florian Loitsch's avatar
Florian Loitsch committed
384
/// An oscillating curve that grows in magnitude while overshooting its bounds.
385 386 387 388
///
/// An instance of this class using the default period of 0.4 is available as
/// [Curves.elasticIn].
///
389
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in.mp4}
390
class ElasticInCurve extends Curve {
391 392 393
  /// Creates an elastic-in curve.
  ///
  /// Rather than creating a new instance, consider using [Curves.elasticIn].
394
  const ElasticInCurve([this.period = 0.4]);
395

396
  /// The duration of the oscillation.
397
  final double period;
398 399

  @override
400
  double transformInternal(double t) {
401
    final double s = period / 4.0;
402
    t = t - 1.0;
403
    return -math.pow(2.0, 10.0 * t) * math.sin((t - s) * (math.pi * 2.0) / period);
404
  }
405 406 407 408 409

  @override
  String toString() {
    return '$runtimeType($period)';
  }
410 411
}

Florian Loitsch's avatar
Florian Loitsch committed
412
/// An oscillating curve that shrinks in magnitude while overshooting its bounds.
413 414 415 416
///
/// An instance of this class using the default period of 0.4 is available as
/// [Curves.elasticOut].
///
417
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_out.mp4}
418
class ElasticOutCurve extends Curve {
419 420 421
  /// Creates an elastic-out curve.
  ///
  /// Rather than creating a new instance, consider using [Curves.elasticOut].
422
  const ElasticOutCurve([this.period = 0.4]);
423

424
  /// The duration of the oscillation.
425
  final double period;
426 427

  @override
428
  double transformInternal(double t) {
429
    final double s = period / 4.0;
430
    return math.pow(2.0, -10 * t) * math.sin((t - s) * (math.pi * 2.0) / period) + 1.0;
431
  }
432 433 434 435 436

  @override
  String toString() {
    return '$runtimeType($period)';
  }
437 438
}

439 440 441 442 443 444
/// An oscillating curve that grows and then shrinks in magnitude while
/// overshooting its bounds.
///
/// An instance of this class using the default period of 0.4 is available as
/// [Curves.elasticInOut].
///
445
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in_out.mp4}
446
class ElasticInOutCurve extends Curve {
447 448 449
  /// Creates an elastic-in-out curve.
  ///
  /// Rather than creating a new instance, consider using [Curves.elasticInOut].
450
  const ElasticInOutCurve([this.period = 0.4]);
451

452
  /// The duration of the oscillation.
453
  final double period;
454 455

  @override
456
  double transformInternal(double t) {
457
    final double s = period / 4.0;
458
    t = 2.0 * t - 1.0;
459
    if (t < 0.0)
460
      return -0.5 * math.pow(2.0, 10.0 * t) * math.sin((t - s) * (math.pi * 2.0) / period);
461
    else
462
      return math.pow(2.0, -10.0 * t) * math.sin((t - s) * (math.pi * 2.0) / period) * 0.5 + 1.0;
463
  }
464 465 466 467 468

  @override
  String toString() {
    return '$runtimeType($period)';
  }
469 470
}

471 472 473

// PREDEFINED CURVES

474
/// A collection of common animation curves.
475
///
476 477 478 479 480 481
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_decelerate.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in.mp4}
482 483 484 485 486 487 488 489
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_back.mp4}
490
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out.mp4}
491 492 493 494 495 496 497 498
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_back.mp4}
499
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out.mp4}
500 501 502 503 504 505 506 507
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_back.mp4}
508 509 510 511
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_fast_out_slow_in.mp4}
512
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_slow_middle.mp4}
513
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_linear.mp4}
514 515 516 517 518
///
/// See also:
///
///  * [Curve], the interface implemented by the constants available from the
///    [Curves] class.
519 520
class Curves {
  Curves._();
521

522 523 524 525 526
  /// A linear animation curve.
  ///
  /// This is the identity map over the unit interval: its [Curve.transform]
  /// method returns its input unmodified. This is useful as a default curve for
  /// cases where a [Curve] is required but no actual curve is desired.
527
  ///
528
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_linear.mp4}
529
  static const Curve linear = _Linear._();
530 531 532 533 534 535

  /// A curve where the rate of change starts out quickly and then decelerates; an
  /// upside-down `f(t) = t²` parabola.
  ///
  /// This is equivalent to the Android `DecelerateInterpolator` class with a unit
  /// factor (the default factor).
536
  ///
537
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_decelerate.mp4}
538
  static const Curve decelerate = _DecelerateCurve._();
539

540 541 542 543 544 545 546 547 548
  /// A curve that is very steep and linear at the beginning, but quickly flattens out
  /// and very slowly eases in.
  ///
  /// By default is the curve used to animate pages on iOS back to their original
  /// position if a swipe gesture is ended midway through a swipe.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/fast_linear_to_slow_ease_in.mp4}
  static const Cubic fastLinearToSlowEaseIn = Cubic(0.18, 1.0, 0.04, 1.0);

Florian Loitsch's avatar
Florian Loitsch committed
549
  /// A cubic animation curve that speeds up quickly and ends slowly.
550
  ///
551
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
552
  static const Cubic ease = Cubic(0.25, 0.1, 0.25, 1.0);
553

Florian Loitsch's avatar
Florian Loitsch committed
554
  /// A cubic animation curve that starts slowly and ends quickly.
555
  ///
556
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in.mp4}
557
  static const Cubic easeIn = Cubic(0.42, 0.0, 1.0, 1.0);
558

559 560 561 562 563 564 565
  /// A cubic animation curve that starts starts slowly and ends linearly.
  ///
  /// The symmetric animation to [linearToEaseOut].
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_to_linear.mp4}
  static const Cubic easeInToLinear = Cubic(0.67, 0.03, 0.65, 0.09);

566 567 568 569 570 571 572 573
  /// A cubic animation curve that starts slowly and ends quickly. This is
  /// similar to [Curves.easeIn], but with sinusoidal easing for a slightly less
  /// abrupt beginning and end. Nonetheless, the result is quite gentle and is
  /// hard to distinguish from [Curves.linear] at a glance.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_sine.mp4}
574
  static const Cubic easeInSine = Cubic(0.47, 0.0, 0.745, 0.715);
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654

  /// A cubic animation curve that starts slowly and ends quickly. Based on a
  /// quadratic equation where `f(t) = t²`, this is effectively the inverse of
  /// [Curves.decelerate].
  ///
  /// Compared to [Curves.easeInSine], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quad.mp4}
  static const Cubic easeInQuad = Cubic(0.55, 0.085, 0.68, 0.53);

  /// A cubic animation curve that starts slowly and ends quickly. This curve is
  /// based on a cubic equation where `f(t) = t³`. The result is a safe sweet
  /// spot when choosing a curve for widgets animating off the viewport.
  ///
  /// Compared to [Curves.easeInQuad], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_cubic.mp4}
  static const Cubic easeInCubic = Cubic(0.55, 0.055, 0.675, 0.19);

  /// A cubic animation curve that starts slowly and ends quickly. This curve is
  /// based on a quartic equation where `f(t) = t⁴`.
  ///
  /// Animations using this curve or steeper curves will benefit from a longer
  /// duration to avoid motion feeling unnatural.
  ///
  /// Compared to [Curves.easeInCubic], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quart.mp4}
  static const Cubic easeInQuart = Cubic(0.895, 0.03, 0.685, 0.22);

  /// A cubic animation curve that starts slowly and ends quickly. This curve is
  /// based on a quintic equation where `f(t) = t⁵`.
  ///
  /// Compared to [Curves.easeInQuart], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quint.mp4}
  static const Cubic easeInQuint = Cubic(0.755, 0.05, 0.855, 0.06);

  /// A cubic animation curve that starts slowly and ends quickly. This curve is
  /// based on an exponential equation where `f(t) = 2¹⁰⁽ᵗ⁻¹⁾`.
  ///
  /// Using this curve can give your animations extra flare, but a longer
  /// duration may need to be used to compensate for the steepness of the curve.
  ///
  /// Compared to [Curves.easeInQuint], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_expo.mp4}
  static const Cubic easeInExpo = Cubic(0.95, 0.05, 0.795, 0.035);

  /// A cubic animation curve that starts slowly and ends quickly. This curve is
  /// effectively the bottom-right quarter of a circle.
  ///
  /// Like [Curves.easeInExpo], this curve is fairly dramatic and will reduce
  /// the clarity of an animation if not given a longer duration.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_circ.mp4}
  static const Cubic easeInCirc = Cubic(0.6, 0.04, 0.98, 0.335);

  /// A cubic animation curve that starts slowly and ends quickly. This curve
  /// is similar to [Curves.elasticIn] in that it overshoots its bounds before
  /// reaching its end. Instead of repeated swinging motions before ascending,
  /// though, this curve overshoots once, then continues to ascend.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_back.mp4}
  static const Cubic easeInBack = Cubic(0.6, -0.28, 0.735, 0.045);

Florian Loitsch's avatar
Florian Loitsch committed
655
  /// A cubic animation curve that starts quickly and ends slowly.
656
  ///
657
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out.mp4}
658
  static const Cubic easeOut = Cubic(0.0, 0.0, 0.58, 1.0);
659

660 661 662 663 664 665 666
  /// A cubic animation curve that starts linearly and ends slowly.
  ///
  /// A symmetric animation to [easeInToLinear].
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/linear_to_ease_out.mp4}
  static const Cubic linearToEaseOut = Cubic(0.35, 0.91, 0.33, 0.97);

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
  /// A cubic animation curve that starts quickly and ends slowly. This is
  /// similar to [Curves.easeOut], but with sinusoidal easing for a slightly
  /// less abrupt beginning and end. Nonetheless, the result is quite gentle and
  /// is hard to distinguish from [Curves.linear] at a glance.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_sine.mp4}
  static const Cubic easeOutSine = Cubic(0.39, 0.575, 0.565, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This is
  /// effectively the same as [Curves.decelerate], only simulated using a cubic
  /// bezier function.
  ///
  /// Compared to [Curves.easeOutSine], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quad.mp4}
  static const Cubic easeOutQuad = Cubic(0.25, 0.46, 0.45, 0.94);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// a flipped version of [Curves.easeInCubic].
  ///
  /// The result is a safe sweet spot when choosing a curve for animating a
  /// widget's position entering or already inside the viewport.
  ///
  /// Compared to [Curves.easeOutQuad], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_cubic.mp4}
  static const Cubic easeOutCubic = Cubic(0.215, 0.61, 0.355, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// a flipped version of [Curves.easeInQuart].
  ///
  /// Animations using this curve or steeper curves will benefit from a longer
  /// duration to avoid motion feeling unnatural.
  ///
  /// Compared to [Curves.easeOutCubic], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quart.mp4}
  static const Cubic easeOutQuart = Cubic(0.165, 0.84, 0.44, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// a flipped version of [Curves.easeInQuint].
  ///
  /// Compared to [Curves.easeOutQuart], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quint.mp4}
  static const Cubic easeOutQuint = Cubic(0.23, 1.0, 0.32, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// a flipped version of [Curves.easeInExpo]. Using this curve can give your
  /// animations extra flare, but a longer duration may need to be used to
  /// compensate for the steepness of the curve.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_expo.mp4}
  static const Cubic easeOutExpo = Cubic(0.19, 1.0, 0.22, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// effectively the top-left quarter of a circle.
  ///
  /// Like [Curves.easeOutExpo], this curve is fairly dramatic and will reduce
  /// the clarity of an animation if not given a longer duration.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_circ.mp4}
  static const Cubic easeOutCirc = Cubic(0.075, 0.82, 0.165, 1.0);

  /// A cubic animation curve that starts quickly and ends slowly. This curve is
  /// similar to [Curves.elasticOut] in that it overshoots its bounds before
  /// reaching its end. Instead of repeated swinging motions after ascending,
  /// though, this curve only overshoots once.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_back.mp4}
  static const Cubic easeOutBack = Cubic(0.175, 0.885, 0.32, 1.275);

755
  /// A cubic animation curve that starts slowly, speeds up, and then ends
756
  /// slowly.
757
  ///
758
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out.mp4}
759
  static const Cubic easeInOut = Cubic(0.42, 0.0, 0.58, 1.0);
760

761
  /// A cubic animation curve that starts slowly, speeds up, and then ends
762 763 764 765 766 767 768 769
  /// slowly. This is similar to [Curves.easeInOut], but with sinusoidal easing
  /// for a slightly less abrupt beginning and end.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_sine.mp4}
  static const Cubic easeInOutSine = Cubic(0.445, 0.05, 0.55, 0.95);

770
  /// A cubic animation curve that starts slowly, speeds up, and then ends
771 772 773 774 775 776 777 778 779 780
  /// slowly. This curve can be imagined as [Curves.easeInQuad] as the first
  /// half, and [Curves.easeOutQuad] as the second.
  ///
  /// Compared to [Curves.easeInOutSine], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quad.mp4}
  static const Cubic easeInOutQuad = Cubic(0.455, 0.03, 0.515, 0.955);

781
  /// A cubic animation curve that starts slowly, speeds up, and then ends
782 783 784 785 786 787 788 789 790 791 792 793 794
  /// slowly. This curve can be imagined as [Curves.easeInCubic] as the first
  /// half, and [Curves.easeOutCubic] as the second.
  ///
  /// The result is a safe sweet spot when choosing a curve for a widget whose
  /// initial and final positions are both within the viewport.
  ///
  /// Compared to [Curves.easeInOutQuad], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_cubic.mp4}
  static const Cubic easeInOutCubic = Cubic(0.645, 0.045, 0.355, 1.0);

795
  /// A cubic animation curve that starts slowly, speeds up, and then ends
796 797 798 799 800 801 802 803 804 805 806
  /// slowly. This curve can be imagined as [Curves.easeInQuart] as the first
  /// half, and [Curves.easeOutQuart] as the second.
  ///
  /// Animations using this curve or steeper curves will benefit from a longer
  /// duration to avoid motion feeling unnatural.
  ///
  /// Compared to [Curves.easeInOutCubic], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quart.mp4}
807
  static const Cubic easeInOutQuart = Cubic(0.77, 0.0, 0.175, 1.0);
808

809
  /// A cubic animation curve that starts slowly, speeds up, and then ends
810 811 812 813 814 815 816 817
  /// slowly. This curve can be imagined as [Curves.easeInQuint] as the first
  /// half, and [Curves.easeOutQuint] as the second.
  ///
  /// Compared to [Curves.easeInOutQuart], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quint.mp4}
818
  static const Cubic easeInOutQuint = Cubic(0.86, 0.0, 0.07, 1.0);
819

820
  /// A cubic animation curve that starts slowly, speeds up, and then ends
821 822 823 824 825 826 827 828 829 830 831
  /// slowly.
  ///
  /// Since this curve is arrived at with an exponential function, the midpoint
  /// is exceptionally steep. Extra consideration should be taken when designing
  /// an animation using this.
  ///
  /// Compared to [Curves.easeInOutQuint], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_expo.mp4}
832
  static const Cubic easeInOutExpo = Cubic(1.0, 0.0, 0.0, 1.0);
833

834
  /// A cubic animation curve that starts slowly, speeds up, and then ends
835 836 837 838 839 840 841 842 843 844 845 846 847
  /// slowly. This curve can be imagined as [Curves.easeInCirc] as the first
  /// half, and [Curves.easeOutCirc] as the second.
  ///
  /// Like [Curves.easeInOutExpo], this curve is fairly dramatic and will reduce
  /// the clarity of an animation if not given a longer duration.
  ///
  /// Compared to [Curves.easeInOutExpo], this curve is slightly steeper.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_circ.mp4}
  static const Cubic easeInOutCirc = Cubic(0.785, 0.135, 0.15, 0.86);

848
  /// A cubic animation curve that starts slowly, speeds up, and then ends
849 850 851 852 853 854 855 856 857 858 859 860 861
  /// slowly. This curve can be imagined as [Curves.easeInBack] as the first
  /// half, and [Curves.easeOutBack] as the second.
  ///
  /// Since two curves are used as a basis for this curve, the resulting
  /// animation will overshoot its bounds twice before reaching its end - first
  /// by exceeding its lower bound, then exceeding its upper bound and finally
  /// descending to its final position.
  ///
  /// Derived from Robert Penner’s easing functions.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_back.mp4}
  static const Cubic easeInOutBack = Cubic(0.68, -0.55, 0.265, 1.55);

862 863 864 865 866
  /// A curve that starts quickly and eases into its final position.
  ///
  /// Over the course of the animation, the object spends more time near its
  /// final destination. As a result, the user isn’t left waiting for the
  /// animation to finish, and the negative effects of motion are minimized.
867
  ///
868
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_fast_out_slow_in.mp4}
869
  static const Cubic fastOutSlowIn = Cubic(0.4, 0.0, 0.2, 1.0);
870

871 872 873 874 875 876
  /// A cubic animation curve that starts quickly, slows down, and then ends
  /// quickly.
  ///
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_slow_middle.mp4}
  static const Cubic slowMiddle = Cubic(0.15, 0.85, 0.85, 0.15);

Florian Loitsch's avatar
Florian Loitsch committed
877
  /// An oscillating curve that grows in magnitude.
878
  ///
879
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
880
  static const Curve bounceIn = _BounceInCurve._();
881

Florian Loitsch's avatar
Florian Loitsch committed
882
  /// An oscillating curve that first grows and then shrink in magnitude.
883
  ///
884
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_out.mp4}
885
  static const Curve bounceOut = _BounceOutCurve._();
886

Florian Loitsch's avatar
Florian Loitsch committed
887
  /// An oscillating curve that first grows and then shrink in magnitude.
888
  ///
889
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in_out.mp4}
890
  static const Curve bounceInOut = _BounceInOutCurve._();
891

892
  /// An oscillating curve that grows in magnitude while overshooting its bounds.
893
  ///
894
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in.mp4}
895
  static const ElasticInCurve elasticIn = ElasticInCurve();
896

897
  /// An oscillating curve that shrinks in magnitude while overshooting its bounds.
898
  ///
899
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_out.mp4}
900
  static const ElasticOutCurve elasticOut = ElasticOutCurve();
901

902
  /// An oscillating curve that grows and then shrinks in magnitude while overshooting its bounds.
903
  ///
904
  /// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in_out.mp4}
905
  static const ElasticInOutCurve elasticInOut = ElasticInOutCurve();
906
}