001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030/** 031 * 032 */ 033package org.openimaj.content.animation.animator; 034 035/** 036 * An animator that will animate a value over a given time period. The animator 037 * is constructed using a specific time period and on the first call of the 038 * makeNextValue() will start a timer. 039 * <p> 040 * Subclasses must implement a method that can return a value based on an 041 * absolute percentage value. This class will convert the time each nextValue() 042 * is called into a percentage value between the start and end times and use 043 * that to calculate the absolute value of the animator. 044 * 045 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 046 * @version $Author$, $Revision$, $Date$ 047 * @param <T> 048 * The type of value produced 049 */ 050public abstract class TimeBasedValueAnimator<T> implements ValueAnimator<T> 051{ 052 /** The time the animation started */ 053 private long startTime = 0; 054 055 /** The length of the animation */ 056 private long animationLength = 0; 057 058 /** The start value of the animation */ 059 protected T startValue = null; 060 061 /** The end/target value of the animation */ 062 protected T endValue = null; 063 064 /** The current percentage */ 065 private double currentPC = 0; 066 067 /** 068 * @param initial 069 * The start value for the animator 070 * @param end 071 * The end value for the animator 072 * @param millis 073 * The length of time the animation should run 074 */ 075 public TimeBasedValueAnimator(final T initial, final T end, final long millis) 076 { 077 this.startValue = initial; 078 this.endValue = end; 079 this.animationLength = millis; 080 } 081 082 /** 083 * Given a percentage value (0 < pc <=1), the method should return a value 084 * for the animation. 085 * 086 * @param pc 087 * the percentage value 088 * @return The animator value 089 */ 090 protected abstract T calculateValue(double pc); 091 092 /** 093 * {@inheritDoc} 094 * 095 * @see org.openimaj.content.animation.animator.ValueAnimator#nextValue() 096 */ 097 @Override 098 public T nextValue() 099 { 100 final long currentTime = System.currentTimeMillis(); 101 if (this.startTime == 0) 102 this.startTime = currentTime; 103 104 this.currentPC = (currentTime - this.startTime) / (double) this.animationLength; 105 106 if (this.isComplete()) 107 return this.endValue; 108 109 return this.calculateValue(this.currentPC); 110 } 111 112 /** 113 * {@inheritDoc} 114 * 115 * @see org.openimaj.content.animation.animator.ValueAnimator#reset() 116 */ 117 @Override 118 public void reset() 119 { 120 this.startTime = 0; 121 this.currentPC = 0; 122 } 123 124 /** 125 * Returns whether the animator has completed 126 * 127 * @return TRUE if the animator has completed. 128 */ 129 public boolean isComplete() 130 { 131 return this.currentPC >= 1.0; 132 } 133 134 /** 135 * A implementation sugar for {@link #isComplete()} 136 * 137 * {@inheritDoc} 138 * 139 * @see org.openimaj.content.animation.animator.ValueAnimator#hasFinished() 140 */ 141 @Override 142 public boolean hasFinished() 143 { 144 return this.isComplete(); 145 } 146}