mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 02:25:34 +00:00
Bug 776149: Fix Gecko panning code to account for time deltas for displacements r=cjones
This commit is contained in:
parent
0ff58775d6
commit
d9bf60609b
@ -427,8 +427,8 @@ float AsyncPanZoomController::PanDistance(const MultiTouchInput& aEvent) {
|
||||
SingleTouchData& touch = GetFirstSingleTouch(aEvent);
|
||||
nsIntPoint point = touch.mScreenPoint;
|
||||
PRInt32 xPos = point.x, yPos = point.y;
|
||||
mX.UpdateWithTouchAtDevicePoint(xPos, 0);
|
||||
mY.UpdateWithTouchAtDevicePoint(yPos, 0);
|
||||
mX.UpdateWithTouchAtDevicePoint(xPos, TimeDuration(0));
|
||||
mY.UpdateWithTouchAtDevicePoint(yPos, TimeDuration(0));
|
||||
return NS_hypot(mX.PanDistance(), mY.PanDistance()) * mFrameMetrics.mResolution.width;
|
||||
}
|
||||
|
||||
@ -442,10 +442,11 @@ const nsPoint AsyncPanZoomController::GetVelocityVector() {
|
||||
void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
|
||||
SingleTouchData& touch = GetFirstSingleTouch(aEvent);
|
||||
nsIntPoint point = touch.mScreenPoint;
|
||||
PRInt32 xPos = point.x, yPos = point.y, timeDelta = aEvent.mTime - mLastEventTime;
|
||||
PRInt32 xPos = point.x, yPos = point.y;
|
||||
TimeDuration timeDelta = TimeDuration().FromMilliseconds(aEvent.mTime - mLastEventTime);
|
||||
|
||||
// Probably a duplicate event, just throw it away.
|
||||
if (!timeDelta) {
|
||||
if (timeDelta.ToMilliseconds() <= EPSILON) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -458,8 +459,8 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
|
||||
// larger swipe should move you a shorter distance.
|
||||
float inverseScale = 1 / mFrameMetrics.mResolution.width;
|
||||
|
||||
PRInt32 xDisplacement = mX.UpdateAndGetDisplacement(inverseScale);
|
||||
PRInt32 yDisplacement = mY.UpdateAndGetDisplacement(inverseScale);
|
||||
PRInt32 xDisplacement = mX.GetDisplacementForDuration(inverseScale, timeDelta);
|
||||
PRInt32 yDisplacement = mY.GetDisplacementForDuration(inverseScale, timeDelta);
|
||||
if (!xDisplacement && !yDisplacement) {
|
||||
return;
|
||||
}
|
||||
@ -494,8 +495,8 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
|
||||
float inverseScale = 1 / mFrameMetrics.mResolution.width;
|
||||
|
||||
ScrollBy(nsIntPoint(
|
||||
mX.UpdateAndGetDisplacement(inverseScale),
|
||||
mY.UpdateAndGetDisplacement(inverseScale)
|
||||
mX.GetDisplacementForDuration(inverseScale, aDelta),
|
||||
mY.GetDisplacementForDuration(inverseScale, aDelta)
|
||||
));
|
||||
RequestContentRepaint();
|
||||
|
||||
|
@ -10,13 +10,7 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static const float EPSILON = 0.0001;
|
||||
|
||||
/**
|
||||
* Milliseconds per frame, used to judge how much displacement should have
|
||||
* happened every frame based on the velocity calculated from touch events.
|
||||
*/
|
||||
static const float MS_PER_FRAME = 1000.0f / 60.0f;
|
||||
static const float EPSILON = 0.0001f;
|
||||
|
||||
/**
|
||||
* Maximum acceleration that can happen between two frames. Velocity is
|
||||
@ -24,31 +18,31 @@ static const float MS_PER_FRAME = 1000.0f / 60.0f;
|
||||
* or we get a touch point very far away from the previous position for some
|
||||
* reason.
|
||||
*/
|
||||
static const float MAX_EVENT_ACCELERATION = 12;
|
||||
static const float MAX_EVENT_ACCELERATION = 0.5f;
|
||||
|
||||
/**
|
||||
* Amount of friction applied during flings when going above
|
||||
* VELOCITY_THRESHOLD.
|
||||
*/
|
||||
static const float FLING_FRICTION_FAST = 0.010;
|
||||
static const float FLING_FRICTION_FAST = 0.010f;
|
||||
|
||||
/**
|
||||
* Amount of friction applied during flings when going below
|
||||
* VELOCITY_THRESHOLD.
|
||||
*/
|
||||
static const float FLING_FRICTION_SLOW = 0.008;
|
||||
static const float FLING_FRICTION_SLOW = 0.008f;
|
||||
|
||||
/**
|
||||
* Maximum velocity before fling friction increases.
|
||||
*/
|
||||
static const float VELOCITY_THRESHOLD = 10;
|
||||
static const float VELOCITY_THRESHOLD = 0.5f;
|
||||
|
||||
/**
|
||||
* When flinging, if the velocity goes below this number, we just stop the
|
||||
* animation completely. This is to prevent asymptotically approaching 0
|
||||
* velocity and rerendering unnecessarily.
|
||||
*/
|
||||
static const float FLING_STOPPED_THRESHOLD = 0.1f;
|
||||
static const float FLING_STOPPED_THRESHOLD = 0.01f;
|
||||
|
||||
Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
: mPos(0.0f),
|
||||
@ -58,10 +52,10 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
|
||||
}
|
||||
|
||||
void Axis::UpdateWithTouchAtDevicePoint(PRInt32 aPos, PRInt32 aTimeDelta) {
|
||||
float newVelocity = MS_PER_FRAME * (mPos - aPos) / aTimeDelta;
|
||||
void Axis::UpdateWithTouchAtDevicePoint(PRInt32 aPos, const TimeDuration& aTimeDelta) {
|
||||
float newVelocity = (mPos - aPos) / aTimeDelta.ToMilliseconds();
|
||||
|
||||
bool curVelocityIsLow = fabsf(newVelocity) < 1.0f;
|
||||
bool curVelocityIsLow = fabsf(newVelocity) < 0.01f;
|
||||
bool directionChange = (mVelocity > 0) != (newVelocity != 0);
|
||||
|
||||
// If a direction change has happened, or the current velocity due to this new
|
||||
@ -69,7 +63,7 @@ void Axis::UpdateWithTouchAtDevicePoint(PRInt32 aPos, PRInt32 aTimeDelta) {
|
||||
if (curVelocityIsLow || (directionChange && fabs(newVelocity) - EPSILON <= 0.0f)) {
|
||||
mVelocity = newVelocity;
|
||||
} else {
|
||||
float maxChange = fabsf(mVelocity * aTimeDelta * MAX_EVENT_ACCELERATION);
|
||||
float maxChange = fabsf(mVelocity * aTimeDelta.ToMilliseconds() * MAX_EVENT_ACCELERATION);
|
||||
mVelocity = NS_MIN(mVelocity + maxChange, NS_MAX(mVelocity - maxChange, newVelocity));
|
||||
}
|
||||
|
||||
@ -83,8 +77,8 @@ void Axis::StartTouch(PRInt32 aPos) {
|
||||
mVelocity = 0.0f;
|
||||
}
|
||||
|
||||
PRInt32 Axis::UpdateAndGetDisplacement(float aScale) {
|
||||
PRInt32 displacement = NS_lround(mVelocity * aScale);
|
||||
PRInt32 Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) {
|
||||
PRInt32 displacement = NS_lround(mVelocity * aScale * aDelta.ToMilliseconds());
|
||||
// If this displacement will cause an overscroll, throttle it. Can potentially
|
||||
// bring it to 0 even if the velocity is high.
|
||||
if (DisplacementWillOverscroll(displacement) != OVERSCROLL_NONE) {
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
* indicating how long it has been since the previous one. This triggers a
|
||||
* recalculation of velocity.
|
||||
*/
|
||||
void UpdateWithTouchAtDevicePoint(PRInt32 aPos, PRInt32 aTimeDelta);
|
||||
void UpdateWithTouchAtDevicePoint(PRInt32 aPos, const TimeDuration& aTimeDelta);
|
||||
|
||||
/**
|
||||
* Notify this Axis that a touch has begun, i.e. the user has put their finger
|
||||
@ -61,14 +61,14 @@ public:
|
||||
/**
|
||||
* Gets displacement that should have happened since the previous touch.
|
||||
* Note: Does not reset the displacement. It gets recalculated on the next
|
||||
* updateWithTouchAtDevicePoint(), however it is not safe to assume this will
|
||||
* UpdateWithTouchAtDevicePoint(), however it is not safe to assume this will
|
||||
* be the same on every call. This also checks for page boundaries and will
|
||||
* return an adjusted displacement to prevent the viewport from overscrolling
|
||||
* the page rect. An example of where this might matter is when you call it,
|
||||
* apply a displacement that takes you to the boundary of the page, then call
|
||||
* it again. The result will be different in this case.
|
||||
*/
|
||||
PRInt32 UpdateAndGetDisplacement(float aScale);
|
||||
PRInt32 GetDisplacementForDuration(float aScale, const TimeDuration& aDelta);
|
||||
|
||||
/**
|
||||
* Gets the distance between the starting position of the touch supplied in
|
||||
|
Loading…
Reference in New Issue
Block a user