| 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 | 6 |
| 7 import 'mechanics.dart'; | 7 import 'mechanics.dart'; |
| 8 import 'generators.dart'; | 8 import 'generators.dart'; |
| 9 | 9 |
| 10 const double _kScrollFriction = 0.005; | 10 const double _kScrollFriction = 0.005; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 // TODO(ianh) now what? what if we have a simulation ongoing? | 53 // TODO(ianh) now what? what if we have a simulation ongoing? |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 OverscrollBehavior({double contentsHeight: 0.0, double containerHeight: 0.0}) | 57 OverscrollBehavior({double contentsHeight: 0.0, double containerHeight: 0.0}) |
| 58 : _contentsHeight = contentsHeight, | 58 : _contentsHeight = contentsHeight, |
| 59 _containerHeight = containerHeight; | 59 _containerHeight = containerHeight; |
| 60 | 60 |
| 61 double get maxScrollOffset => math.max(0.0, _contentsHeight - _containerHeight
); | 61 double get maxScrollOffset => math.max(0.0, _contentsHeight - _containerHeight
); |
| 62 | 62 |
| 63 bool get contentsHeightIsKnown => _contentsHeight != null; |
| 64 |
| 63 Simulation release(Particle particle) { | 65 Simulation release(Particle particle) { |
| 64 System system; | 66 System system; |
| 65 if ((particle.position >= 0.0) && (particle.position < maxScrollOffset)) { | 67 if (contentsHeightIsKnown && particle.position >= 0.0 && particle.position <
maxScrollOffset) { |
| 66 if (particle.velocity == 0.0) | 68 if (particle.velocity == 0.0) |
| 67 return null; | 69 return null; |
| 68 System slowdownSystem = new ParticleInBoxWithFriction( | 70 System slowdownSystem = new ParticleInBoxWithFriction( |
| 69 particle: particle, | 71 particle: particle, |
| 70 friction: _kScrollFriction, | 72 friction: _kScrollFriction, |
| 71 box: new GeofenceBox(min: 0.0, max: maxScrollOffset, onEscape: () { | 73 box: new GeofenceBox(min: 0.0, max: maxScrollOffset, onEscape: () { |
| 72 (system as Multisystem).transitionToSystem(new ParticleInBoxWithFricti
on( | 74 (system as Multisystem).transitionToSystem(new ParticleInBoxWithFricti
on( |
| 73 particle: particle, | 75 particle: particle, |
| 74 friction: _kOverscrollFriction, | 76 friction: _kOverscrollFriction, |
| 75 box: new ClosedBox(), | 77 box: new ClosedBox(), |
| 76 onStop: () => (system as Multisystem).transitionToSystem(getBounceBa
ckSystem(particle)) | 78 onStop: () => (system as Multisystem).transitionToSystem(getBounceBa
ckSystem(particle)) |
| 77 )); | 79 )); |
| 78 })); | 80 })); |
| 79 system = new Multisystem(particle: particle, system: slowdownSystem); | 81 system = new Multisystem(particle: particle, system: slowdownSystem); |
| 82 } else if (contentsHeightIsKnown || particle.position < 0) { |
| 83 system = getBounceBackSystem(particle); |
| 80 } else { | 84 } else { |
| 81 system = getBounceBackSystem(particle); | 85 double maxParticlePosition = particle.position + containerHeight; |
| 86 if (particle.velocity == 0.0) |
| 87 return null; |
| 88 System slowdownSystem = new ParticleInBoxWithFriction( |
| 89 particle: particle, |
| 90 friction: _kScrollFriction, |
| 91 box: new GeofenceBox(min: 0.0, max: maxParticlePosition, onEscape: (){ }
) |
| 92 ); |
| 93 system = slowdownSystem; |
| 82 } | 94 } |
| 83 return new Simulation(system, terminationCondition: () => particle.position
== 0.0); | 95 return new Simulation(system, terminationCondition: () => particle.position
== 0.0); |
| 84 } | 96 } |
| 85 | 97 |
| 86 System getBounceBackSystem(Particle particle) { | 98 System getBounceBackSystem(Particle particle) { |
| 87 if (particle.position < 0.0) | 99 if (particle.position < 0.0) |
| 88 return new ParticleClimbingRamp( | 100 return new ParticleClimbingRamp( |
| 89 particle: particle, | 101 particle: particle, |
| 90 box: new ClosedBox(max: 0.0), | 102 box: new ClosedBox(max: 0.0), |
| 91 theta: _kBounceSlopeAngle, | 103 theta: _kBounceSlopeAngle, |
| 92 targetPosition: 0.0); | 104 targetPosition: 0.0); |
| 105 |
| 106 assert(contentsHeightIsKnown); |
| 93 return new ParticleClimbingRamp( | 107 return new ParticleClimbingRamp( |
| 94 particle: particle, | 108 particle: particle, |
| 95 box: new ClosedBox(min: maxScrollOffset), | 109 box: new ClosedBox(min: maxScrollOffset), |
| 96 theta: _kBounceSlopeAngle, | 110 theta: _kBounceSlopeAngle, |
| 97 targetPosition: maxScrollOffset); | 111 targetPosition: maxScrollOffset); |
| 98 } | 112 } |
| 99 | 113 |
| 100 double applyCurve(double scrollOffset, double scrollDelta) { | 114 double applyCurve(double scrollOffset, double scrollDelta) { |
| 101 double newScrollOffset = scrollOffset + scrollDelta; | 115 double newScrollOffset = scrollOffset + scrollDelta; |
| 102 // If we're overscrolling, we want move the scroll offset 2x | 116 // If we're overscrolling, we want move the scroll offset 2x |
| 103 // slower than we would otherwise. Therefore, we "rewind" the | 117 // slower than we would otherwise. Therefore, we "rewind" the |
| 104 // newScrollOffset by half the amount that we moved it above. | 118 // newScrollOffset by half the amount that we moved it above. |
| 105 // Notice that we clap the "old" value to 0.0 so that we only | 119 // Notice that we clamp the "old" value to 0.0 so that we only |
| 106 // reduce the portion of scrollDelta that's applied beyond 0.0. We | 120 // reduce the portion of scrollDelta that's applied beyond 0.0. We |
| 107 // do similar things for overscroll in the other direction. | 121 // do similar things for overscroll in the other direction. |
| 108 if (newScrollOffset < 0.0) { | 122 if (newScrollOffset < 0.0) { |
| 109 newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0; | 123 newScrollOffset -= (newScrollOffset - math.min(0.0, scrollOffset)) / 2.0; |
| 110 } else if (newScrollOffset > maxScrollOffset) { | 124 } else if (contentsHeightIsKnown && newScrollOffset > maxScrollOffset) { |
| 111 newScrollOffset -= (newScrollOffset - math.max(maxScrollOffset, scrollOffs
et)) / 2.0; | 125 newScrollOffset -= (newScrollOffset - math.max(maxScrollOffset, scrollOffs
et)) / 2.0; |
| 112 } | 126 } |
| 113 return newScrollOffset; | 127 return newScrollOffset; |
| 114 } | 128 } |
| 115 } | 129 } |
| OLD | NEW |