blob: fcc65a43e3892e1002da56e884c3874fc741036d [file] [log] [blame] [edit]
// 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;
import 'mechanics.dart';
import 'generators.dart';
const double _kSlope = 0.02;
const double _kFriction = 0.004;
abstract class ScrollBehavior {
Simulation release(Particle particle) => null;
// Returns the new scroll offset.
double applyCurve(double scrollOffset, double scrollDelta);
}
class BoundedScrollBehavior extends ScrollBehavior {
double minOffset;
double maxOffset;
BoundedScrollBehavior({this.minOffset: 0.0, this.maxOffset});
double applyCurve(double scrollOffset, double scrollDelta) {
double newScrollOffset = scrollOffset + scrollDelta;
if (minOffset != null)
newScrollOffset = math.max(minOffset, newScrollOffset);
if (maxOffset != null)
newScrollOffset = math.min(maxOffset, newScrollOffset);
return newScrollOffset;
}
}
class OverscrollBehavior extends ScrollBehavior {
Simulation release(Particle particle) {
if (particle.position >= 0.0) {
if (particle.velocity == 0.0)
return null;
System system = new ParticleInBoxWithFriction(
particle: particle,
box: new Box(min: 0.0),
friction: _kFriction);
return new Simulation(system,
terminationCondition: () => particle.velocity == 0.0);
}
System system = new ParticleClimbingRamp(
particle: particle,
box: new Box(max: 0.0),
slope: _kSlope,
targetPosition: 0.0);
return new Simulation(system,
terminationCondition: () => particle.position == 0.0);
}
double applyCurve(double scrollOffset, double scrollDelta) {
double newScrollOffset = scrollOffset + scrollDelta;
if (newScrollOffset < 0.0) {
// If we're overscrolling, we want move the scroll offset 2x slower than
// we would otherwise. Therefore, we "rewind" the newScrollOffset by half
// the amount that we moved it above. Notice that we clap the "old" value
// to 0.0 so that we only reduce the portion of scrollDelta that's applied
// beyond 0.0.
newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0;
}
return newScrollOffset;
}
}