1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_DesktopFlingPhysics_h_ 8 #define mozilla_layers_DesktopFlingPhysics_h_ 9 10 #include "AsyncPanZoomController.h" 11 #include "Units.h" 12 #include "mozilla/Assertions.h" 13 #include "mozilla/StaticPrefs_apz.h" 14 15 namespace mozilla { 16 namespace layers { 17 18 class DesktopFlingPhysics { 19 public: Init(const ParentLayerPoint & aStartingVelocity,float aPLPPI)20 void Init(const ParentLayerPoint& aStartingVelocity, 21 float aPLPPI /* unused */) { 22 mVelocity = aStartingVelocity; 23 } Sample(const TimeDuration & aDelta,ParentLayerPoint * aOutVelocity,ParentLayerPoint * aOutOffset)24 void Sample(const TimeDuration& aDelta, ParentLayerPoint* aOutVelocity, 25 ParentLayerPoint* aOutOffset) { 26 float friction = StaticPrefs::apz_fling_friction(); 27 float threshold = StaticPrefs::apz_fling_stopped_threshold(); 28 29 mVelocity = ParentLayerPoint( 30 ApplyFrictionOrCancel(mVelocity.x, aDelta, friction, threshold), 31 ApplyFrictionOrCancel(mVelocity.y, aDelta, friction, threshold)); 32 33 *aOutVelocity = mVelocity; 34 *aOutOffset = mVelocity * aDelta.ToMilliseconds(); 35 } 36 37 private: 38 /** 39 * Applies friction to the given velocity and returns the result, or 40 * returns zero if the velocity is too low. 41 * |aVelocity| is the incoming velocity. 42 * |aDelta| is the amount of time that has passed since the last time 43 * friction was applied. 44 * |aFriction| is the amount of friction to apply. 45 * |aThreshold| is the velocity below which the fling is cancelled. 46 */ ApplyFrictionOrCancel(float aVelocity,const TimeDuration & aDelta,float aFriction,float aThreshold)47 static float ApplyFrictionOrCancel(float aVelocity, 48 const TimeDuration& aDelta, 49 float aFriction, float aThreshold) { 50 if (fabsf(aVelocity) <= aThreshold) { 51 // If the velocity is very low, just set it to 0 and stop the fling, 52 // otherwise we'll just asymptotically approach 0 and the user won't 53 // actually see any changes. 54 return 0.0f; 55 } 56 57 aVelocity *= pow(1.0f - aFriction, float(aDelta.ToMilliseconds())); 58 return aVelocity; 59 } 60 61 ParentLayerPoint mVelocity; 62 }; 63 64 } // namespace layers 65 } // namespace mozilla 66 67 #endif // mozilla_layers_DesktopFlingPhysics_h_ 68