/* * Copyright 2014 Flavio Faria * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.marshalchen.common.uimodule.kenburnsview; import android.graphics.RectF; import android.view.animation.Interpolator; public class Transition { /** The rect the transition will start from. */ private RectF mSrcRect; /** The rect the transition will end at. */ private RectF mDstRect; /** An intermediary rect that changes in every frame according to the transition progress. */ private final RectF mCurrentRect = new RectF(); /** Precomputed width difference between {@link #mSrcRect} and {@link #mSrcRect}. */ private float mWidthDiff; /** Precomputed height difference between {@link #mSrcRect} and {@link #mSrcRect}. */ private float mHeightDiff; /** Precomputed X offset between the center points of * {@link #mSrcRect} and {@link #mSrcRect}. */ private float mCenterXDiff; /** Precomputed Y offset between the center points of * {@link #mSrcRect} and {@link #mSrcRect}. */ private float mCenterYDiff; /** The duration of the transition in milliseconds. The default duration is 5000 ms. */ private long mDuration; /** The {@link android.view.animation.Interpolator} used to perform the transitions between rects. */ private Interpolator mInterpolator; public Transition(RectF srcRect, RectF dstRect, long duration, Interpolator interpolator) { // Reduces precision to avoid problems when comparing aspect ratios. float srcRectRatio = MathUtils.truncate(MathUtils.getRectRatio(srcRect), 2); float dstRectRatio = MathUtils.truncate(MathUtils.getRectRatio(dstRect), 2); if (srcRectRatio != dstRectRatio) { throw new IncompatibleRatioException(); } mSrcRect = srcRect; mDstRect = dstRect; mDuration = duration; mInterpolator = interpolator; // Precomputes a few variables to avoid doing it in onDraw(). mWidthDiff = dstRect.width() - srcRect.width(); mHeightDiff = dstRect.height() - srcRect.height(); mCenterXDiff = dstRect.centerX() - srcRect.centerX(); mCenterYDiff = dstRect.centerY() - srcRect.centerY(); } /** * Gets the rect that will take the scene when a Ken Burns transition starts. * @return the rect that starts the transition. */ public RectF getSourceRect() { return mSrcRect; } /** * Gets the rect that will take the scene when a Ken Burns transition ends. * @return the rect that ends the transition. */ public RectF getDestinyRect() { return mDstRect; } /** * Gets the current rect that represents the part of the image to take the scene * in the current frame. * @param elapsedTime the elapsed time since this transition started. */ public RectF getInterpolatedRect(long elapsedTime) { float elapsedTimeFraction = elapsedTime / (float) mDuration; float interpolationProgress = Math.min(elapsedTimeFraction, 1); float interpolation = mInterpolator.getInterpolation(interpolationProgress); float currentWidth = mSrcRect.width() + (interpolation * mWidthDiff); float currentHeight = mSrcRect.height() + (interpolation * mHeightDiff); float currentCenterX = mSrcRect.centerX() + (interpolation * mCenterXDiff); float currentCenterY = mSrcRect.centerY() + (interpolation * mCenterYDiff); float left = currentCenterX - (currentWidth / 2); float top = currentCenterY - (currentHeight / 2); float right = left + currentWidth; float bottom = top + currentHeight; mCurrentRect.set(left, top, right, bottom); return mCurrentRect; } /** * Gets the duration of this transition. * @return the duration, in milliseconds. */ public long getDuration() { return mDuration; } }