@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (panEnabled && readySent && vTranslate != null && e1 != null && e2 != null && (Math.abs(e1.getX() - e2.getX()) > 50 || Math.abs(e1.getY() - e2.getY()) > 50) && (Math.abs(velocityX) > 500 || Math.abs(velocityY) > 500) && !isZooming) { PointF vTranslateEnd = new PointF(vTranslate.x + (velocityX * 0.25f), vTranslate.y + (velocityY * 0.25f)); float sCenterXEnd = ((getWidth()/2) - vTranslateEnd.x)/scale; float sCenterYEnd = ((getHeight()/2) - vTranslateEnd.y)/scale; new AnimationBuilder(new PointF(sCenterXEnd, sCenterYEnd)).withEasing(EASE_OUT_QUAD).withPanLimited(false).withOrigin(ORIGIN_FLING).start(); return true; } return super.onFling(e1, e2, velocityX, velocityY); }
/** * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * beyond the panning limits, the image is automatically panned during the animation. * @param scale Target scale. * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ @Nullable public AnimationBuilder animateScale(float scale) { if (!isReady()) { return null; } return new AnimationBuilder(scale); }
/** * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * beyond the panning limits, the image is automatically panned during the animation. * @param scale Target scale. * @param sCenter Target source center. * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ @Nullable public AnimationBuilder animateScaleAndCenter(float scale, PointF sCenter) { if (!isReady()) { return null; } return new AnimationBuilder(scale, sCenter); }
/** * Double tap zoom handler triggered from gesture detector or on touch, depending on whether * quick scale is enabled. */ private void doubleTapZoom(PointF sCenter, PointF vFocus) { if (!panEnabled) { if (sRequestedCenter != null) { // With a center specified from code, zoom around that point. sCenter.x = sRequestedCenter.x; sCenter.y = sRequestedCenter.y; } else { // With no requested center, scale around the image center. sCenter.x = sWidth()/2; sCenter.y = sHeight()/2; } } float doubleTapZoomScale = Math.min(maxScale, SubsamplingScaleImageView.this.doubleTapZoomScale); boolean zoomIn = scale <= doubleTapZoomScale * 0.9; float targetScale = zoomIn ? doubleTapZoomScale : minScale(); if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) { setScaleAndCenter(targetScale, sCenter); } else if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER || !zoomIn || !panEnabled) { new AnimationBuilder(targetScale, sCenter).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } else if (doubleTapZoomStyle == ZOOM_FOCUS_FIXED) { new AnimationBuilder(targetScale, sCenter, vFocus).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } invalidate(); }
/** * Creates a panning animation builder, that when started will animate the image to place the given coordinates of * the image in the center of the screen. If doing this would move the image beyond the edges of the screen, the * image is instead animated to move the center point as near to the center of the screen as is allowed - it's * guaranteed to be on screen. * @param sCenter Target center point * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ public AnimationBuilder animateCenter(PointF sCenter) { if (!isReady()) { return null; } return new AnimationBuilder(sCenter); }
/** * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * beyond the panning limits, the image is automatically panned during the animation. * @param scale Target scale. * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ public AnimationBuilder animateScale(float scale) { if (!isReady()) { return null; } return new AnimationBuilder(scale); }
/** * Creates a scale animation builder, that when started will animate a zoom in or out. If this would move the image * beyond the panning limits, the image is automatically panned during the animation. * @param scale Target scale. * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ public AnimationBuilder animateScaleAndCenter(float scale, PointF sCenter) { if (!isReady()) { return null; } return new AnimationBuilder(scale, sCenter); }
@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (panEnabled && readySent && vTranslate != null && e1 != null && e2 != null && (Math.abs(e1.getX() - e2.getX()) > 50 || Math.abs(e1.getY() - e2.getY()) > 50) && (Math.abs(velocityX) > 500 || Math.abs(velocityY) > 500) && !isZooming) { PointF vTranslateEnd = new PointF(vTranslate.x + (velocityX * 0.25f), vTranslate.y + (velocityY * 0.25f)); float sCenterXEnd = ((getWidth()/2) - vTranslateEnd.x)/scale; float sCenterYEnd = ((getHeight()/2) - vTranslateEnd.y)/scale; new AnimationBuilder(new PointF(sCenterXEnd, sCenterYEnd)).withEasing(EASE_OUT_QUAD).withPanLimited(false).withOrigin(ORIGIN_FLING).start(); return true; } return super.onFling(e1, e2, velocityX, velocityY); }
/** * Double tap zoom handler triggered from gesture detector or on touch, depending on whether * quick scale is enabled. */ private void doubleTapZoom(PointF sCenter, PointF vFocus) { if (!panEnabled) { if (sRequestedCenter != null) { // With a center specified from code, zoom around that point. sCenter.x = sRequestedCenter.x; sCenter.y = sRequestedCenter.y; } else { // With no requested center, scale around the image center. sCenter.x = sWidth()/2; sCenter.y = sHeight()/2; } } float doubleTapZoomScale = Math.min(maxScale, SubsamplingScaleImageView.this.doubleTapZoomScale); boolean zoomIn = (scale <= doubleTapZoomScale * 0.9) || scale == minScale; float targetScale = zoomIn ? doubleTapZoomScale : minScale(); if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) { setScaleAndCenter(targetScale, sCenter); } else if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER || !zoomIn || !panEnabled) { new AnimationBuilder(targetScale, sCenter).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } else if (doubleTapZoomStyle == ZOOM_FOCUS_FIXED) { new AnimationBuilder(targetScale, sCenter, vFocus).withInterruptible(false).withDuration(doubleTapZoomDuration).withOrigin(ORIGIN_DOUBLE_TAP_ZOOM).start(); } invalidate(); }
/** * Creates a panning animation builder, that when started will animate the image to place the given coordinates of * the image in the center of the screen. If doing this would move the image beyond the edges of the screen, the * image is instead animated to move the center point as near to the center of the screen as is allowed - it's * guaranteed to be on screen. * @param sCenter Target center point * @return {@link AnimationBuilder} instance. Call {@link SubsamplingScaleImageView.AnimationBuilder#start()} to start the anim. */ @Nullable public AnimationBuilder animateCenter(PointF sCenter) { if (!isReady()) { return null; } return new AnimationBuilder(sCenter); }