/** * Given a requested source center and scale, calculate what the actual center will have to be to keep the image in * pan limits, keeping the requested center as near to the middle of the screen as allowed. */ @NonNull private PointF limitedSCenter(float sCenterX, float sCenterY, float scale, @NonNull PointF sTarget) { PointF vTranslate = vTranslateForSCenter(sCenterX, sCenterY, scale); int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; float sx = (vxCenter - vTranslate.x)/scale; float sy = (vyCenter - vTranslate.y)/scale; sTarget.set(sx, sy); return sTarget; }
/** * Get the translation required to place a given source coordinate at the center of the screen, with the center * adjusted for asymmetric padding. Accepts the desired scale as an argument, so this is independent of current * translate and scale. The result is fitted to bounds, putting the image point as near to the screen center as permitted. */ @NonNull private PointF vTranslateForSCenter(float sCenterX, float sCenterY, float scale) { int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; if (satTemp == null) { satTemp = new ScaleAndTranslate(0, new PointF(0, 0)); } satTemp.scale = scale; satTemp.vTranslate.set(vxCenter - (sCenterX * scale), vyCenter - (sCenterY * scale)); fitToBounds(true, satTemp); return satTemp.vTranslate; }
int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; float targetScale = limitedScale(this.targetScale);
float xPaddingRatio = getPaddingLeft() > 0 || getPaddingRight() > 0 ? getPaddingLeft()/(float)(getPaddingLeft() + getPaddingRight()) : 0.5f; float yPaddingRatio = getPaddingTop() > 0 || getPaddingBottom() > 0 ? getPaddingTop()/(float)(getPaddingTop() + getPaddingBottom()) : 0.5f;
/** * Returns the minimum allowed scale. */ private float minScale() { int vPadding = getPaddingBottom() + getPaddingTop(); int hPadding = getPaddingLeft() + getPaddingRight(); if (minimumScaleType == SCALE_TYPE_CENTER_CROP || minimumScaleType == SCALE_TYPE_START) { return Math.max((getWidth() - hPadding) / (float) sWidth(), (getHeight() - vPadding) / (float) sHeight()); } else if (minimumScaleType == SCALE_TYPE_CUSTOM && minScale > 0) { return minScale; } else { return Math.min((getWidth() - hPadding) / (float) sWidth(), (getHeight() - vPadding) / (float) sHeight()); } }
/** * Given a requested source center and scale, calculate what the actual center will have to be to keep the image in * pan limits, keeping the requested center as near to the middle of the screen as allowed. */ private PointF limitedSCenter(float sCenterX, float sCenterY, float scale, PointF sTarget) { PointF vTranslate = vTranslateForSCenter(sCenterX, sCenterY, scale); int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; float sx = (vxCenter - vTranslate.x)/scale; float sy = (vyCenter - vTranslate.y)/scale; sTarget.set(sx, sy); return sTarget; }
/** * Get the translation required to place a given source coordinate at the center of the screen, with the center * adjusted for asymmetric padding. Accepts the desired scale as an argument, so this is independent of current * translate and scale. The result is fitted to bounds, putting the image point as near to the screen center as permitted. */ private PointF vTranslateForSCenter(float sCenterX, float sCenterY, float scale) { int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; if (satTemp == null) { satTemp = new ScaleAndTranslate(0, new PointF(0, 0)); } satTemp.scale = scale; satTemp.vTranslate.set(vxCenter - (sCenterX * scale), vyCenter - (sCenterY * scale)); fitToBounds(true, satTemp); return satTemp.vTranslate; }
int vxCenter = getPaddingLeft() + (getWidth() - getPaddingRight() - getPaddingLeft())/2; int vyCenter = getPaddingTop() + (getHeight() - getPaddingBottom() - getPaddingTop())/2; float targetScale = limitedScale(this.targetScale);
float xPaddingRatio = getPaddingLeft() > 0 || getPaddingRight() > 0 ? getPaddingLeft()/(float)(getPaddingLeft() + getPaddingRight()) : 0.5f; float yPaddingRatio = getPaddingTop() > 0 || getPaddingBottom() > 0 ? getPaddingTop()/(float)(getPaddingTop() + getPaddingBottom()) : 0.5f;
/** * Returns the minimum allowed scale. */ private float minScale() { int vPadding = getPaddingBottom() + getPaddingTop(); int hPadding = getPaddingLeft() + getPaddingRight(); if (minimumScaleType == SCALE_TYPE_CENTER_CROP) { return Math.max((getWidth() - hPadding) / (float) sWidth(), (getHeight() - vPadding) / (float) sHeight()); } else if (minimumScaleType == SCALE_TYPE_CUSTOM && minScale > 0) { return minScale; } else { return Math.min((getWidth() - hPadding) / (float) sWidth(), (getHeight() - vPadding) / (float) sHeight()); } }