summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Sapperstein <asapperstein@google.com>2014-10-17 19:33:17 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-10-17 19:33:17 +0000
commitbcbd114452a8d672077e406304ebbba317509252 (patch)
tree6a3e36a98d61511b50f38064e209d110790c8591
parent656e80363682740f0344f9ec798e0d0d596d757a (diff)
parentc9d25c87e10cc773f167b60a3d7b4b05f0c819ec (diff)
downloadphotoviewer-l-preview.tar.gz
Merge "Overzoom animation added when attempting to zoom past max scale."android-l-preview_r2l-preview
-rw-r--r--src/com/android/ex/photo/views/PhotoView.java43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/com/android/ex/photo/views/PhotoView.java b/src/com/android/ex/photo/views/PhotoView.java
index 1792115..3fb1da3 100644
--- a/src/com/android/ex/photo/views/PhotoView.java
+++ b/src/com/android/ex/photo/views/PhotoView.java
@@ -63,6 +63,8 @@ public class PhotoView extends View implements OnGestureListener,
private static final long SNAP_DELAY = 250L;
/** By how much to scale the image when double click occurs */
private final static float DOUBLE_TAP_SCALE_FACTOR = 2.0f;
+ /** Amount which can be zoomed in past the maximum scale, and then scaled back */
+ private final static float SCALE_OVERZOOM_FACTOR = 1.5f;
/** Amount of translation needed before starting a snap animation */
private final static float SNAP_THRESHOLD = 20.0f;
/** The width & height of the bitmap returned by {@link #getCroppedPhoto()} */
@@ -339,7 +341,7 @@ public class PhotoView extends View implements OnGestureListener,
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- if (mTransformsEnabled) {
+ if (mTransformsEnabled && !mScaleRunnable.mRunning) {
translate(-distanceX, -distanceY);
}
return true;
@@ -356,7 +358,7 @@ public class PhotoView extends View implements OnGestureListener,
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- if (mTransformsEnabled) {
+ if (mTransformsEnabled && !mScaleRunnable.mRunning) {
mTranslateRunnable.start(velocityX, velocityY);
}
return true;
@@ -384,6 +386,37 @@ public class PhotoView extends View implements OnGestureListener,
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
+ // Scale back to the maximum if over-zoomed
+ float currentScale = getScale();
+ if (currentScale > mMaxScale) {
+ // The number of times the crop amount pulled in can fit on the screen
+ float marginFit = 1 / (1 - mMaxScale / currentScale);
+ // The (negative) relative maximum distance from an image edge such that when scaled
+ // this far from the edge, all of the image off-screen in that direction is pulled in
+ float relativeDistance = 1 - marginFit;
+ float centerX = getWidth() / 2;
+ float centerY = getHeight() / 2;
+ // This center will pull all of the margin from the lesser side, over will expose trim
+ float maxX = mTranslateRect.left * relativeDistance;
+ float maxY = mTranslateRect.top * relativeDistance;
+ // This center will pull all of the margin from the greater side, over will expose trim
+ float minX = getWidth() * marginFit + mTranslateRect.right * relativeDistance;
+ float minY = getHeight() * marginFit + mTranslateRect.bottom * relativeDistance;
+ // Adjust center according to bounds to avoid bad crop
+ if (minX > maxX) {
+ // Border is inevitable due to small image size, so we split the crop difference
+ centerX = (minX + maxX) / 2;
+ } else {
+ centerX = Math.min(Math.max(minX, centerX), maxX);
+ }
+ if (minY > maxY) {
+ // Border is inevitable due to small image size, so we split the crop difference
+ centerY = (minY + maxY) / 2;
+ } else {
+ centerY = Math.min(Math.max(minY, centerY), maxY);
+ }
+ mScaleRunnable.start(currentScale, mMaxScale, centerX, centerY);
+ }
if (mTransformsEnabled && mIsDoubleTouch) {
mDoubleTapDebounce = true;
resetTransformations();
@@ -874,7 +907,7 @@ public class PhotoView extends View implements OnGestureListener,
} else {
mMinScale = getScale();
}
- mMaxScale = Math.max(mMinScale * 8, 8);
+ mMaxScale = Math.max(mMinScale * 4, 4);
}
/**
@@ -910,9 +943,9 @@ public class PhotoView extends View implements OnGestureListener,
// rotate back to the original orientation
mMatrix.postRotate(-mRotation, getWidth() / 2, getHeight() / 2);
- // ensure that mMixScale <= newScale <= mMaxScale
+ // ensure that mMinScale <= newScale <= mMaxScale
newScale = Math.max(newScale, mMinScale);
- newScale = Math.min(newScale, mMaxScale);
+ newScale = Math.min(newScale, mMaxScale * SCALE_OVERZOOM_FACTOR);
float currentScale = getScale();
float factor = newScale / currentScale;