| 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 |