implement animating zoom

git-svn-id: https://osmand.googlecode.com/svn/trunk@315 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-07-10 22:34:27 +00:00
parent 03569b29cb
commit 97b00ef47e
4 changed files with 69 additions and 14 deletions

View file

@ -19,8 +19,7 @@ public class ToDoConstants {
// 60. Audio guidance for routing ! // 60. Audio guidance for routing !
// 68. Implement service to app work with screen offline // 68. Implement service to app work with screen offline
// (introduce special settings how often update location to monitoring & audio guidance) // (introduce special settings how often update location to monitoring & audio guidance)
// 69. Multitouch zoom, animated zoom, animate map shift! // 69. Multitouch zoom, animated zoom, animate map shift (when select some point to see)!
// check everywhere float zoom
// Improvement : Show stops in the transport route on the map // Improvement : Show stops in the transport route on the map
// Not clear if it is really needed // Not clear if it is really needed

View file

@ -228,7 +228,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
zoomControls.setOnZoomInClickListener(new OnClickListener() { zoomControls.setOnZoomInClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
mapView.setZoom(mapView.getZoom() + 1); mapView.getAnimatedDraggingThread().startZooming(mapView.getZoom(), mapView.getZoom() + 1);
showAndHideMapPosition(); showAndHideMapPosition();
// user can preview map manually switch off auto zoom while user don't press back to location // user can preview map manually switch off auto zoom while user don't press back to location
if(OsmandSettings.isAutoZoomEnabled(MapActivity.this)){ if(OsmandSettings.isAutoZoomEnabled(MapActivity.this)){
@ -239,7 +239,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
zoomControls.setOnZoomOutClickListener(new OnClickListener() { zoomControls.setOnZoomOutClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
mapView.setZoom(mapView.getZoom() - 1); mapView.getAnimatedDraggingThread().startZooming(mapView.getZoom(), mapView.getZoom() - 1);
showAndHideMapPosition(); showAndHideMapPosition();
// user can preview map manually switch off auto zoom while user don't press back to location // user can preview map manually switch off auto zoom while user don't press back to location
if(OsmandSettings.isAutoZoomEnabled(MapActivity.this)){ if(OsmandSettings.isAutoZoomEnabled(MapActivity.this)){

View file

@ -6,9 +6,15 @@ package com.osmand.views;
*/ */
public class AnimateDraggingMapThread implements Runnable { public class AnimateDraggingMapThread implements Runnable {
public interface AnimateDraggingCallback { public interface AnimateDraggingCallback {
public void dragTo(float curX, float curY, float newX, float newY); public void dragTo(float curX, float curY, float newX, float newY);
public void zoomTo(float zoom);
} }
private int endZ;
private float curZ;
private int timeZ;
private float curX; private float curX;
private float curY; private float curY;
@ -18,6 +24,7 @@ public class AnimateDraggingMapThread implements Runnable {
private float ay; private float ay;
private byte dirX; private byte dirX;
private byte dirY; private byte dirY;
private byte dirZ;
private long time; private long time;
private volatile boolean stopped; private volatile boolean stopped;
private final float a = 0.001f; private final float a = 0.001f;
@ -30,20 +37,42 @@ public class AnimateDraggingMapThread implements Runnable {
public void run() { public void run() {
currentThread = Thread.currentThread(); currentThread = Thread.currentThread();
try { try {
while (!stopped && (vx > 0 || vy > 0)) { while (!stopped && (vx > 0 || vy > 0 || curZ != endZ)) {
Thread.sleep((long) (40d / (Math.max(vx, vy) + 0.45))); // calculate sleep
long sleep = 0;
if(vx > 0 || vy > 0){
sleep = (long) (40d / (Math.max(vx, vy) + 0.45));
} else {
sleep = 80;
}
Thread.sleep(sleep);
long curT = System.currentTimeMillis(); long curT = System.currentTimeMillis();
int dt = (int) (curT - time); int dt = (int) (curT - time);
float newX = vx > 0 ? curX + dirX * vx * dt : curX; float newX = vx > 0 ? curX + dirX * vx * dt : curX;
float newY = vy > 0 ? curY + dirY * vy * dt : curY; float newY = vy > 0 ? curY + dirY * vy * dt : curY;
float newZ = curZ;
if(timeZ > 0){
newZ = newZ + dirZ * (float)dt / timeZ;
if(dirZ > 0 == newZ > endZ){
newZ = endZ;
}
}
if (!stopped && callback != null) { if (!stopped && callback != null) {
callback.dragTo(curX, curY, newX, newY); callback.dragTo(curX, curY, newX, newY);
if(newZ > 0){
callback.zoomTo(newZ);
}
} }
vx -= ax * dt; vx -= ax * dt;
vy -= ay * dt; vy -= ay * dt;
time = curT; time = curT;
curX = newX; curX = newX;
curY = newY; curY = newY;
curZ = newZ;
}
if(curZ != endZ && endZ > 0){
callback.zoomTo(endZ);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
@ -54,14 +83,14 @@ public class AnimateDraggingMapThread implements Runnable {
/** /**
* Stop dragging async * Stop dragging async
*/ */
public void stopDragging(){ public void stopAnimating(){
stopped = true; stopped = true;
} }
/** /**
* Stop dragging sync * Stop dragging sync
*/ */
public void stopDraggingSync(){ public void stopAnimatingSync(){
// wait until current thread != null // wait until current thread != null
stopped = true; stopped = true;
while(currentThread != null){ while(currentThread != null){
@ -72,6 +101,22 @@ public class AnimateDraggingMapThread implements Runnable {
} }
} }
public void startZooming(int zoomStart, int zoomEnd){
stopAnimatingSync();
if(zoomStart < zoomEnd){
dirZ = 1;
} else {
dirZ = -1;
}
curZ = zoomStart;
endZ = zoomEnd;
timeZ = 600;
time = System.currentTimeMillis();
stopped = false;
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$
thread.start();
}
public void startDragging(float dTime, float startX, float startY, float endX, float endY){ public void startDragging(float dTime, float startX, float startY, float endX, float endY){
vx = Math.abs((endX - startX)/dTime); vx = Math.abs((endX - startX)/dTime);
vy = Math.abs((endY - startY)/dTime); vy = Math.abs((endY - startY)/dTime);
@ -79,7 +124,7 @@ public class AnimateDraggingMapThread implements Runnable {
} }
public void startDragging(float velocityX, float velocityY, float startX, float startY, float endX, float endY){ public void startDragging(float velocityX, float velocityY, float startX, float startY, float endX, float endY){
stopDraggingSync(); stopAnimatingSync();
vx = velocityX; vx = velocityX;
vy = velocityY; vy = velocityY;
dirX = (byte) (endX > startX ? 1 : -1); dirX = (byte) (endX > startX ? 1 : -1);

View file

@ -218,17 +218,24 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public void setZoom(float zoom){ public void setZoom(float zoom){
if (map == null || (map.getMaximumZoomSupported() >= zoom && map.getMinimumZoomSupported() <= zoom)) { if (map == null || (map.getMaximumZoomSupported() >= zoom && map.getMinimumZoomSupported() <= zoom)) {
animatedDraggingThread.stopDragging(); animatedDraggingThread.stopAnimating();
this.zoom = zoom; this.zoom = zoom;
refreshMap(); refreshMap();
} }
} }
// for internal usage
@Override
public void zoomTo(float zoom) {
this.zoom = zoom;
refreshMap();
}
public void setRotate(float rotate) { public void setRotate(float rotate) {
float dif = this.rotate - rotate; float dif = this.rotate - rotate;
if (dif > 2 || dif < -2) { if (dif > 2 || dif < -2) {
this.rotate = rotate; this.rotate = rotate;
animatedDraggingThread.stopDragging(); animatedDraggingThread.stopAnimating();
refreshMap(); refreshMap();
} }
} }
@ -262,7 +269,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
} }
public void setLatLon(double latitude, double longitude){ public void setLatLon(double latitude, double longitude){
animatedDraggingThread.stopDragging(); animatedDraggingThread.stopAnimating();
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
refreshMap(); refreshMap();
@ -631,7 +638,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){ if(event.getAction() == MotionEvent.ACTION_DOWN){
animatedDraggingThread.stopDragging(); animatedDraggingThread.stopAnimating();
} }
if (!multiTouchSupport.onTouchEvent(event)) { if (!multiTouchSupport.onTouchEvent(event)) {
/* return */gestureDetector.onTouchEvent(event); /* return */gestureDetector.onTouchEvent(event);
@ -671,7 +678,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
@Override @Override
public boolean onDown(MotionEvent e) { public boolean onDown(MotionEvent e) {
animatedDraggingThread.stopDragging(); animatedDraggingThread.stopAnimating();
return false; return false;
} }
@ -702,6 +709,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return true; return true;
} }
public AnimateDraggingMapThread getAnimatedDraggingThread() {
return animatedDraggingThread;
}
@Override @Override
public void onLongPress(MotionEvent e) { public void onLongPress(MotionEvent e) {
if(multiTouchSupport.isInZoomMode()){ if(multiTouchSupport.isInZoomMode()){