Improve dragging animation
This commit is contained in:
parent
e9317a4b89
commit
9fa007928a
3 changed files with 65 additions and 32 deletions
|
@ -5,7 +5,11 @@ import net.osmand.osm.MapUtils;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread for animated dragging.
|
* Thread for animated dragging.
|
||||||
|
@ -70,7 +74,9 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
currentThread = Thread.currentThread();
|
currentThread = Thread.currentThread();
|
||||||
|
AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
boolean conditionToCountinue = true;
|
boolean conditionToCountinue = true;
|
||||||
while (!stopped && conditionToCountinue) {
|
while (!stopped && conditionToCountinue) {
|
||||||
// calculate sleep
|
// calculate sleep
|
||||||
|
@ -159,11 +165,11 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
conditionToCountinue = true;
|
conditionToCountinue = true;
|
||||||
while (conditionToCountinue && callback != null) {
|
while (conditionToCountinue && callback != null) {
|
||||||
conditionToCountinue = false;
|
conditionToCountinue = false;
|
||||||
float rotationDiff = targetRotate-callback.getRotate();
|
float rotationDiff = targetRotate - callback.getRotate();
|
||||||
if (Math.abs((rotationDiff+360)%360) < Math.abs((rotationDiff-360)%360)) {
|
if (Math.abs((rotationDiff + 360) % 360) < Math.abs((rotationDiff - 360) % 360)) {
|
||||||
rotationDiff = (rotationDiff+360)%360;
|
rotationDiff = (rotationDiff + 360) % 360;
|
||||||
} else {
|
} else {
|
||||||
rotationDiff = (rotationDiff-360)%360;
|
rotationDiff = (rotationDiff - 360) % 360;
|
||||||
}
|
}
|
||||||
float absDiff = Math.abs(rotationDiff);
|
float absDiff = Math.abs(rotationDiff);
|
||||||
if (absDiff > 0) {
|
if (absDiff > 0) {
|
||||||
|
@ -172,7 +178,7 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
callback.rotateTo(targetRotate);
|
callback.rotateTo(targetRotate);
|
||||||
} else {
|
} else {
|
||||||
conditionToCountinue = true;
|
conditionToCountinue = true;
|
||||||
callback.rotateTo(((absDiff/10)*Math.signum(rotationDiff) + callback.getRotate())%360);
|
callback.rotateTo(((absDiff / 10) * Math.signum(rotationDiff) + callback.getRotate()) % 360);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,31 +291,62 @@ public class AnimateDraggingMapThread implements Runnable {
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startDragging(float velocityX, float velocityY, float startX, float startY, float endX, float endY){
|
public void startDragging(final float velocityX, final float velocityY, float startX, float startY,
|
||||||
|
final float endX, final float endY){
|
||||||
stopAnimatingSync();
|
stopAnimatingSync();
|
||||||
targetZoom = 0;
|
|
||||||
this.notifyListener = true;
|
this.notifyListener = true;
|
||||||
vx = velocityX;
|
|
||||||
vy = velocityY;
|
|
||||||
dirX = (byte) (endX > startX ? 1 : -1);
|
|
||||||
dirY = (byte) (endY > startY ? 1 : -1);
|
|
||||||
animateDrag = true;
|
|
||||||
ax = vx * a;
|
|
||||||
ay = vy * a;
|
|
||||||
time = System.currentTimeMillis();
|
|
||||||
stopped = false;
|
stopped = false;
|
||||||
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$
|
final float animationTime = 1900f;
|
||||||
|
System.out.println("Velocity x " + velocityX + " velocity Y " + velocityY);
|
||||||
|
|
||||||
|
Thread thread = new Thread(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
float curX = endX;
|
||||||
|
float curY = endY;
|
||||||
|
|
||||||
|
DecelerateInterpolator interpolator = new DecelerateInterpolator(1);
|
||||||
|
|
||||||
|
long timeMillis = SystemClock.uptimeMillis();
|
||||||
|
float normalizedTime = 0f;
|
||||||
|
float prevNormalizedTime = 0f;
|
||||||
|
while(!stopped){
|
||||||
|
normalizedTime = (SystemClock.uptimeMillis() - timeMillis) / animationTime;
|
||||||
|
if(normalizedTime >= 1f){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
float interpolation = interpolator.getInterpolation(normalizedTime);
|
||||||
|
|
||||||
|
float newX = velocityX * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curX;
|
||||||
|
float newY = velocityY * (1 - interpolation) * (normalizedTime - prevNormalizedTime) + curY;
|
||||||
|
|
||||||
|
callback.dragTo(curX, curY, newX, newY, notifyListener);
|
||||||
|
curX = newX;
|
||||||
|
curY = newY;
|
||||||
|
prevNormalizedTime = normalizedTime;
|
||||||
|
try {
|
||||||
|
Thread.sleep(50);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stopped){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},"Animatable dragging"); //$NON-NLS-1$
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startRotate(float rotate)
|
public void startRotate(float rotate) {
|
||||||
{
|
|
||||||
this.targetRotate = rotate;
|
this.targetRotate = rotate;
|
||||||
if (!isAnimating()) {
|
if (!isAnimating()) {
|
||||||
//stopped = false;
|
// stopped = false;
|
||||||
//do we need to kill and recreate the thread? wait would be enough as now it
|
// do we need to kill and recreate the thread? wait would be enough as now it
|
||||||
//also handles the rotation?
|
// also handles the rotation?
|
||||||
Thread thread = new Thread(this,"Animatable dragging"); //$NON-NLS-1$
|
Thread thread = new Thread(this, "Animatable dragging"); //$NON-NLS-1$
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
private void refreshMapInternal() {
|
private void refreshMapInternal() {
|
||||||
handler.removeMessages(1);
|
handler.removeMessages(1);
|
||||||
|
|
||||||
long time = System.currentTimeMillis();
|
// long time = System.currentTimeMillis();
|
||||||
|
|
||||||
boolean useInternet = getSettings().USE_INTERNET_TO_DOWNLOAD_TILES.get();
|
boolean useInternet = getSettings().USE_INTERNET_TO_DOWNLOAD_TILES.get();
|
||||||
if (useInternet) {
|
if (useInternet) {
|
||||||
|
@ -439,7 +439,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
Canvas canvas = holder.lockCanvas();
|
Canvas canvas = holder.lockCanvas();
|
||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
boolean nightMode = false;
|
boolean nightMode = false;
|
||||||
log.info("Canvas " + (System.currentTimeMillis() - time));
|
|
||||||
if (application != null) {
|
if (application != null) {
|
||||||
Boolean dayNightRenderer = application.getDaynightHelper().getDayNightRenderer();
|
Boolean dayNightRenderer = application.getDaynightHelper().getDayNightRenderer();
|
||||||
if (dayNightRenderer != null) {
|
if (dayNightRenderer != null) {
|
||||||
|
@ -455,7 +454,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
|
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
|
||||||
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
|
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
|
||||||
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
|
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
|
||||||
log.info("Calc" + (System.currentTimeMillis() - time));
|
|
||||||
if(nightMode){
|
if(nightMode){
|
||||||
canvas.drawARGB(255, 220, 220, 220);
|
canvas.drawARGB(255, 220, 220, 220);
|
||||||
} else {
|
} else {
|
||||||
|
@ -472,11 +470,9 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
// drawEmptyTile(canvas, x1, y1, ftileSize, nightMode);
|
// drawEmptyTile(canvas, x1, y1, ftileSize, nightMode);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
log.info("Draw before layers" + (System.currentTimeMillis() - time));
|
|
||||||
|
|
||||||
drawOverMap(canvas, latlonRect, tilesRect, nightMode);
|
drawOverMap(canvas, latlonRect, tilesRect, nightMode);
|
||||||
|
|
||||||
log.info("Draw with layers " + (System.currentTimeMillis() - time));
|
// log.info("Draw with layers " + (System.currentTimeMillis() - time));
|
||||||
} finally {
|
} finally {
|
||||||
holder.unlockCanvasAndPost(canvas);
|
holder.unlockCanvasAndPost(canvas);
|
||||||
}
|
}
|
||||||
|
@ -752,8 +748,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
@Override
|
@Override
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||||
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
|
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
|
||||||
animatedDraggingThread.startDragging(Math.abs(velocityX / 1000), Math.abs(velocityY / 1000), e1.getX(), e1.getY(), e2
|
animatedDraggingThread.startDragging(velocityX, velocityY,
|
||||||
.getX(), e2.getY());
|
e1.getX(), e1.getY(), e2.getX(), e2.getY());
|
||||||
} else {
|
} else {
|
||||||
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
|
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue