/src/mozilla-central/layout/generic/ScrollAnimationMSDPhysics.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "ScrollAnimationMSDPhysics.h" |
8 | | #include "gfxPrefs.h" |
9 | | |
10 | | using namespace mozilla; |
11 | | |
12 | | ScrollAnimationMSDPhysics::ScrollAnimationMSDPhysics(const nsPoint& aStartPos) |
13 | | : mStartPos(aStartPos) |
14 | | , mModelX(0, 0, 0, gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant(), 1) |
15 | | , mModelY(0, 0, 0, gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant(), 1) |
16 | | , mIsFirstIteration(true) |
17 | 0 | { |
18 | 0 | } |
19 | | |
20 | | void |
21 | | ScrollAnimationMSDPhysics::Update(const TimeStamp& aTime, |
22 | | const nsPoint& aDestination, |
23 | | const nsSize& aCurrentVelocity) |
24 | 0 | { |
25 | 0 | double springConstant = ComputeSpringConstant(aTime); |
26 | 0 |
|
27 | 0 | // mLastSimulatedTime is the most recent time that this animation has been |
28 | 0 | // "observed" at. We don't want to update back to a state in the past, so we |
29 | 0 | // set mStartTime to the more recent of mLastSimulatedTime and aTime. |
30 | 0 | // aTime can be in the past if we're processing an input event whose internal |
31 | 0 | // timestamp is in the past. |
32 | 0 | if (mLastSimulatedTime && aTime < mLastSimulatedTime) { |
33 | 0 | mStartTime = mLastSimulatedTime; |
34 | 0 | } else { |
35 | 0 | mStartTime = aTime; |
36 | 0 | } |
37 | 0 |
|
38 | 0 | if (!mIsFirstIteration) { |
39 | 0 | mStartPos = PositionAt(mStartTime); |
40 | 0 | } |
41 | 0 |
|
42 | 0 | mLastSimulatedTime = mStartTime; |
43 | 0 | mDestination = aDestination; |
44 | 0 | mModelX = AxisPhysicsMSDModel(mStartPos.x, aDestination.x, |
45 | 0 | aCurrentVelocity.width, springConstant, 1); |
46 | 0 | mModelY = AxisPhysicsMSDModel(mStartPos.y, aDestination.y, |
47 | 0 | aCurrentVelocity.height, springConstant, 1); |
48 | 0 | mIsFirstIteration = false; |
49 | 0 | } |
50 | | |
51 | | double |
52 | | ScrollAnimationMSDPhysics::ComputeSpringConstant(const TimeStamp& aTime) |
53 | 0 | { |
54 | 0 | if (!mPreviousEventTime) { |
55 | 0 | mPreviousEventTime = aTime; |
56 | 0 | mPreviousDelta = TimeDuration(); |
57 | 0 | return gfxPrefs::SmoothScrollMSDPhysicsMotionBeginSpringConstant(); |
58 | 0 | } |
59 | 0 | |
60 | 0 | TimeDuration delta = aTime - mPreviousEventTime; |
61 | 0 | TimeDuration previousDelta = mPreviousDelta; |
62 | 0 |
|
63 | 0 | mPreviousEventTime = aTime; |
64 | 0 | mPreviousDelta = delta; |
65 | 0 |
|
66 | 0 | double deltaMS = delta.ToMilliseconds(); |
67 | 0 | if (deltaMS >= gfxPrefs::SmoothScrollMSDPhysicsContinuousMotionMaxDeltaMS()) { |
68 | 0 | return gfxPrefs::SmoothScrollMSDPhysicsMotionBeginSpringConstant(); |
69 | 0 | } |
70 | 0 | |
71 | 0 | if (previousDelta && |
72 | 0 | deltaMS >= gfxPrefs::SmoothScrollMSDPhysicsSlowdownMinDeltaMS() && |
73 | 0 | deltaMS >= previousDelta.ToMilliseconds() * gfxPrefs::SmoothScrollMSDPhysicsSlowdownMinDeltaRatio()) { |
74 | 0 | // The rate of events has slowed (the time delta between events has |
75 | 0 | // increased) enough that we think that the current scroll motion is coming |
76 | 0 | // to a stop. Use a stiffer spring in order to reach the destination more |
77 | 0 | // quickly. |
78 | 0 | return gfxPrefs::SmoothScrollMSDPhysicsSlowdownSpringConstant(); |
79 | 0 | } |
80 | 0 | |
81 | 0 | return gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant(); |
82 | 0 | } |
83 | | |
84 | | void |
85 | | ScrollAnimationMSDPhysics::SimulateUntil(const TimeStamp& aTime) |
86 | 0 | { |
87 | 0 | if (!mLastSimulatedTime || aTime < mLastSimulatedTime) { |
88 | 0 | return; |
89 | 0 | } |
90 | 0 | TimeDuration delta = aTime - mLastSimulatedTime; |
91 | 0 | mModelX.Simulate(delta); |
92 | 0 | mModelY.Simulate(delta); |
93 | 0 | mLastSimulatedTime = aTime; |
94 | 0 | } |
95 | | |
96 | | nsPoint |
97 | | ScrollAnimationMSDPhysics::PositionAt(const TimeStamp& aTime) |
98 | 0 | { |
99 | 0 | SimulateUntil(aTime); |
100 | 0 | return nsPoint(NSToCoordRound(mModelX.GetPosition()), |
101 | 0 | NSToCoordRound(mModelY.GetPosition())); |
102 | 0 | } |
103 | | |
104 | | nsSize |
105 | | ScrollAnimationMSDPhysics::VelocityAt(const TimeStamp& aTime) |
106 | 0 | { |
107 | 0 | SimulateUntil(aTime); |
108 | 0 | return nsSize(NSToCoordRound(mModelX.GetVelocity()), |
109 | 0 | NSToCoordRound(mModelY.GetVelocity())); |
110 | 0 | } |