tick method

bool tick(
  1. double dt
)

Advances by dt seconds. Returns whether value changed - false once the chase has come to rest (after snapping exactly onto the target once), so the owner can skip downstream work instead of re-rendering epsilon motion every frame under a motionless finger.

The frame is integrated in slices: semi-implicit Euler at this stiffness is stable only for steps under ~sqrt(stiffness)/0.83 seconds, and a 30 fps frame is already past that - one whole-frame step would make the chase diverge with growing oscillation instead of converging.

Implementation

bool tick(double dt) {
  if (_resting || dt <= 0) {
    return false;
  }
  final double maxStep = 0.25 / math.sqrt(stiffness);
  final double damping = 2 * math.sqrt(stiffness);
  double remaining = dt;
  while (remaining > 0) {
    final Offset delta = _target - value;
    if (delta.distanceSquared < 0.01 && velocity.distanceSquared < 0.25) {
      value = _target;
      velocity = .zero;
      _resting = true;
      return true;
    }
    final double h = remaining < maxStep ? remaining : maxStep;
    velocity += (delta * stiffness - velocity * damping) * h;
    value += velocity * h;
    remaining -= h;
  }
  return true;
}