Skip to content
This repository

added centerOn, changed maxZoom method #15

Open
wants to merge 2 commits into from

3 participants

Jesse Rosalia SalmanTKhan Vincent Wang
Jesse Rosalia

Added a centerOn method, to programmatically center on a point in the image.

Changed the maxZoom method to better support rectangular images

Jesse Rosalia

Sorry this is in 2 commits...I had other ideas with the first commit and was under a deadline. The second commit reverts a lot of superfluous changes, and gets just the core functionality I want to push back into the main line.

SalmanTKhan

theJenix, very nice contribution, is there a way to keep the zoomed image rectangle bounds within image's bounds rather than the outside square, what I wanted to do was actually use this in conjunction with "option to force fill image to view" but it didn't work out so I tried zooming before and then using your center code.

Vincent Wang

@SalmanTkhan : you can use scrollBy instead of using postTranslate, that way you may keep you image bounded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
27  ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouch.java
@@ -16,7 +16,6 @@
16 16
 
17 17
 public class ImageViewTouch extends ImageViewTouchBase {
18 18
 
19  
-	private static final float SCROLL_DELTA_THRESHOLD = 1.0f;
20 19
 	static final float MIN_ZOOM = 0.9f;
21 20
 	protected ScaleGestureDetector mScaleDetector;
22 21
 	protected GestureDetector mGestureDetector;
@@ -127,31 +126,7 @@ protected float onDoubleTapPost( float scale, float maxZoom ) {
127 126
 			return 1f;
128 127
 		}
129 128
 	}
130  
-	
131  
-	/**
132  
-	 * Determines whether this ImageViewTouch can be scrolled.
133  
-	 * @param direction
134  
-	 * 				- positive direction value means scroll from right to left, 
135  
-	 * 				negative value means scroll from left to right
136  
-	 * 
137  
-	 * @return true if there is some more place to scroll, false - otherwise.
138  
-	 */
139  
-	public boolean canScroll(int direction) {
140  
-		RectF bitmapRect = getBitmapRect();
141  
-		updateRect(bitmapRect, mScrollRect);
142  
-		Rect imageViewRect = new Rect();
143  
-		getGlobalVisibleRect(imageViewRect);
144  
-		
145  
-		if (bitmapRect.right >= imageViewRect.right) {
146  
-			if (direction < 0) {
147  
-				return Math.abs(bitmapRect.right - imageViewRect.right) > SCROLL_DELTA_THRESHOLD;
148  
-			}
149  
-		}
150  
-		
151  
-		double bitmapScrollRectDelta = Math.abs(bitmapRect.left - mScrollRect.left);
152  
-		return bitmapScrollRectDelta > SCROLL_DELTA_THRESHOLD;
153  
-	}
154  
-	
  129
+
155 130
 	public class GestureListener extends GestureDetector.SimpleOnGestureListener {
156 131
 
157 132
 		@Override
65  ImageViewTouch/src/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java
@@ -226,7 +226,8 @@ protected float maxZoom() {
226 226
 
227 227
 		float fw = (float) drawable.getIntrinsicWidth() / (float) mThisWidth;
228 228
 		float fh = (float) drawable.getIntrinsicHeight() / (float) mThisHeight;
229  
-		float max = Math.max( fw, fh ) * 4;
  229
+		
  230
+		float max = (1.0f / Math.min( fw, fh )) * 4;
230 231
 		return max;
231 232
 	}
232 233
 
@@ -403,6 +404,33 @@ protected void zoomTo( float scale, float centerX, float centerY ) {
403 404
 
404 405
 	protected void onZoom( float scale ) {}
405 406
 
  407
+	/**
  408
+	 * Center on a specific coordinate in the image.
  409
+	 * 
  410
+	 * This method uses image-based coordinates, with 0,0 at the top left of the image.  It is scale agnostic.
  411
+	 * 
  412
+	 */
  413
+	public void centerOn( float x, float y ) {
  414
+        Drawable d = getDrawable();
  415
+        if (d == null) {
  416
+            return; //nothing to do
  417
+        }
  418
+	    //get the bitmap rect, which represents the rectangle of the view at the specified scale
  419
+	    //NOTE: this currently has no relation to the actual bitmap...we will provide that relation in this method
  420
+        RectF rect = getBitmapRect();
  421
+        float screenMidX = getWidth() / 2;
  422
+        float screenMidY = getHeight() / 2;
  423
+        //determine the centerX and centerY of the image on screen (these coordinates are scaled image coordinates)
  424
+        float viewCenterX  = -(rect.left - screenMidX);
  425
+        float viewCenterY  = -(rect.top  - screenMidY);
  426
+        
  427
+        //NOTE: postTranslate expects - numbers to pull the image right and + to pull it left
  428
+        float xp = viewCenterX - (x / d.getIntrinsicWidth())  * (rect.right - rect.left);
  429
+        //NOTE: postTranslate expects - numbers to pull the image down, and + to pull it up
  430
+        float yp = viewCenterY - (y / d.getIntrinsicHeight()) * (rect.bottom - rect.top);
  431
+	    postTranslate(xp, yp);
  432
+	}
  433
+
406 434
 	public void scrollBy( float x, float y ) {
407 435
 		panBy( x, y );
408 436
 	}
@@ -462,21 +490,26 @@ protected void zoomTo( float scale, final float centerX, final float centerY, fi
462 490
 		final long startTime = System.currentTimeMillis();
463 491
 		final float incrementPerMs = ( scale - getScale() ) / durationMs;
464 492
 		final float oldScale = getScale();
465  
-		mHandler.post( new Runnable() {
466  
-
467  
-			@Override
468  
-			public void run() {
469  
-				long now = System.currentTimeMillis();
470  
-				float currentMs = Math.min( durationMs, now - startTime );
471  
-				float target = oldScale + ( incrementPerMs * currentMs );
472  
-				zoomTo( target, centerX, centerY );
473  
-				if ( currentMs < durationMs ) {
474  
-					mHandler.post( this );
475  
-				} else {
476  
-					// if ( getScale() < 1f ) {}
477  
-				}
478  
-			}
479  
-		} );
  493
+		if (durationMs == 0) {
  494
+		    //special case for instantaneous zoom
  495
+		    zoomTo(scale, centerX, centerY);
  496
+		} else {
  497
+    		mHandler.post( new Runnable() {
  498
+    
  499
+    			@Override
  500
+    			public void run() {
  501
+    				long now = System.currentTimeMillis();
  502
+    				float currentMs = Math.min( durationMs, now - startTime );
  503
+    				float target = oldScale + ( incrementPerMs * currentMs );
  504
+    				zoomTo( target, centerX, centerY );
  505
+    				if ( currentMs < durationMs ) {
  506
+    					mHandler.post( this );
  507
+    				} else {
  508
+    					// if ( getScale() < 1f ) {}
  509
+    				}
  510
+    			}
  511
+    		} );
  512
+		}
480 513
 	}
481 514
 
482 515
 	@Override
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.