1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef AnimationBase_h 30 #define AnimationBase_h 31 32 #include "AtomicString.h" 33 #include <wtf/HashMap.h> 34 35 namespace WebCore { 36 37 class Animation; 38 class AnimationBase; 39 class AnimationController; 40 class CompositeAnimation; 41 class Element; 42 class Node; 43 class RenderObject; 44 class RenderStyle; 45 class TimingFunction; 46 47 class AnimationBase : public RefCounted<AnimationBase> { 48 friend class CompositeAnimationPrivate; 49 50 public: 51 AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim); 52 virtual ~AnimationBase(); 53 renderer()54 RenderObject* renderer() const { return m_object; } clearRenderer()55 void clearRenderer() { m_object = 0; } 56 57 double duration() const; 58 59 // Animations and Transitions go through the states below. When entering the STARTED state 60 // the animation is started. This may or may not require deferred response from the animator. 61 // If so, we stay in this state until that response is received (and it returns the start time). 62 // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping 63 // or AnimationStateEnding. 64 enum AnimState { 65 AnimationStateNew, // animation just created, animation not running yet 66 AnimationStateStartWaitTimer, // start timer running, waiting for fire 67 AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations 68 AnimationStateStartWaitResponse, // animation started, waiting for response 69 AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire 70 AnimationStateEnding, // received, animation running, end timer running, waiting for fire 71 AnimationStatePausedWaitTimer, // in pause mode when animation started 72 AnimationStatePausedWaitResponse, // animation paused when in STARTING state 73 AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state 74 AnimationStateDone // end timer fired, animation finished and removed 75 }; 76 77 enum AnimStateInput { 78 AnimationStateInputMakeNew, // reset back to new from any state 79 AnimationStateInputStartAnimation, // animation requests a start 80 AnimationStateInputRestartAnimation, // force a restart from any state 81 AnimationStateInputStartTimerFired, // start timer fired 82 AnimationStateInputStyleAvailable, // style is setup, ready to start animating 83 AnimationStateInputStartTimeSet, // m_startTime was set 84 AnimationStateInputLoopTimerFired, // loop timer fired 85 AnimationStateInputEndTimerFired, // end timer fired 86 AnimationStateInputPauseOverride, // pause an animation due to override 87 AnimationStateInputResumeOverride, // resume an overridden animation 88 AnimationStateInputPlayStateRunnning, // play state paused -> running 89 AnimationStateInputPlayStatePaused, // play state running -> paused 90 AnimationStateInputEndAnimation // force an end from any state 91 }; 92 93 // Called when animation is in AnimationStateNew to start animation 94 void updateStateMachine(AnimStateInput, double param); 95 96 // Animation has actually started, at passed time 97 void onAnimationStartResponse(double startTime); 98 99 // Called to change to or from paused state 100 void updatePlayState(bool running); 101 bool playStatePlaying() const; 102 waitingToStart()103 bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } preActive()104 bool preActive() const 105 { 106 return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse; 107 } 108 postActive()109 bool postActive() const { return m_animState == AnimationStateDone; } active()110 bool active() const { return !postActive() && !preActive(); } running()111 bool running() const { return !isNew() && !postActive(); } paused()112 bool paused() const { return m_pauseTime >= 0; } isNew()113 bool isNew() const { return m_animState == AnimationStateNew; } waitingForStartTime()114 bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; } waitingForStyleAvailable()115 bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; } 116 117 // "animating" means that something is running that requires a timer to keep firing 118 // (e.g. a software animation) 119 void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; } 120 double willNeedService() const; 121 122 double progress(double scale, double offset, const TimingFunction*) const; 123 animate(CompositeAnimation *,RenderObject *,const RenderStyle *,const RenderStyle *,RefPtr<RenderStyle> &)124 virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, 125 const RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) { } 126 shouldFireEvents()127 virtual bool shouldFireEvents() const { return false; } 128 129 void fireAnimationEventsIfNeeded(); 130 131 bool animationsMatch(const Animation*) const; 132 setAnimation(const Animation * anim)133 void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); } 134 135 // Return true if this animation is overridden. This will only be the case for 136 // ImplicitAnimations and is used to determine whether or not we should force 137 // set the start time. If an animation is overridden, it will probably not get 138 // back the AnimationStateInputStartTimeSet input. overridden()139 virtual bool overridden() const { return false; } 140 141 // Does this animation/transition involve the given property? affectsProperty(int)142 virtual bool affectsProperty(int /*property*/) const { return false; } isAnimatingProperty(int property,bool isRunningNow)143 bool isAnimatingProperty(int property, bool isRunningNow) const 144 { 145 if (isRunningNow) 146 return (!waitingToStart() && !postActive()) && affectsProperty(property); 147 148 return !postActive() && affectsProperty(property); 149 } 150 isTransformFunctionListValid()151 bool isTransformFunctionListValid() const { return m_transformFunctionListValid; } 152 153 void pauseAtTime(double t); 154 155 double beginAnimationUpdateTime() const; 156 157 double getElapsedTime() const; 158 next()159 AnimationBase* next() const { return m_next; } setNext(AnimationBase * animation)160 void setNext(AnimationBase* animation) { m_next = animation; } 161 styleAvailable()162 void styleAvailable() 163 { 164 ASSERT(waitingForStyleAvailable()); 165 updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1); 166 } 167 168 protected: overrideAnimations()169 virtual void overrideAnimations() { } resumeOverriddenAnimations()170 virtual void resumeOverriddenAnimations() { } 171 compositeAnimation()172 CompositeAnimation* compositeAnimation() { return m_compAnim; } 173 174 // These are called when the corresponding timer fires so subclasses can do any extra work onAnimationStart(double)175 virtual void onAnimationStart(double /*elapsedTime*/) { } onAnimationIteration(double)176 virtual void onAnimationIteration(double /*elapsedTime*/) { } onAnimationEnd(double)177 virtual void onAnimationEnd(double /*elapsedTime*/) { } startAnimation(double)178 virtual bool startAnimation(double /*beginTime*/) { return false; } endAnimation(bool)179 virtual void endAnimation(bool /*reset*/) { } 180 181 void goIntoEndingOrLoopingState(); 182 183 static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b); 184 static int getPropertyAtIndex(int, bool& isShorthand); 185 static int getNumProperties(); 186 187 // Return true if we need to start software animation timers 188 static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress); 189 190 static void setChanged(Node*); 191 192 AnimState m_animState; 193 194 bool m_isAnimating; // transition/animation requires continual timer firing 195 bool m_waitedForResponse; 196 double m_startTime; 197 double m_pauseTime; 198 double m_requestedStartTime; 199 RenderObject* m_object; 200 201 RefPtr<Animation> m_animation; 202 CompositeAnimation* m_compAnim; 203 bool m_transformFunctionListValid; 204 double m_totalDuration, m_nextIterationDuration; 205 206 AnimationBase* m_next; 207 }; 208 209 } // namespace WebCore 210 211 #endif // AnimationBase_h 212