mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
1e9fc689ae
This patch changes the inheritance of ElementPropertyTransition so that it is a subclass of Animation not AnimationPlayer. The only thing special about ElementPropertyTransition is it stores some extra state for reversing transitions and an extra ValuePortionFor convenience method. This reversing behavior is implemented by the transition manager by creating a new AnimationPlayer (i.e. it is *not* a property of the AnimationPlayer). As a result this extra state can be pushed down to Animation which simplifies the code significantly. In future if we implement KeyframeEffect as a separate object we may be able to push transition-specific state down to KeyframeEffect instead.
260 lines
8.0 KiB
C++
260 lines
8.0 KiB
C++
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_dom_Animation_h
|
|
#define mozilla_dom_Animation_h
|
|
|
|
#include "nsAutoPtr.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsWrapperCache.h"
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/StyleAnimationValue.h"
|
|
#include "mozilla/TimeStamp.h"
|
|
#include "mozilla/dom/Nullable.h"
|
|
#include "nsSMILKeySpline.h"
|
|
#include "nsStyleStruct.h" // for nsTimingFunction
|
|
|
|
struct JSContext;
|
|
|
|
namespace mozilla {
|
|
|
|
/**
|
|
* Input timing parameters.
|
|
*
|
|
* Eventually this will represent all the input timing parameters specified
|
|
* by content but for now it encapsulates just the subset of those
|
|
* parameters passed to GetPositionInIteration.
|
|
*/
|
|
struct AnimationTiming
|
|
{
|
|
TimeDuration mIterationDuration;
|
|
TimeDuration mDelay;
|
|
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
|
|
uint8_t mDirection;
|
|
uint8_t mFillMode;
|
|
|
|
bool FillsForwards() const {
|
|
return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
|
|
mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS;
|
|
}
|
|
bool FillsBackwards() const {
|
|
return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
|
|
mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Stores the results of calculating the timing properties of an animation
|
|
* at a given sample time.
|
|
*/
|
|
struct ComputedTiming
|
|
{
|
|
ComputedTiming()
|
|
: mTimeFraction(kNullTimeFraction)
|
|
, mCurrentIteration(0)
|
|
, mPhase(AnimationPhase_Null)
|
|
{ }
|
|
|
|
static const double kNullTimeFraction;
|
|
|
|
// The total duration of the animation including all iterations.
|
|
// Will equal TimeDuration::Forever() if the animation repeats indefinitely.
|
|
TimeDuration mActiveDuration;
|
|
|
|
// Will be kNullTimeFraction if the animation is neither animating nor
|
|
// filling at the sampled time.
|
|
double mTimeFraction;
|
|
|
|
// Zero-based iteration index (meaningless if mTimeFraction is
|
|
// kNullTimeFraction).
|
|
uint64_t mCurrentIteration;
|
|
|
|
enum {
|
|
// Not sampled (null sample time)
|
|
AnimationPhase_Null,
|
|
// Sampled prior to the start of the active interval
|
|
AnimationPhase_Before,
|
|
// Sampled within the active interval
|
|
AnimationPhase_Active,
|
|
// Sampled after (or at) the end of the active interval
|
|
AnimationPhase_After
|
|
} mPhase;
|
|
};
|
|
|
|
class ComputedTimingFunction
|
|
{
|
|
public:
|
|
typedef nsTimingFunction::Type Type;
|
|
void Init(const nsTimingFunction &aFunction);
|
|
double GetValue(double aPortion) const;
|
|
const nsSMILKeySpline* GetFunction() const {
|
|
NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
|
|
return &mTimingFunction;
|
|
}
|
|
Type GetType() const { return mType; }
|
|
uint32_t GetSteps() const { return mSteps; }
|
|
|
|
private:
|
|
Type mType;
|
|
nsSMILKeySpline mTimingFunction;
|
|
uint32_t mSteps;
|
|
};
|
|
|
|
struct AnimationPropertySegment
|
|
{
|
|
float mFromKey, mToKey;
|
|
StyleAnimationValue mFromValue, mToValue;
|
|
ComputedTimingFunction mTimingFunction;
|
|
};
|
|
|
|
struct AnimationProperty
|
|
{
|
|
nsCSSProperty mProperty;
|
|
InfallibleTArray<AnimationPropertySegment> mSegments;
|
|
};
|
|
|
|
struct ElementPropertyTransition;
|
|
|
|
namespace dom {
|
|
|
|
class Animation : public nsWrapperCache
|
|
{
|
|
public:
|
|
Animation(nsIDocument* aDocument, const AnimationTiming &aTiming)
|
|
: mDocument(aDocument)
|
|
, mTiming(aTiming)
|
|
, mIsFinishedTransition(false)
|
|
, mLastNotification(LAST_NOTIFICATION_NONE)
|
|
{
|
|
SetIsDOMBinding();
|
|
}
|
|
|
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Animation)
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Animation)
|
|
|
|
nsIDocument* GetParentObject() const { return mDocument; }
|
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
|
|
// FIXME: If we succeed in moving transition-specific code to a type of
|
|
// AnimationEffect (as per the Web Animations API) we should remove these
|
|
// virtual methods.
|
|
virtual ElementPropertyTransition* AsTransition() { return nullptr; }
|
|
virtual const ElementPropertyTransition* AsTransition() const {
|
|
return nullptr;
|
|
}
|
|
|
|
void SetParentTime(Nullable<TimeDuration> aParentTime);
|
|
|
|
const AnimationTiming& Timing() const {
|
|
return mTiming;
|
|
}
|
|
AnimationTiming& Timing() {
|
|
return mTiming;
|
|
}
|
|
|
|
// Return the duration from the start the active interval to the point where
|
|
// the animation begins playback. This is zero unless the animation has
|
|
// a negative delay in which case it is the absolute value of the delay.
|
|
// This is used for setting the elapsedTime member of CSS AnimationEvents.
|
|
TimeDuration InitialAdvance() const {
|
|
return std::max(TimeDuration(), mTiming.mDelay * -1);
|
|
}
|
|
|
|
Nullable<TimeDuration> GetLocalTime() const {
|
|
// Since the *animation* start time is currently always zero, the local
|
|
// time is equal to the parent time.
|
|
return mParentTime;
|
|
}
|
|
|
|
// This function takes as input the timing parameters of an animation and
|
|
// returns the computed timing at the specified local time.
|
|
//
|
|
// The local time may be null in which case only static parameters such as the
|
|
// active duration are calculated. All other members of the returned object
|
|
// are given a null/initial value.
|
|
//
|
|
// This function returns ComputedTiming::kNullTimeFraction for the
|
|
// mTimeFraction member of the return value if the animation should not be
|
|
// run (because it is not currently active and is not filling at this time).
|
|
static ComputedTiming
|
|
GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
|
|
const AnimationTiming& aTiming);
|
|
|
|
// Shortcut for that gets the computed timing using the current local time as
|
|
// calculated from the timeline time.
|
|
ComputedTiming GetComputedTiming(const AnimationTiming* aTiming
|
|
= nullptr) const {
|
|
return GetComputedTimingAt(GetLocalTime(), aTiming ? *aTiming : mTiming);
|
|
}
|
|
|
|
// Return the duration of the active interval for the given timing parameters.
|
|
static TimeDuration ActiveDuration(const AnimationTiming& aTiming);
|
|
|
|
// After transitions finish they need to be retained for one throttle-able
|
|
// cycle (for reasons see explanation in
|
|
// layout/style/nsTransitionManager.cpp).
|
|
// In the meantime, however, they should be ignored.
|
|
bool IsFinishedTransition() const {
|
|
return mIsFinishedTransition;
|
|
}
|
|
|
|
void SetIsFinishedTransition() {
|
|
MOZ_ASSERT(AsTransition(),
|
|
"Calling SetIsFinishedTransition but it's not a transition");
|
|
mIsFinishedTransition = true;
|
|
}
|
|
|
|
bool IsCurrent() const {
|
|
if (IsFinishedTransition()) {
|
|
return false;
|
|
}
|
|
|
|
ComputedTiming computedTiming = GetComputedTiming();
|
|
return computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
|
|
computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
|
|
}
|
|
|
|
enum {
|
|
LAST_NOTIFICATION_NONE = uint64_t(-1),
|
|
LAST_NOTIFICATION_END = uint64_t(-2)
|
|
};
|
|
uint64_t LastNotification() const { return mLastNotification; }
|
|
void SetLastNotification(uint64_t aLastNotification) {
|
|
mLastNotification = aLastNotification;
|
|
}
|
|
|
|
bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
|
|
const InfallibleTArray<AnimationProperty>& Properties() const {
|
|
return mProperties;
|
|
}
|
|
InfallibleTArray<AnimationProperty>& Properties() {
|
|
return mProperties;
|
|
}
|
|
|
|
protected:
|
|
virtual ~Animation() { }
|
|
|
|
// We use a document for a parent object since the other likely candidate,
|
|
// the target element, can be empty.
|
|
nsRefPtr<nsIDocument> mDocument;
|
|
Nullable<TimeDuration> mParentTime;
|
|
|
|
AnimationTiming mTiming;
|
|
// A flag to mark transitions that have finished and are due to
|
|
// be removed on the next throttle-able cycle.
|
|
bool mIsFinishedTransition;
|
|
// One of the LAST_NOTIFICATION_* constants, or an integer for the iteration
|
|
// whose start we last notified on.
|
|
uint64_t mLastNotification;
|
|
|
|
InfallibleTArray<AnimationProperty> mProperties;
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_dom_Animation_h
|