forces.dart 2.51 KB
Newer Older
Matt Perry's avatar
Matt Perry committed
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
import 'package:flutter/physics.dart';
6

7
export 'package:flutter/physics.dart' show SpringDescription;
8

Florian Loitsch's avatar
Florian Loitsch committed
9
/// A factory for simulations.
Matt Perry's avatar
Matt Perry committed
10
abstract class Force {
11 12
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
13 14
  const Force();

15
  /// Creates a new physics simulation with the given initial conditions.
16
  Simulation release(double position, double velocity);
Matt Perry's avatar
Matt Perry committed
17 18
}

Florian Loitsch's avatar
Florian Loitsch committed
19
/// A factory for spring-based physics simulations.
Matt Perry's avatar
Matt Perry committed
20
class SpringForce extends Force {
21 22 23 24
  /// Creates a spring force.
  ///
  /// The [spring], [left], and [right] arguments must not be null. The [left]
  /// argument defaults to 0.0 and the [right] argument defaults to 1.0.
25
  const SpringForce(this.spring, { this.left: 0.0, this.right: 1.0 });
26

Florian Loitsch's avatar
Florian Loitsch committed
27
  /// The description of the spring to be used in the created simulations.
Matt Perry's avatar
Matt Perry committed
28
  final SpringDescription spring;
29

Florian Loitsch's avatar
Florian Loitsch committed
30
  /// Where to put the spring's resting point when releasing left.
31
  final double left;
32

Florian Loitsch's avatar
Florian Loitsch committed
33
  /// Where to put the spring's resting point when releasing right.
34
  final double right;
Matt Perry's avatar
Matt Perry committed
35

36 37 38 39 40 41 42 43 44 45 46 47 48
  /// Creates a copy of this spring force but with the given fields replaced with the new values.
  SpringForce copyWith({
    SpringDescription spring,
    double left,
    double right
  }) {
    return new SpringForce(
      spring ?? this.spring,
      left: left ?? this.left,
      right: right ?? this.right
    );
  }

Florian Loitsch's avatar
Florian Loitsch committed
49
  /// How pricely to terminate the simulation.
50 51 52 53
  ///
  /// We overshoot the target by this distance, but stop the simulation when
  /// the spring gets within this distance (regardless of how fast it's moving).
  /// This causes the spring to settle a bit faster than it otherwise would.
54
  static const Tolerance tolerance = const Tolerance(
55 56 57 58
    velocity: double.INFINITY,
    distance: 0.01
  );

59
  @override
60
  Simulation release(double position, double velocity) {
61 62
    double target = velocity < 0.0 ? this.left - tolerance.distance
                                   : this.right + tolerance.distance;
63 64
    return new SpringSimulation(spring, position, target, velocity)
      ..tolerance = tolerance;
Matt Perry's avatar
Matt Perry committed
65 66 67
  }
}

68 69 70 71 72 73
final SpringDescription _kDefaultSpringDesc = new SpringDescription.withDampingRatio(
  mass: 1.0,
  springConstant: 500.0,
  ratio: 1.0
);

Florian Loitsch's avatar
Florian Loitsch committed
74
/// A spring force with reasonable default values.
Matt Perry's avatar
Matt Perry committed
75
final SpringForce kDefaultSpringForce = new SpringForce(_kDefaultSpringDesc);