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_layout_ScrollAnimationBezierPhysics_h_ 8 #define mozilla_layout_ScrollAnimationBezierPhysics_h_ 9 10 #include "ScrollAnimationPhysics.h" 11 #include "nsSMILKeySpline.h" 12 13 namespace mozilla { 14 15 struct ScrollAnimationBezierPhysicsSettings { 16 // These values are minimum and maximum animation duration per event, 17 // and a global ratio which defines how longer is the animation's duration 18 // compared to the average recent events intervals (such that for a relatively 19 // consistent events rate, the next event arrives before current animation 20 // ends) 21 int32_t mMinMS; 22 int32_t mMaxMS; 23 double mIntervalRatio; 24 }; 25 26 // This class implements a cubic bezier timing function and automatically 27 // adapts the animation duration based on the scrolling rate. 28 class ScrollAnimationBezierPhysics : public ScrollAnimationPhysics { 29 public: 30 explicit ScrollAnimationBezierPhysics( 31 const nsPoint& aStartPos, 32 const ScrollAnimationBezierPhysicsSettings& aSettings); 33 34 void Update(const TimeStamp& aTime, const nsPoint& aDestination, 35 const nsSize& aCurrentVelocity) override; 36 37 // Get the velocity at a point in time in nscoords/sec. 38 nsSize VelocityAt(const TimeStamp& aTime) override; 39 40 // Returns the expected scroll position at a given point in time, in app 41 // units, relative to the scroll frame. 42 nsPoint PositionAt(const TimeStamp& aTime) override; 43 IsFinished(const TimeStamp & aTime)44 bool IsFinished(const TimeStamp& aTime) override { 45 return aTime > mStartTime + mDuration; 46 } 47 48 protected: ProgressAt(const TimeStamp & aTime)49 double ProgressAt(const TimeStamp& aTime) const { 50 return clamped((aTime - mStartTime) / mDuration, 0.0, 1.0); 51 } 52 53 nscoord VelocityComponent(double aTimeProgress, 54 const nsSMILKeySpline& aTimingFunction, 55 nscoord aStart, nscoord aDestination) const; 56 57 // Calculate duration, possibly dynamically according to events rate and 58 // event origin. (also maintain previous timestamps - which are only used 59 // here). 60 TimeDuration ComputeDuration(const TimeStamp& aTime); 61 62 // Initializes the timing function in such a way that the current velocity is 63 // preserved. 64 void InitTimingFunction(nsSMILKeySpline& aTimingFunction, nscoord aCurrentPos, 65 nscoord aCurrentVelocity, nscoord aDestination); 66 67 // Initialize event history. 68 void InitializeHistory(const TimeStamp& aTime); 69 70 // Cached Preferences values. 71 ScrollAnimationBezierPhysicsSettings mSettings; 72 73 // mPrevEventTime holds previous 3 timestamps for intervals averaging (to 74 // reduce duration fluctuations). When AsyncScroll is constructed and no 75 // previous timestamps are available (indicated with mIsFirstIteration), 76 // initialize mPrevEventTime using imaginary previous timestamps with maximum 77 // relevant intervals between them. 78 TimeStamp mPrevEventTime[3]; 79 80 TimeStamp mStartTime; 81 82 nsPoint mStartPos; 83 nsPoint mDestination; 84 TimeDuration mDuration; 85 nsSMILKeySpline mTimingFunctionX; 86 nsSMILKeySpline mTimingFunctionY; 87 bool mIsFirstIteration; 88 }; 89 90 } // namespace mozilla 91 92 #endif // mozilla_layout_ScrollAnimationBezierPhysics_h_ 93