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 }