diff --git a/packages/newton/lib/src/scroll.dart b/packages/newton/lib/src/scroll.dart index c4a9fe6a74d..4b57b9f0af8 100644 --- a/packages/newton/lib/src/scroll.dart +++ b/packages/newton/lib/src/scroll.dart @@ -15,6 +15,7 @@ class Scroll extends SimulationGroup { bool _isSpringing = false; Simulation _currentSimulation; + double _offset = 0.0; Scroll(double position, double velocity, double leading, double trailing, SpringDesc spring, double drag) @@ -22,30 +23,43 @@ class Scroll extends SimulationGroup { _trailingExtent = trailing, _springDesc = spring, _drag = drag { - _chooseSimulation(position, velocity); + _chooseSimulation(position, velocity, 0.0); } @override void step(double time) => _chooseSimulation( - _currentSimulation.x(time), _currentSimulation.dx(time)); + _currentSimulation.x(time - _offset), + _currentSimulation.dx(time - _offset), time); @override Simulation get currentSimulation => _currentSimulation; - void _chooseSimulation(double position, double velocity) { - /// This simulation can only step forward + @override + double get currentIntervalOffset => _offset; + + void _chooseSimulation( + double position, double velocity, double intervalOffset) { + + /// This simulation can only step forward. if (!_isSpringing) { if (position > _trailingExtent) { _isSpringing = true; + _offset = intervalOffset; _currentSimulation = new Spring(_springDesc, position, _trailingExtent, velocity); + return; } else if (position < _leadingExtent) { _isSpringing = true; + _offset = intervalOffset; _currentSimulation = new Spring(_springDesc, position, _leadingExtent, velocity); + return; } - } else if (_currentSimulation == null) { + } + + if (_currentSimulation == null) { _currentSimulation = new Friction(_drag, position, velocity); + return; } } } diff --git a/packages/newton/lib/src/simulation_group.dart b/packages/newton/lib/src/simulation_group.dart index 29f9311b4f3..9fb6f9c3654 100644 --- a/packages/newton/lib/src/simulation_group.dart +++ b/packages/newton/lib/src/simulation_group.dart @@ -4,24 +4,31 @@ part of newton; -/// The abstract base class of all composite simulations. Concrete subclasses +/// The abstract base class for all composite simulations. Concrete subclasses /// must implement the appropriate methods to select the appropriate simulation /// at a given time interval. The simulation group takes care to call the `step` /// method at appropriate intervals. If more fine grained control over the the -/// step is necessary, subclasses may override the `Simulatable` methods. +/// step is necessary, subclasses may override `Simulatable` methods. abstract class SimulationGroup extends Simulation { + + /// The currently active simulation Simulation get currentSimulation; + /// The time offset applied to the currently active simulation; + double get currentIntervalOffset; + + /// Called when a significant change in the interval is detected. Subclasses + /// must decide if the the current simulation must be switched (or updated). void step(double time); double x(double time) { _stepIfNecessary(time); - return currentSimulation.x(time); + return currentSimulation.x(time - currentIntervalOffset); } double dx(double time) { _stepIfNecessary(time); - return currentSimulation.dx(time); + return currentSimulation.dx(time - currentIntervalOffset); } @override diff --git a/packages/newton/lib/src/spring_solution.dart b/packages/newton/lib/src/spring_solution.dart index fe57f7c08b5..7363a5d7846 100644 --- a/packages/newton/lib/src/spring_solution.dart +++ b/packages/newton/lib/src/spring_solution.dart @@ -34,7 +34,6 @@ class _CriticalSolution implements _SpringSolution { return new _CriticalSolution.withArgs(r, c1, c2); } - @override SpringType get type => SpringType.criticallyDamped; _CriticalSolution.withArgs(double r, double c1, double c2) @@ -72,7 +71,6 @@ class _OverdampedSolution implements _SpringSolution { _c1 = c1, _c2 = c2; - @override SpringType get type => SpringType.overDamped; double x(double time) => @@ -103,7 +101,6 @@ class _UnderdampedSolution implements _SpringSolution { _c1 = c1, _c2 = c2; - @override SpringType get type => SpringType.underDamped; double x(double time) => Math.pow(Math.E, _r * time) * diff --git a/packages/newton/test/newton_test.dart b/packages/newton/test/newton_test.dart index 8ef74e357f8..a568848eab5 100644 --- a/packages/newton/test/newton_test.dart +++ b/packages/newton/test/newton_test.dart @@ -132,4 +132,16 @@ void main() { expect(under.isDone(6.0), true); }); + + test('test_kinetic_scroll', () { + var spring = new SpringDesc.withDampingRatio(1.0, 50.0, 0.5); + + var scroll = new Scroll(100.0, 800.0, 0.0, 300.0, spring, 0.3); + + expect(scroll.isDone(0.0), false); + expect(scroll.isDone(3.5), true); + + var scroll2 = new Scroll(100.0, -800.0, 0.0, 300.0, spring, 0.3); + expect(scroll2.isDone(4.5), true); + }); }