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 "mozilla/SMILKeySpline.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 final : 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 void ApplyContentShift(const CSSPoint& aShiftDelta) override; 38 39 // Get the velocity at a point in time in nscoords/sec. 40 nsSize VelocityAt(const TimeStamp& aTime) override; 41 42 // Returns the expected scroll position at a given point in time, in app 43 // units, relative to the scroll frame. 44 nsPoint PositionAt(const TimeStamp& aTime) override; 45 IsFinished(const TimeStamp & aTime)46 bool IsFinished(const TimeStamp& aTime) override { 47 return aTime > mStartTime + mDuration; 48 } 49 50 protected: ProgressAt(const TimeStamp & aTime)51 double ProgressAt(const TimeStamp& aTime) const { 52 return clamped((aTime - mStartTime) / mDuration, 0.0, 1.0); 53 } 54 55 nscoord VelocityComponent(double aTimeProgress, 56 const SMILKeySpline& aTimingFunction, 57 nscoord aStart, nscoord aDestination) const; 58 59 // Calculate duration, possibly dynamically according to events rate and 60 // event origin. (also maintain previous timestamps - which are only used 61 // here). 62 TimeDuration ComputeDuration(const TimeStamp& aTime); 63 64 // Initializes the timing function in such a way that the current velocity is 65 // preserved. 66 void InitTimingFunction(SMILKeySpline& aTimingFunction, nscoord aCurrentPos, 67 nscoord aCurrentVelocity, nscoord aDestination); 68 69 // Initialize event history. 70 void InitializeHistory(const TimeStamp& aTime); 71 72 // Cached Preferences values. 73 ScrollAnimationBezierPhysicsSettings mSettings; 74 75 // mPrevEventTime holds previous 3 timestamps for intervals averaging (to 76 // reduce duration fluctuations). When AsyncScroll is constructed and no 77 // previous timestamps are available (indicated with mIsFirstIteration), 78 // initialize mPrevEventTime using imaginary previous timestamps with maximum 79 // relevant intervals between them. 80 TimeStamp mPrevEventTime[3]; 81 82 TimeStamp mStartTime; 83 84 nsPoint mStartPos; 85 nsPoint mDestination; 86 TimeDuration mDuration; 87 SMILKeySpline mTimingFunctionX; 88 SMILKeySpline mTimingFunctionY; 89 bool mIsFirstIteration; 90 }; 91 92 } // namespace mozilla 93 94 #endif // mozilla_layout_ScrollAnimationBezierPhysics_h_ 95