improve MapViewAnimation

This commit is contained in:
Hannes Janetzek 2013-03-13 15:26:53 +01:00
parent 064434896e
commit 555a951d25
2 changed files with 62 additions and 97 deletions

View File

@ -32,7 +32,7 @@ import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.view.animation.DecelerateInterpolator; import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
import android.widget.Scroller; import android.widget.Scroller;
@ -158,7 +158,6 @@ public class MapViewPosition {
&& pos.tilt == mTilt) && pos.tilt == mTilt)
return false; return false;
pos.lat = mLatitude; pos.lat = mLatitude;
pos.lon = mLongitude; pos.lon = mLongitude;
pos.angle = mRotation; pos.angle = mRotation;
@ -166,7 +165,7 @@ public class MapViewPosition {
// for tiling // for tiling
pos.scale = scale; pos.scale = scale;
pos.zoomLevel = (byte)z; pos.zoomLevel = (byte) z;
pos.x = mAbsX * (Tile.TILE_SIZE << z); pos.x = mAbsX * (Tile.TILE_SIZE << z);
pos.y = mAbsY * (Tile.TILE_SIZE << z); pos.y = mAbsY * (Tile.TILE_SIZE << z);
@ -271,7 +270,7 @@ public class MapViewPosition {
z = FastMath.clamp(z, MIN_ZOOMLEVEL, MAX_ZOOMLEVEL); z = FastMath.clamp(z, MIN_ZOOMLEVEL, MAX_ZOOMLEVEL);
float scale = (float) (mAbsScale / (1 << z)); float scale = (float) (mAbsScale / (1 << z));
return new MapPosition(mLatitude, mLongitude, (byte)z, scale, mRotation); return new MapPosition(mLatitude, mLongitude, (byte) z, scale, mRotation);
} }
/** /**
@ -672,7 +671,7 @@ public class MapViewPosition {
private boolean mAnimMove; private boolean mAnimMove;
private boolean mAnimFling; private boolean mAnimFling;
private boolean mAnimScale; private boolean mAnimScale;
private final DecelerateInterpolator mDecInterpolator = new DecelerateInterpolator(2); private final AccelerateDecelerateInterpolator mDecInterpolator = new AccelerateDecelerateInterpolator();
public synchronized void animateTo(BoundingBox bbox) { public synchronized void animateTo(BoundingBox bbox) {
double dx = MercatorProjection.longitudeToX(bbox.getMaxLongitude()) double dx = MercatorProjection.longitudeToX(bbox.getMaxLongitude())
@ -680,7 +679,6 @@ public class MapViewPosition {
double dy = MercatorProjection.latitudeToY(bbox.getMinLatitude()) double dy = MercatorProjection.latitudeToY(bbox.getMinLatitude())
- MercatorProjection.latitudeToY(bbox.getMaxLatitude()); - MercatorProjection.latitudeToY(bbox.getMaxLatitude());
double z = Math.min( double z = Math.min(
-LOG4 * Math.log(dx) + (mWidth / Tile.TILE_SIZE), -LOG4 * Math.log(dx) + (mWidth / Tile.TILE_SIZE),
-LOG4 * Math.log(dy) + (mHeight / Tile.TILE_SIZE)); -LOG4 * Math.log(dy) + (mHeight / Tile.TILE_SIZE));
@ -716,43 +714,29 @@ public class MapViewPosition {
mAnimFling = false; mAnimFling = false;
mDuration = 500; mDuration = 500;
// double mx = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(),
// (byte) ABS_ZOOMLEVEL);
// double my = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(),
// (byte) ABS_ZOOMLEVEL);
//
// double f = Tile.TILE_SIZE << ABS_ZOOMLEVEL;
// double x = mAbsX * f;
// double y = mAbsY * f;
//
// mScroller.startScroll((int) x, (int) y, (int) (mx - x), (int) (my - y), (int) mDuration);
// mFling = false;
mHandler.start((int) mDuration); mHandler.start((int) mDuration);
} }
public synchronized void animateTo(GeoPoint geoPoint) { public synchronized void animateTo(GeoPoint geoPoint) {
double mx = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(),
(byte) ABS_ZOOMLEVEL);
double my = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(),
(byte) ABS_ZOOMLEVEL);
double f = Tile.TILE_SIZE << ABS_ZOOMLEVEL; double f = Tile.TILE_SIZE << ABS_ZOOMLEVEL;
double x = mAbsX * f;
double y = mAbsY * f;
mScroller.startScroll((int) x, (int) y, (int) (mx - x), (int) (my - y), (int) mDuration); mStartX = mAbsX * f;
mStartY = mAbsY * f;
mAnimFling = false; mEndX = MercatorProjection.longitudeToX(geoPoint.getLongitude()) * f;
mEndY = MercatorProjection.latitudeToY(geoPoint.getLatitude()) * f;
mEndX -= mStartX;
mEndY -= mStartY;
mAnimMove = true;
mAnimScale = false; mAnimScale = false;
mAnimMove = false; mAnimFling = false;
mDuration = 300; mDuration = 300;
mHandler.start((int) mDuration); mHandler.start(mDuration);
} }
public synchronized void animateFling(int velocityX, int velocityY, public synchronized void animateFling(int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY) { int minX, int maxX, int minY, int maxY) {
@ -767,7 +751,7 @@ public class MapViewPosition {
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); //mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
mDuration = 250; mDuration = 250;
mHandler.start((int) mDuration); mHandler.start(mDuration);
} }
public synchronized void animateZoom(float scale) { public synchronized void animateZoom(float scale) {
@ -777,7 +761,7 @@ public class MapViewPosition {
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); //mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
mDuration = 300; mDuration = 300;
mHandler.start((int) mDuration); mHandler.start(mDuration);
} }
public void updateAnimation() { public void updateAnimation() {
@ -793,7 +777,6 @@ public class MapViewPosition {
double dx = mScroller.getCurrX(); double dx = mScroller.getCurrX();
double dy = mScroller.getCurrY(); double dy = mScroller.getCurrY();
if (mAnimFling) {
int mx = (int) (dx - mScrollX); int mx = (int) (dx - mScrollX);
int my = (int) (dy - mScrollY); int my = (int) (dy - mScrollY);
@ -802,40 +785,34 @@ public class MapViewPosition {
mScrollX = dx; mScrollX = dx;
mScrollY = dy; mScrollY = dy;
} }
}
else
moveAbs(dx, dy);
return true; return true;
} }
public synchronized void animateTo(float dx, float dy, float duration) {
applyRotation(dx, dy);
mDuration = duration;
mHandler.start((int) mDuration);
}
void onTick(long millisLeft) { void onTick(long millisLeft) {
boolean changed = false; boolean changed = false;
if (mAnimScale) {
float adv = (1.0f - millisLeft / mDuration); float adv = (1.0f - millisLeft / mDuration);
adv = mDecInterpolator.getInterpolation(adv); adv = mDecInterpolator.getInterpolation(adv);
//adv *= adv; if (mAnimScale) {
mAbsScale = mStartScale + (mEndScale * (Math.pow(2, adv)-1)); if (mEndScale > 0)
mAbsScale = mStartScale + (mEndScale * (Math.pow(2, adv) - 1));
//div = mAbsScale / mStartScale; else
mAbsScale = mStartScale + (mEndScale * adv);
if (mAnimMove)
moveAbs(mStartX + mEndX * adv, mStartY + mEndY * adv);
updatePosition();
changed = true; changed = true;
} }
if (scroll()) if (mAnimMove) {
moveAbs(mStartX + mEndX * adv, mStartY + mEndY * adv);
changed = true;
}
if (changed) {
updatePosition();
}
if (mAnimFling && scroll())
changed = true; changed = true;
if (changed) if (changed)
@ -843,13 +820,14 @@ public class MapViewPosition {
} }
void onFinish() { void onFinish() {
if (!mAnimFling && !mScroller.isFinished())
moveAbs(mScroller.getFinalX(), mScroller.getFinalY());
if (mStartScale != 0) { if (mAnimMove) {
moveAbs(mStartX + mEndX, mStartY + mEndY);
}
if (mAnimScale) {
mAbsScale = mStartScale + mEndScale; mAbsScale = mStartScale + mEndScale;
updatePosition(); updatePosition();
mStartScale = 0;
} }
//mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); //mMapView.mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
@ -875,8 +853,8 @@ public class MapViewPosition {
mMapViewPosition = new WeakReference<MapViewPosition>(mapAnimator); mMapViewPosition = new WeakReference<MapViewPosition>(mapAnimator);
} }
public synchronized final void start(int millis) { public synchronized final void start(float millis) {
mMillisInFuture = millis; mMillisInFuture = (int) millis;
MapViewPosition animator = mMapViewPosition.get(); MapViewPosition animator = mMapViewPosition.get();
if (animator == null) if (animator == null)
return; return;

View File

@ -354,16 +354,6 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener {
if (debug) if (debug)
printState("onDown"); printState("onDown");
// if (fling) {
// mScroller.forceFinished(true);
//
// if (mTimer != null) {
// mTimer.cancel();
// mTimer = null;
// }
// fling = false;
// }
return true; return true;
} }
@ -395,25 +385,22 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener {
int w = Tile.TILE_SIZE * 6; int w = Tile.TILE_SIZE * 6;
int h = Tile.TILE_SIZE * 6; int h = Tile.TILE_SIZE * 6;
if (mMapView.enablePagedFling) { //if (mMapView.enablePagedFling) {
// double a = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
double a = Math.sqrt(velocityX * velocityX + velocityY * velocityY); //
// float vx = (float) (velocityX / a);
float vx = (float) (velocityX / a); // float vy = (float) (velocityY / a);
float vy = (float) (velocityY / a); //
// if (a < 400)
Log.d(TAG, "velocity: " + a + " " + velocityX + " " + velocityY + " - " + vx + " " + vy); // return true;
//
if (a < 400) // float move = Math.min(mMapView.getWidth(), mMapView.getHeight()) * 2 / 3;
return true; // mMapPosition.animateTo(vx * move, vy * move, 250);
//} else {
float move = Math.min(mMapView.getWidth(), mMapView.getHeight()) * 2 / 3;
mMapPosition.animateTo(vx * move, vy * move, 250);
} else {
float s = (300 / mMapView.dpi); float s = (300 / mMapView.dpi);
mMapPosition.animateFling(Math.round(velocityX * s), Math.round(velocityY * s), -w, w, -h, h); mMapPosition.animateFling(Math.round(velocityX * s), Math.round(velocityY * s), -w, w, -h,
} h);
return true; return true;
} }