001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.anim;
020:
021: import org.apache.batik.anim.timing.TimedElement;
022: import org.apache.batik.anim.values.AnimatableValue;
023: import org.apache.batik.dom.anim.AnimatableElement;
024:
025: // import org.apache.batik.anim.timing.Trace;
026:
027: /**
028: * An abstract base class for the different types of animation.
029: *
030: * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
031: * @version $Id: AbstractAnimation.java 478283 2006-11-22 18:53:40Z dvholten $
032: */
033: public abstract class AbstractAnimation {
034:
035: // Constants for calcMode.
036: public static final short CALC_MODE_DISCRETE = 0;
037: public static final short CALC_MODE_LINEAR = 1;
038: public static final short CALC_MODE_PACED = 2;
039: public static final short CALC_MODE_SPLINE = 3;
040:
041: /**
042: * The TimedElement that controls the timing of this animation.
043: */
044: protected TimedElement timedElement;
045:
046: /**
047: * The AnimatableElement that gives access to underlying values in the
048: * document.
049: */
050: protected AnimatableElement animatableElement;
051:
052: /**
053: * The animation that is lower in the sandwich.
054: */
055: protected AbstractAnimation lowerAnimation;
056:
057: /**
058: * The animation that is higher in the sandwich.
059: */
060: protected AbstractAnimation higherAnimation;
061:
062: /**
063: * Whether this animation needs recomputing.
064: */
065: protected boolean isDirty;
066:
067: /**
068: * Whether this animation is active.
069: */
070: protected boolean isActive;
071:
072: /**
073: * Whether this animation is frozen.
074: */
075: protected boolean isFrozen;
076:
077: /**
078: * The time at which this animation became active. Used for ensuring the
079: * sandwich order is correct when multiple animations become active
080: * simultaneously.
081: */
082: protected float beginTime;
083:
084: /**
085: * The value of this animation.
086: */
087: protected AnimatableValue value;
088:
089: /**
090: * The value of this animation composed with any others.
091: */
092: protected AnimatableValue composedValue;
093:
094: /**
095: * Whether this animation depends on the underlying value.
096: */
097: protected boolean usesUnderlyingValue;
098:
099: /**
100: * Whether this animation is a 'to-animation'.
101: */
102: protected boolean toAnimation;
103:
104: /**
105: * Creates a new Animation.
106: */
107: protected AbstractAnimation(TimedElement timedElement,
108: AnimatableElement animatableElement) {
109: this .timedElement = timedElement;
110: this .animatableElement = animatableElement;
111: }
112:
113: /**
114: * Returns the TimedElement for this animation.
115: */
116: public TimedElement getTimedElement() {
117: return timedElement;
118: }
119:
120: /**
121: * Returns the value of this animation, or null if it isn't active.
122: */
123: public AnimatableValue getValue() {
124: if (!isActive && !isFrozen) {
125: return null;
126: }
127: return value;
128: }
129:
130: /**
131: * Returns the composed value of this animation, or null if it isn't active.
132: */
133: public AnimatableValue getComposedValue() {
134: // Trace.enter(this, "getComposedValue", null); try {
135: // Trace.print("isActive == " + isActive + ", isFrozen == " + isFrozen + ", isDirty == " + isDirty);
136: if (!isActive && !isFrozen) {
137: return null;
138: }
139: if (isDirty) {
140: // Trace.print("willReplace() == " + willReplace());
141: // Trace.print("value == " + value);
142: AnimatableValue lowerValue = null;
143: if (!willReplace()) {
144: // Trace.print("lowerAnimation == " + lowerAnimation);
145: if (lowerAnimation == null) {
146: lowerValue = animatableElement.getUnderlyingValue();
147: usesUnderlyingValue = true;
148: } else {
149: lowerValue = lowerAnimation.getComposedValue();
150: usesUnderlyingValue = false;
151: }
152: // Trace.print("lowerValue == " + lowerValue);
153: }
154: composedValue = value.interpolate(composedValue, null, 0f,
155: lowerValue, 1);
156: // Trace.print("composedValue == " + composedValue);
157: isDirty = false;
158: }
159: return composedValue;
160: // } finally { Trace.exit(); }
161: }
162:
163: /**
164: * Returns a string representation of this animation.
165: */
166: public String toString() {
167: return timedElement.toString();
168: }
169:
170: /**
171: * Returns whether this animation depends on the underlying value.
172: */
173: public boolean usesUnderlyingValue() {
174: return usesUnderlyingValue || toAnimation;
175: }
176:
177: /**
178: * Returns whether this animation will replace values on animations
179: * lower in the sandwich.
180: */
181: protected boolean willReplace() {
182: return true;
183: }
184:
185: /**
186: * Marks this animation and any animation that depends on it
187: * as dirty.
188: */
189: protected void markDirty() {
190: isDirty = true;
191: if (higherAnimation != null && !higherAnimation.willReplace()
192: && !higherAnimation.isDirty) {
193: higherAnimation.markDirty();
194: }
195: }
196:
197: /**
198: * Called when the element is sampled for its "last" value.
199: */
200: protected void sampledLastValue(int repeatIteration) {
201: }
202:
203: /**
204: * Called when the element is sampled at the given time. This updates
205: * the {@link #value} of the animation if active.
206: */
207: protected abstract void sampledAt(float simpleTime,
208: float simpleDur, int repeatIteration);
209: }
|