1 /* 2 3 dsh-piccolo-ease Piccolo2D easing activities and supporting classes. 4 Copyright (c) 2009-2013 held jointly by the individual authors. 5 6 This library is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 3 of the License, or (at 9 your option) any later version. 10 11 This library is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with this library; if not, write to the Free Software Foundation, 18 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 20 > http://www.fsf.org/licensing/licenses/lgpl.html 21 > http://www.opensource.org/licenses/lgpl-license.php 22 23 */ 24 package org.dishevelled.piccolo.ease; 25 26 import org.piccolo2d.activities.PInterpolatingActivity; 27 28 import org.piccolo2d.util.PUtil; 29 30 import org.dishevelled.interpolate.EasingFunction; 31 32 /** 33 * Easing activity. 34 * 35 * @author Michael Heuer 36 * @version $Revision$ $Date$ 37 */ 38 public class EasingActivity 39 extends PInterpolatingActivity 40 { 41 /** Easing function for this easing activity. */ 42 private final EasingFunction easingFunction; 43 44 45 /** 46 * Create a new easing activity with the specified easing function and 47 * duration in milliseconds. 48 * 49 * @param easingFunction easing function, must not be null 50 * @param duration duration in milliseconds, must be at least <code>1</code> ms 51 */ 52 public EasingActivity(final EasingFunction easingFunction, final long duration) 53 { 54 super(duration, PUtil.DEFAULT_ACTIVITY_STEP_RATE); 55 if (easingFunction == null) 56 { 57 throw new IllegalArgumentException("easingFunction must not be null"); 58 } 59 if (duration < 1) 60 { 61 throw new IllegalArgumentException("duration must be at least 1 ms"); 62 } 63 this.easingFunction = easingFunction; 64 super.setSlowInSlowOut(false); 65 } 66 67 /** 68 * Create a new easing activity with the specified easing function and 69 * duration in milliseconds. 70 * 71 * @param easingFunction easing function, must not be null 72 * @param duration duration in milliseconds, must be at least <code>1</code> ms 73 * @param stepRate step rate in milliseconds 74 * @param startTime start time in milliseconds, relative to <code>System.currentTimeMillis()</code> 75 * @param loopCount number of times this easing activity should reschedule itself 76 * @param mode defines how this easing activity interpolates between states 77 */ 78 public EasingActivity(final EasingFunction easingFunction, 79 final long duration, 80 final long stepRate, 81 final long startTime, 82 final int loopCount, 83 final int mode) 84 { 85 super(duration, stepRate, startTime, loopCount, mode); 86 if (easingFunction == null) 87 { 88 throw new IllegalArgumentException("easingFunction must not be null"); 89 } 90 if (duration < 1) 91 { 92 throw new IllegalArgumentException("duration must be at least 1 ms"); 93 } 94 this.easingFunction = easingFunction; 95 super.setSlowInSlowOut(false); 96 } 97 98 99 /** 100 * {@inheritDoc} 101 * 102 * <p> 103 * Overridden to throw an UnsupportedOperationException. Use the 104 * easing function specified in this class' constructor instead. 105 * </p> 106 */ 107 public final void setSlowInSlowOut(final boolean slowInSlowOut) 108 { 109 throw new UnsupportedOperationException("slowInSlowOut is not supported by this activity, use easingFunction in ctr instead"); 110 } 111 112 /** 113 * {@inheritDoc} 114 * 115 * <p> 116 * The typical interval for interpolated activities is <code>0.0f</code> to 117 * <code>1.0f</code>, inclusive. An easing interpolation function allows for 118 * overshooting this interval range in both directions, so the valid interval for 119 * the specified value is <code>-1.0f</code> to <code>2.0f</code>, inclusive. 120 * </p> 121 */ 122 public void setRelativeTargetValue(final float value) 123 { 124 super.setRelativeTargetValue(value); 125 } 126 127 /** 128 * {@inheritDoc} 129 * 130 * <p> 131 * If subclasses override this method, they must call <code>super.activityStarted()</code>. 132 * </p> 133 */ 134 protected void activityStarted() 135 { 136 super.activityStarted(); 137 } 138 139 /** 140 * {@inheritDoc} 141 * 142 * <p> 143 * This method has been made final to prevent subclasses from overriding its behaviour. 144 * </p> 145 */ 146 protected final void activityStep(final long elapsed) 147 { 148 super.activityStep(elapsed); 149 } 150 151 /** 152 * {@inheritDoc} 153 * 154 * <p> 155 * If subclasses override this method, they must call <code>super.activityFinished()</code>. 156 * </p> 157 */ 158 protected void activityFinished() 159 { 160 super.activityFinished(); 161 } 162 163 /** 164 * {@inheritDoc} 165 * 166 * <p> 167 * Overridden to evaluate the easing function against the specified value. 168 * </p> 169 */ 170 protected final void setRelativeTargetValueAdjustingForMode(final float value) 171 { 172 double v = value; 173 if (getMode() == DESTINATION_TO_SOURCE) 174 { 175 v = 1.0f - value; 176 } 177 else if (getMode() == SOURCE_TO_DESTINATION_TO_SOURCE) 178 { 179 v = (value <= 0.5f) ? 2.0f * value : 1.0f - ((value - 0.5f) * 2.0f); 180 } 181 float easedValue = easingFunction.evaluate(Double.valueOf(v)).floatValue(); 182 setRelativeTargetValue(easedValue); 183 } 184 }