diff --git a/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouch.java b/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouch.java index 1abdcb6..367a8c1 100644 --- a/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouch.java +++ b/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouch.java @@ -16,7 +16,6 @@ public class ImageViewTouch extends ImageViewTouchBase { - private static final float SCROLL_DELTA_THRESHOLD = 1.0f; static final float MIN_ZOOM = 0.9f; protected ScaleGestureDetector mScaleDetector; protected GestureDetector mGestureDetector; @@ -127,31 +126,7 @@ protected float onDoubleTapPost( float scale, float maxZoom ) { return 1f; } } - - /** - * Determines whether this ImageViewTouch can be scrolled. - * @param direction - * - positive direction value means scroll from right to left, - * negative value means scroll from left to right - * - * @return true if there is some more place to scroll, false - otherwise. - */ - public boolean canScroll(int direction) { - RectF bitmapRect = getBitmapRect(); - updateRect(bitmapRect, mScrollRect); - Rect imageViewRect = new Rect(); - getGlobalVisibleRect(imageViewRect); - - if (bitmapRect.right >= imageViewRect.right) { - if (direction < 0) { - return Math.abs(bitmapRect.right - imageViewRect.right) > SCROLL_DELTA_THRESHOLD; - } - } - - double bitmapScrollRectDelta = Math.abs(bitmapRect.left - mScrollRect.left); - return bitmapScrollRectDelta > SCROLL_DELTA_THRESHOLD; - } - + public class GestureListener extends GestureDetector.SimpleOnGestureListener { @Override diff --git a/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java b/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java index a0e1a3b..f10af90 100644 --- a/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java +++ b/ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java @@ -226,7 +226,8 @@ protected float maxZoom() { float fw = (float) drawable.getIntrinsicWidth() / (float) mThisWidth; float fh = (float) drawable.getIntrinsicHeight() / (float) mThisHeight; - float max = Math.max( fw, fh ) * 4; + + float max = (1.0f / Math.min( fw, fh )) * 4; return max; } @@ -403,6 +404,33 @@ protected void zoomTo( float scale, float centerX, float centerY ) { protected void onZoom( float scale ) {} + /** + * Center on a specific coordinate in the image. + * + * This method uses image-based coordinates, with 0,0 at the top left of the image. It is scale agnostic. + * + */ + public void centerOn( float x, float y ) { + Drawable d = getDrawable(); + if (d == null) { + return; //nothing to do + } + //get the bitmap rect, which represents the rectangle of the view at the specified scale + //NOTE: this currently has no relation to the actual bitmap...we will provide that relation in this method + RectF rect = getBitmapRect(); + float screenMidX = getWidth() / 2; + float screenMidY = getHeight() / 2; + //determine the centerX and centerY of the image on screen (these coordinates are scaled image coordinates) + float viewCenterX = -(rect.left - screenMidX); + float viewCenterY = -(rect.top - screenMidY); + + //NOTE: postTranslate expects - numbers to pull the image right and + to pull it left + float xp = viewCenterX - (x / d.getIntrinsicWidth()) * (rect.right - rect.left); + //NOTE: postTranslate expects - numbers to pull the image down, and + to pull it up + float yp = viewCenterY - (y / d.getIntrinsicHeight()) * (rect.bottom - rect.top); + postTranslate(xp, yp); + } + public void scrollBy( float x, float y ) { panBy( x, y ); } @@ -462,21 +490,26 @@ protected void zoomTo( float scale, final float centerX, final float centerY, fi final long startTime = System.currentTimeMillis(); final float incrementPerMs = ( scale - getScale() ) / durationMs; final float oldScale = getScale(); - mHandler.post( new Runnable() { - - @Override - public void run() { - long now = System.currentTimeMillis(); - float currentMs = Math.min( durationMs, now - startTime ); - float target = oldScale + ( incrementPerMs * currentMs ); - zoomTo( target, centerX, centerY ); - if ( currentMs < durationMs ) { - mHandler.post( this ); - } else { - // if ( getScale() < 1f ) {} - } - } - } ); + if (durationMs == 0) { + //special case for instantaneous zoom + zoomTo(scale, centerX, centerY); + } else { + mHandler.post( new Runnable() { + + @Override + public void run() { + long now = System.currentTimeMillis(); + float currentMs = Math.min( durationMs, now - startTime ); + float target = oldScale + ( incrementPerMs * currentMs ); + zoomTo( target, centerX, centerY ); + if ( currentMs < durationMs ) { + mHandler.post( this ); + } else { + // if ( getScale() < 1f ) {} + } + } + } ); + } } @Override