mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
We now use a physics simulationt to drive the scroll fling. We're also closer to integrating fling into overscroll. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1004363002
69 lines
2.2 KiB
Dart
69 lines
2.2 KiB
Dart
// 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;
|
|
}
|
|
}
|