fling_curve.dart 1.6 KB
Newer Older
A
Adam Barth 已提交
1 2 3 4 5 6 7 8 9 10 11
// 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.

import "dart:math" as math;

const double _kDefaultAlpha = -5707.62;
const double _kDefaultBeta = 172.0;
const double _kDefaultGamma = 3.7;

double _positionAtTime(double t) {
12 13 14
  return _kDefaultAlpha * math.exp(-_kDefaultGamma * t)
      - _kDefaultBeta * t
      - _kDefaultAlpha;
A
Adam Barth 已提交
15 16 17
}

double _velocityAtTime(double t) {
18 19
  return -_kDefaultAlpha * _kDefaultGamma * math.exp(-_kDefaultGamma * t)
      - _kDefaultBeta;
A
Adam Barth 已提交
20 21 22
}

double _timeAtVelocity(double v) {
23 24
  return -math.log((v + _kDefaultBeta) / (-_kDefaultAlpha * _kDefaultGamma))
      / _kDefaultGamma;
A
Adam Barth 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38
}

final double _kMaxVelocity = _velocityAtTime(0.0);
final double _kCurveDuration = _timeAtVelocity(0.0);

class FlingCurve {
  double _timeOffset;
  double _positionOffset;
  double _startTime;
  double _previousPosition;
  double _direction;

  FlingCurve(double velocity, double startTime) {
    double startingVelocity = math.min(_kMaxVelocity, velocity.abs());
A
Adam Barth 已提交
39
    _timeOffset = _timeAtVelocity(startingVelocity);
A
Adam Barth 已提交
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    _positionOffset = _positionAtTime(_timeOffset);
    _startTime = startTime / 1000.0;
    _previousPosition = 0.0;
    _direction = velocity.sign;
  }

  double update(double timeStamp) {
    double t = timeStamp / 1000.0 - _startTime + _timeOffset;
    if (t >= _kCurveDuration)
      return 0.0;
    double position = _positionAtTime(t) - _positionOffset;
    double positionDelta = position - _previousPosition;
    _previousPosition = position;
    return _direction * math.max(0.0, positionDelta);
  }
}