blob: 64e0a45ba112498effc4c6d1ef614f7d3c52a14f [file] [log] [blame]
// Copyright (c) 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.
part of newton;
/// Simulates kinetic scrolling behavior between a leading and trailing
/// boundary. Friction is applied within the extends and a spring action applied
/// at the boundaries. This simulation can only step forward.
class ScrollSimulation extends SimulationGroup {
ScrollSimulation(
double position,
double velocity,
this._leadingExtent,
this._trailingExtent,
this._spring,
this._drag) {
_chooseSimulation(position, velocity, 0.0);
}
final double _leadingExtent;
final double _trailingExtent;
final SpringDescription _spring;
final double _drag;
bool _isSpringing = false;
Simulation _currentSimulation;
double _offset = 0.0;
@override
bool step(double time) => _chooseSimulation(
_currentSimulation.x(time - _offset),
_currentSimulation.dx(time - _offset), time);
@override
Simulation get currentSimulation => _currentSimulation;
@override
double get currentIntervalOffset => _offset;
bool _chooseSimulation(double position, double velocity, double intervalOffset) {
if (_spring == null && (position > _trailingExtent || position < _leadingExtent))
return false;
/// This simulation can only step forward.
if (!_isSpringing) {
if (position > _trailingExtent) {
_isSpringing = true;
_offset = intervalOffset;
_currentSimulation = new ScrollSpringSimulation(_spring, position, _trailingExtent, velocity);
return true;
} else if (position < _leadingExtent) {
_isSpringing = true;
_offset = intervalOffset;
_currentSimulation = new ScrollSpringSimulation(_spring, position, _leadingExtent, velocity);
return true;
}
}
if (_currentSimulation == null) {
_currentSimulation = new FrictionSimulation(_drag, position, velocity);
return true;
}
return false;
}
}