зеркало из https://github.com/mozilla/gecko-dev.git
Bug 701594 - Part 1: Precompute the ease-out animation. r=kats
This commit is contained in:
Родитель
e74361d640
Коммит
017d92c57f
|
@ -43,4 +43,13 @@ public final class FloatUtils {
|
|||
public static boolean fuzzyEquals(float a, float b) {
|
||||
return (Math.abs(a - b) < 1e-6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value that represents a linear transition between `from` and `to` at time `t`,
|
||||
* which is on the scale [0, 1). Thus with t = 0.0f, this returns `from`; with t = 1.0f, this
|
||||
* returns `to`; with t = 0.5f, this returns the value halfway from `from` to `to`.
|
||||
*/
|
||||
public static float interpolate(float from, float to, float t) {
|
||||
return from + (to - from) * t;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.FloatUtils;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import java.lang.Math;
|
||||
|
@ -62,8 +63,8 @@ public final class PointUtils {
|
|||
* of each of the original points (weight = 1 returns endPoint, weight = 0 returns startPoint)
|
||||
*/
|
||||
public static PointF interpolate(PointF startPoint, PointF endPoint, float weight) {
|
||||
float x = (startPoint.x-endPoint.x)*weight + endPoint.x;
|
||||
float y = (startPoint.y-endPoint.y)*weight + endPoint.y;
|
||||
float x = FloatUtils.interpolate(startPoint.x, endPoint.x, weight);
|
||||
float y = FloatUtils.interpolate(startPoint.y, endPoint.y, weight);
|
||||
return new PointF(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,11 +80,6 @@ public class PanZoomController
|
|||
private static final float SNAP_LIMIT = 0.75f;
|
||||
// The rate of deceleration when the surface has overscrolled.
|
||||
private static final float OVERSCROLL_DECEL_RATE = 0.04f;
|
||||
// The duration of animation when bouncing back.
|
||||
private static final int SNAP_TIME = 240;
|
||||
// The number of subdivisions we should consider when plotting the ease-out transition. Higher
|
||||
// values make the animation more accurate, but slower to plot.
|
||||
private static final int SUBDIVISION_COUNT = 1000;
|
||||
// The distance the user has to pan before we recognize it as such (e.g. to avoid
|
||||
// 1-pixel pans between the touch-down and touch-up of a click). In units of inches.
|
||||
private static final float PAN_THRESHOLD = 0.1f;
|
||||
|
@ -96,6 +91,26 @@ public class PanZoomController
|
|||
// Length of time to spend zooming. in ms
|
||||
public static final int ZOOM_DURATION = 200;
|
||||
|
||||
/* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */
|
||||
private static final float[] EASE_OUT_ANIMATION_FRAMES = {
|
||||
0.00000f, /* 0 */
|
||||
0.10211f, /* 1 */
|
||||
0.19864f, /* 2 */
|
||||
0.29043f, /* 3 */
|
||||
0.37816f, /* 4 */
|
||||
0.46155f, /* 5 */
|
||||
0.54054f, /* 6 */
|
||||
0.61496f, /* 7 */
|
||||
0.68467f, /* 8 */
|
||||
0.74910f, /* 9 */
|
||||
0.80794f, /* 10 */
|
||||
0.86069f, /* 11 */
|
||||
0.90651f, /* 12 */
|
||||
0.94471f, /* 13 */
|
||||
0.97401f, /* 14 */
|
||||
0.99309f, /* 15 */
|
||||
};
|
||||
|
||||
private Timer mFlingTimer;
|
||||
private Axis mX, mY;
|
||||
/* The zoom focus at the first zoom event (in page coordinates). */
|
||||
|
@ -599,7 +614,6 @@ public class PanZoomController
|
|||
public boolean disableSnap; /* Whether overscroll snapping is disabled. */
|
||||
|
||||
private FlingStates mFlingState; /* The fling state we're in on this axis. */
|
||||
private EaseOutAnimation mSnapAnim; /* The animation when the page is snapping back. */
|
||||
|
||||
/* These three need to be kept in sync with the layer controller. */
|
||||
private float viewportPos;
|
||||
|
@ -608,7 +622,11 @@ public class PanZoomController
|
|||
private float mPageLength;
|
||||
|
||||
public float displacement;
|
||||
private float mSnapPosition;
|
||||
|
||||
private int mSnapFrame;
|
||||
private float mSnapPos, mSnapEndPos;
|
||||
|
||||
public Axis() { mSnapFrame = -1; }
|
||||
|
||||
public FlingStates getFlingState() { return mFlingState; }
|
||||
|
||||
|
@ -709,10 +727,12 @@ public class PanZoomController
|
|||
public void startSnap() {
|
||||
switch (getOverscroll()) {
|
||||
case MINUS:
|
||||
mSnapAnim = new EaseOutAnimation(0, getExcess());
|
||||
mSnapFrame = 0;
|
||||
mSnapEndPos = getExcess();
|
||||
break;
|
||||
case PLUS:
|
||||
mSnapAnim = new EaseOutAnimation(0, -getExcess());
|
||||
mSnapFrame = 0;
|
||||
mSnapEndPos = -getExcess();
|
||||
break;
|
||||
default:
|
||||
// no overscroll to deal with, so we're done
|
||||
|
@ -721,20 +741,26 @@ public class PanZoomController
|
|||
}
|
||||
|
||||
displacement = 0;
|
||||
mSnapPosition = mSnapAnim.getPosition();
|
||||
mSnapPos = 0.0f;
|
||||
setFlingState(FlingStates.SNAPPING);
|
||||
}
|
||||
|
||||
// Performs one frame of a snap-into-place operation.
|
||||
private void snap() {
|
||||
mSnapAnim.advance();
|
||||
displacement += mSnapAnim.getPosition() - mSnapPosition;
|
||||
mSnapPosition = mSnapAnim.getPosition();
|
||||
mSnapFrame++;
|
||||
if (mSnapFrame == EASE_OUT_ANIMATION_FRAMES.length) {
|
||||
mSnapFrame = -1;
|
||||
displacement += mSnapEndPos - mSnapPos;
|
||||
mSnapPos = mSnapEndPos;
|
||||
|
||||
if (mSnapAnim.getFinished()) {
|
||||
mSnapAnim = null;
|
||||
setFlingState(FlingStates.STOPPED);
|
||||
return;
|
||||
}
|
||||
|
||||
float t = EASE_OUT_ANIMATION_FRAMES[mSnapFrame];
|
||||
float newSnapPos = FloatUtils.interpolate(0.0f, mSnapEndPos, t);
|
||||
displacement += newSnapPos - mSnapPos;
|
||||
mSnapPos = newSnapPos;
|
||||
}
|
||||
|
||||
// Performs displacement of the viewport position according to the current velocity.
|
||||
|
@ -749,66 +775,6 @@ public class PanZoomController
|
|||
}
|
||||
}
|
||||
|
||||
private static class EaseOutAnimation {
|
||||
private float[] mFrames;
|
||||
private float mPosition;
|
||||
private float mOrigin;
|
||||
private float mDest;
|
||||
private long mTimestamp;
|
||||
private boolean mFinished;
|
||||
|
||||
public EaseOutAnimation(float position, float dest) {
|
||||
mPosition = mOrigin = position;
|
||||
mDest = dest;
|
||||
mFrames = new float[SNAP_TIME];
|
||||
mTimestamp = System.currentTimeMillis();
|
||||
mFinished = false;
|
||||
plot(position, dest, mFrames);
|
||||
}
|
||||
|
||||
public float getPosition() { return mPosition; }
|
||||
public boolean getFinished() { return mFinished; }
|
||||
|
||||
private void advance() {
|
||||
int frame = (int)(System.currentTimeMillis() - mTimestamp);
|
||||
if (frame >= SNAP_TIME) {
|
||||
mPosition = mDest;
|
||||
mFinished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mPosition = mFrames[frame];
|
||||
}
|
||||
|
||||
private static void plot(float from, float to, float[] frames) {
|
||||
int nextX = 0;
|
||||
for (int i = 0; i < SUBDIVISION_COUNT; i++) {
|
||||
float t = (float)i / (float)SUBDIVISION_COUNT;
|
||||
float xPos = (3.0f*t*t - 2.0f*t*t*t) * (float)frames.length;
|
||||
if ((int)xPos < nextX)
|
||||
continue;
|
||||
|
||||
int oldX = nextX;
|
||||
nextX = (int)xPos;
|
||||
|
||||
float yPos = 1.74f*t*t - 0.74f*t*t*t;
|
||||
float framePos = from + (to - from) * yPos;
|
||||
|
||||
while (oldX < nextX)
|
||||
frames[oldX++] = framePos;
|
||||
|
||||
if (nextX >= frames.length)
|
||||
break;
|
||||
}
|
||||
|
||||
// Pad out any remaining frames.
|
||||
while (nextX < frames.length) {
|
||||
frames[nextX] = frames[nextX - 1];
|
||||
nextX++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Zooming
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче