OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
6 import 'mechanics.dart'; | 6 import 'mechanics.dart'; |
7 import 'generators.dart'; | 7 import 'generators.dart'; |
8 | 8 |
9 const double _kScrollFriction = 0.005; | 9 const double _kScrollFriction = 0.005; |
10 const double _kOverscrollFriction = 0.075; | 10 const double _kOverscrollFriction = 0.075; |
(...skipping 16 matching lines...) Expand all Loading... |
27 double newScrollOffset = scrollOffset + scrollDelta; | 27 double newScrollOffset = scrollOffset + scrollDelta; |
28 if (minOffset != null) | 28 if (minOffset != null) |
29 newScrollOffset = math.max(minOffset, newScrollOffset); | 29 newScrollOffset = math.max(minOffset, newScrollOffset); |
30 if (maxOffset != null) | 30 if (maxOffset != null) |
31 newScrollOffset = math.min(maxOffset, newScrollOffset); | 31 newScrollOffset = math.min(maxOffset, newScrollOffset); |
32 return newScrollOffset; | 32 return newScrollOffset; |
33 } | 33 } |
34 } | 34 } |
35 | 35 |
36 class OverscrollBehavior extends ScrollBehavior { | 36 class OverscrollBehavior extends ScrollBehavior { |
| 37 |
| 38 double _contentsHeight; |
| 39 double get contentsHeight => _contentsHeight; |
| 40 void set contentsHeight (double value) { |
| 41 if (_contentsHeight != value) { |
| 42 _contentsHeight = value; |
| 43 // TODO(ianh) now what? what if we have a simulation ongoing? |
| 44 } |
| 45 } |
| 46 |
| 47 double _containerHeight; |
| 48 double get containerHeight => _containerHeight; |
| 49 void set containerHeight (double value) { |
| 50 if (_containerHeight != value) { |
| 51 _containerHeight = value; |
| 52 // TODO(ianh) now what? what if we have a simulation ongoing? |
| 53 } |
| 54 } |
| 55 |
| 56 OverscrollBehavior({double contentsHeight: 0.0, double containerHeight: 0.0}) |
| 57 : _contentsHeight = contentsHeight, |
| 58 _containerHeight = containerHeight; |
| 59 |
| 60 double get maxScroll => math.max(0.0, _contentsHeight - _containerHeight); |
| 61 |
37 Simulation release(Particle particle) { | 62 Simulation release(Particle particle) { |
38 System system; | 63 System system; |
39 if (particle.position >= 0.0) { | 64 if ((particle.position >= 0.0) && (particle.position < maxScroll)) { |
40 if (particle.velocity == 0.0) | 65 if (particle.velocity == 0.0) |
41 return null; | 66 return null; |
42 System slowdownSystem = new ParticleInBoxWithFriction( | 67 System slowdownSystem = new ParticleInBoxWithFriction( |
43 particle: particle, | 68 particle: particle, |
44 friction: _kScrollFriction, | 69 friction: _kScrollFriction, |
45 box: new GeofenceBox(min: 0.0, onEscape: () { | 70 box: new GeofenceBox(min: 0.0, max: maxScroll, onEscape: () { |
46 (system as Multisystem).transitionToSystem(new ParticleInBoxWithFricti
on( | 71 (system as Multisystem).transitionToSystem(new ParticleInBoxWithFricti
on( |
47 particle: particle, | 72 particle: particle, |
48 friction: _kOverscrollFriction, | 73 friction: _kOverscrollFriction, |
49 box: new ClosedBox(), | 74 box: new ClosedBox(), |
50 onStop: () => (system as Multisystem).transitionToSystem(getBounceBa
ckSystem(particle)) | 75 onStop: () => (system as Multisystem).transitionToSystem(getBounceBa
ckSystem(particle)) |
51 )); | 76 )); |
52 })); | 77 })); |
53 system = new Multisystem(particle: particle, system: slowdownSystem); | 78 system = new Multisystem(particle: particle, system: slowdownSystem); |
54 } else { | 79 } else { |
55 system = getBounceBackSystem(particle); | 80 system = getBounceBackSystem(particle); |
56 } | 81 } |
57 return new Simulation(system, terminationCondition: () => particle.position
== 0.0); | 82 return new Simulation(system, terminationCondition: () => particle.position
== 0.0); |
58 } | 83 } |
59 | 84 |
60 System getBounceBackSystem(Particle particle) { | 85 System getBounceBackSystem(Particle particle) { |
61 return new ParticleClimbingRamp( | 86 if (particle.position < 0.0) |
| 87 return new ParticleClimbingRamp( |
62 particle: particle, | 88 particle: particle, |
63 box: new ClosedBox(max: 0.0), | 89 box: new ClosedBox(max: 0.0), |
64 theta: _kBounceSlopeAngle, | 90 theta: _kBounceSlopeAngle, |
65 targetPosition: 0.0); | 91 targetPosition: 0.0); |
| 92 return new ParticleClimbingRamp( |
| 93 particle: particle, |
| 94 box: new ClosedBox(min: maxScroll), |
| 95 theta: _kBounceSlopeAngle, |
| 96 targetPosition: maxScroll); |
66 } | 97 } |
67 | 98 |
68 double applyCurve(double scrollOffset, double scrollDelta) { | 99 double applyCurve(double scrollOffset, double scrollDelta) { |
69 double newScrollOffset = scrollOffset + scrollDelta; | 100 double newScrollOffset = scrollOffset + scrollDelta; |
| 101 // If we're overscrolling, we want move the scroll offset 2x |
| 102 // slower than we would otherwise. Therefore, we "rewind" the |
| 103 // newScrollOffset by half the amount that we moved it above. |
| 104 // Notice that we clap the "old" value to 0.0 so that we only |
| 105 // reduce the portion of scrollDelta that's applied beyond 0.0. We |
| 106 // do similar things for overscroll in the other direction. |
70 if (newScrollOffset < 0.0) { | 107 if (newScrollOffset < 0.0) { |
71 // If we're overscrolling, we want move the scroll offset 2x slower than | |
72 // we would otherwise. Therefore, we "rewind" the newScrollOffset by half | |
73 // the amount that we moved it above. Notice that we clap the "old" value | |
74 // to 0.0 so that we only reduce the portion of scrollDelta that's applied | |
75 // beyond 0.0. | |
76 newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0; | 108 newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0; |
| 109 } else if (newScrollOffset > maxScroll) { |
| 110 newScrollOffset -= (newScrollOffset - math.max(maxScroll, scrollOffset)) /
2.0; |
77 } | 111 } |
78 return newScrollOffset; | 112 return newScrollOffset; |
79 } | 113 } |
80 } | 114 } |
OLD | NEW |