Bug 1004871 part 2 - Add AnimationTiming struct, to encapsulate animation timing parameters; r=dholbert

Introduces a struct to store timing parameters for passing to
GetPositionInIteration. In future this struct is expected to be expanded to
include other timing parameters as well (based roughly on Web Animations'
"Timing" interface, hence the name AnimationTiming).
This commit is contained in:
Brian Birtles 2014-05-28 16:51:49 +09:00
parent 2fe00ba5c9
commit f22f27e127
5 changed files with 59 additions and 37 deletions

View File

@ -328,10 +328,12 @@ AddAnimationForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
aLayer->AddAnimation();
animation->startTime() = ea->mStartTime + ea->mDelay;
animation->duration() = ea->mIterationDuration;
animation->duration() = ea->mTiming.mIterationDuration;
animation->numIterations() =
ea->mIterationCount != NS_IEEEPositiveInfinity() ? ea->mIterationCount : -1;
animation->direction() = ea->mDirection;
ea->mTiming.mIterationCount != NS_IEEEPositiveInfinity() ?
ea->mTiming.mIterationCount :
-1;
animation->direction() = ea->mTiming.mDirection;
animation->property() = aProperty;
animation->data() = aData;

View File

@ -365,13 +365,15 @@ ComputedTimingFunction::GetValue(double aPortion) const
bool
ElementAnimation::IsRunningAt(TimeStamp aTime) const
{
if (IsPaused() || mIterationDuration.ToMilliseconds() <= 0.0 ||
if (IsPaused() || mTiming.mIterationDuration.ToMilliseconds() <= 0.0 ||
mStartTime.IsNull()) {
return false;
}
double iterationsElapsed = ElapsedDurationAt(aTime) / mIterationDuration;
return 0.0 <= iterationsElapsed && iterationsElapsed < mIterationCount;
double iterationsElapsed =
ElapsedDurationAt(aTime) / mTiming.mIterationDuration;
return 0.0 <= iterationsElapsed &&
iterationsElapsed < mTiming.mIterationCount;
}
bool

View File

@ -219,6 +219,21 @@ struct AnimationProperty
InfallibleTArray<AnimationPropertySegment> mSegments;
};
/**
* 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
{
mozilla::TimeDuration mIterationDuration;
float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
uint8_t mDirection;
uint8_t mFillMode;
};
/**
* Data about one animation (i.e., one of the values of
* 'animation-name') running on an element.
@ -241,18 +256,16 @@ struct ElementAnimation
}
nsString mName; // empty string for 'none'
float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
uint8_t mDirection;
uint8_t mFillMode;
AnimationTiming mTiming;
uint8_t mPlayState;
bool FillsForwards() const {
return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS;
return mTiming.mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
mTiming.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;
return mTiming.mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH ||
mTiming.mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
}
bool IsPaused() const {
@ -276,7 +289,6 @@ struct ElementAnimation
mozilla::TimeStamp mStartTime;
mozilla::TimeStamp mPauseStart;
mozilla::TimeDuration mDelay;
mozilla::TimeDuration mIterationDuration;
bool mIsRunningOnCompositor;
enum {

View File

@ -171,7 +171,7 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
ElementAnimation* anim = mAnimations[animIdx];
if (anim->mProperties.IsEmpty() ||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
anim->mTiming.mIterationDuration.ToMilliseconds() <= 0.0) {
continue;
}
@ -179,8 +179,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
// FIXME: avoid recalculating every time when paused.
double positionInIteration =
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
anim->mIterationDuration, anim->mIterationCount,
anim->mDirection,
anim->mTiming.mIterationDuration,
anim->mTiming.mIterationCount,
anim->mTiming.mDirection,
NS_STYLE_ANIMATION_FILL_MODE_BOTH);
// XXX We shouldn't really be using mLastNotification as a general
@ -224,7 +225,7 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
ElementAnimation* anim = mAnimations[animIdx];
if (anim->mProperties.IsEmpty() ||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
anim->mTiming.mIterationDuration.ToMilliseconds() <= 0.0) {
// The animation isn't active or filling at this time.
continue;
}
@ -233,8 +234,10 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
// FIXME: avoid recalculating every time when paused.
double positionInIteration =
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
anim->mIterationDuration, anim->mIterationCount,
anim->mDirection, anim->mFillMode);
anim->mTiming.mIterationDuration,
anim->mTiming.mIterationCount,
anim->mTiming.mDirection,
anim->mTiming.mFillMode);
// XXX Only set mNeedsRefreshes to true when we are either in the before
// or active phase (the reason we test for <= 1 rather than <1 is to cover
// cases where we have an alternating direction which can produce a value
@ -335,14 +338,16 @@ ElementAnimations::GetEventsAt(TimeStamp aRefreshTime,
// We will fix this separately but for now this is necessary since
// GetPositionInIteration does not yet handle zero-duration iterations.
if (anim->mProperties.IsEmpty() ||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
anim->mTiming.mIterationDuration.ToMilliseconds() <= 0.0) {
// The animation isn't active or filling at this time.
continue;
}
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
anim->mIterationDuration, anim->mIterationCount,
anim->mDirection, anim->mFillMode,
anim->mTiming.mIterationDuration,
anim->mTiming.mIterationCount,
anim->mTiming.mDirection,
anim->mTiming.mFillMode,
anim, this, &aEventsToDispatch);
}
}
@ -754,9 +759,12 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
*aAnimations.AppendElement(new ElementAnimation());
dest->mName = src.GetName();
dest->mIterationCount = src.GetIterationCount();
dest->mDirection = src.GetDirection();
dest->mFillMode = src.GetFillMode();
dest->mTiming.mIterationDuration =
TimeDuration::FromMilliseconds(src.GetDuration());
dest->mTiming.mIterationCount = src.GetIterationCount();
dest->mTiming.mDirection = src.GetDirection();
dest->mTiming.mFillMode = src.GetFillMode();
dest->mPlayState = src.GetPlayState();
dest->mDelay = TimeDuration::FromMilliseconds(src.GetDelay());
@ -767,9 +775,6 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
dest->mPauseStart = TimeStamp();
}
dest->mIterationDuration =
TimeDuration::FromMilliseconds(src.GetDuration());
nsCSSKeyframesRule* rule =
mPresContext->StyleSet()->KeyframesRuleForName(mPresContext,
dest->mName);

View File

@ -52,7 +52,7 @@ ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
// Set |timePortion| to the portion of the way we are through the time
// input to the transition's timing function (always within the range
// 0-1).
double duration = mIterationDuration.ToSeconds();
double duration = mTiming.mIterationDuration.ToSeconds();
NS_ABORT_IF_FALSE(duration >= 0.0, "negative duration forbidden");
double timePortion;
if (IsRemovedSentinel()) {
@ -696,10 +696,10 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
pt->mStartTime = mostRecentRefresh;
pt->mDelay = TimeDuration::FromMilliseconds(delay);
pt->mIterationDuration = TimeDuration::FromMilliseconds(duration);
pt->mIterationCount = 1;
pt->mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
pt->mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
pt->mTiming.mIterationDuration = TimeDuration::FromMilliseconds(duration);
pt->mTiming.mIterationCount = 1;
pt->mTiming.mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
pt->mTiming.mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
pt->mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
pt->mPauseStart = TimeStamp();
@ -963,8 +963,8 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
if (aFlags == Can_Throttle) {
et->mAnimations.RemoveElementAt(i);
}
} else if (pt->mStartTime + pt->mDelay + pt->mIterationDuration <=
now) {
} else if (pt->mStartTime + pt->mDelay +
pt->mTiming.mIterationDuration <= now) {
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
nsCSSProperty prop = pt->mProperties[0].mProperty;
@ -976,7 +976,8 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
NS_NAMED_LITERAL_STRING(before, "::before");
NS_NAMED_LITERAL_STRING(after, "::after");
events.AppendElement(
TransitionEventInfo(et->mElement, prop, pt->mIterationDuration,
TransitionEventInfo(et->mElement, prop,
pt->mTiming.mIterationDuration,
ep == nsGkAtoms::transitionsProperty ?
EmptyString() :
ep == nsGkAtoms::transitionsOfBeforeProperty ?