Commit d19daf6c authored by hyatt@apple.com's avatar hyatt@apple.com

2008-07-09 David Hyatt <hyatt@apple.com>

        Switch transitions back to a "destination" model as far as choosing which transitions should apply on a style
        change.  Preserve the behavior of allowing stale transitions (in the absence of property changes) to run to
        completion.

        Reviewed by Dean

        * manual-tests/transitions.html:
        * manual-tests/transitions2.html:
        * page/AnimationController.cpp:
        (WebCore::ImplicitAnimation::reset):
        (WebCore::CompositeImplicitAnimation::animate):
        (WebCore::AnimationControllerPrivate::get):
        (WebCore::AnimationController::updateImplicitAnimations):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@35074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f8491e23
2008-07-09 David Hyatt <hyatt@apple.com>
Switch transitions back to a "destination" model as far as choosing which transitions should apply on a style
change. Preserve the behavior of allowing stale transitions (in the absence of property changes) to run to
completion.
Reviewed by Dean
* manual-tests/transitions.html:
* manual-tests/transitions2.html:
* page/AnimationController.cpp:
(WebCore::ImplicitAnimation::reset):
(WebCore::CompositeImplicitAnimation::animate):
(WebCore::AnimationControllerPrivate::get):
(WebCore::AnimationController::updateImplicitAnimations):
2008-07-09 Michelangelo De Simone <m.des@mac.com>
Reviewed by Adele.
......@@ -28,14 +28,14 @@
<script>
var state = 0;
var transitions = [
{className:"green", description:"instantly change into a green rectangle"},
{className:"", description:"instantly change into a small green square then animate to yellow over 5 seconds"},
{className:"square", description:"instantly change into a big yellow square"},
{className:"green", description:"instantly change into a green square and then animate to a rectangle over 2 seconds"},
{className:"", description:"instantly change into a small green square then animate to yellow over 5 seconds"},
{className:"green", description:"instantly change into a green rectangle"},
{className:"square", description:"instantly change into a green square then animate to yellow over 5 seconds"},
{className:"", description:"instantly change into a rectangle then animate into a square over 2 seconds"}
{className:"green", description:"instantly change into a rectangle and fade from yellow to green over 5 seconds"},
{className:"", description:"instantly change into a small yellow square"},
{className:"square", description:"instantly change into a yellow rectangle and then animate into a big yellow square over 2 seconds"},
{className:"green", description:"instantly change into a yellow rectangle and then animate to a green rectangle over 5 seconds"},
{className:"", description:"instantly change into a small yellow square"},
{className:"green", description:"instantly change into a yellow rectangle and fade from yellow to green over 5 seconds"},
{className:"square", description:"instantly change to a yellow rectangle and then animate into a large yellow square over 2 seconds"},
{className:"", description:"instantly change into a small yellow square"}
];
document.getElementById("description").innerText = transitions[0].description;
......
......@@ -15,8 +15,8 @@
div.rectangle {
width: 100px;
height: 200px;
-webkit-transition-property: all;
-webkit-transition-duration: 2s;
-webkit-transition-property: width, height;
-webkit-transition-duration: 5s;
}
</style>
<p id="instructions">
......@@ -28,12 +28,12 @@
<script>
var state = 0;
var transitions = [
{className:"square", description:"instantly change into a larger square"},
{className:"rectangle", description:"animate to a rectangle over 2 seconds"},
{className:"square", description:"animate to a square over 2 seconds"},
{className:"", description:"instantly change to a small rectangle and then animate to a small square over 2 seconds"},
{className:"rectangle", description:"instantly change into a large rectangle"},
{className:"", description:"animate into a small square over 2 seconds"}
{className:"rectangle", description:"animate to a large rectangle over 5 seconds."},
{className:"square", description:"animate to a square over 2 seconds. Try clicking before the first animation finishes and make sure the width doesn't do an ugly jump."},
{className:"", description:"instantly change to a small square"},
{className:"square", description:"instantly change into a small rectangle and then animate into a large square over 2 seconds"},
{className:"rectangle", description:"animate to a large rectangle over 5 seconds"},
{className:"", description:"instantly change to a small square"}
];
document.getElementById("description").innerText = transitions[0].description;
......
......@@ -148,10 +148,10 @@ void ImplicitAnimation::reset(RenderObject* renderer, RenderStyle* from, RenderS
if (from || to)
m_startTime = currentTime();
// If we are stale, attempt to update to a new transition using the new |from| style. If we are able to find a new transition,
// If we are stale, attempt to update to a new transition using the new |to| style. If we are able to find a new transition,
// then we will unmark ourselves for death.
if (stale() && from && to) {
for (const Transition* transition = from->transitions(); transition; transition = transition->next()) {
for (const Transition* transition = to->transitions(); transition; transition = transition->next()) {
if (m_property != transition->property())
continue;
int duration = transition->duration();
......@@ -384,12 +384,20 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS
{
const Transition* currentTransitions = currentStyle->transitions();
const Transition* targetTransitions = targetStyle->transitions();
bool transitionsChanged = currentTransitions != targetTransitions && !(currentTransitions && targetTransitions && *currentTransitions == *targetTransitions);
bool transitionsChanged = m_animations.isEmpty() || (currentTransitions != targetTransitions && !(currentTransitions && targetTransitions && *currentTransitions == *targetTransitions));
if (m_animations.isEmpty()) {
// For each transition, we create a new animation unless one exists already (later occurrences of duplicate
// triggers in the layer list get ignored).
for (const Transition* transition = currentTransitions; transition; transition = transition->next()) {
if (transitionsChanged) {
HashMap<int, ImplicitAnimation*>::iterator end = m_animations.end();
for (HashMap<int, ImplicitAnimation*>::iterator it = m_animations.begin(); it != end; ++it)
// Mark any running animations as stale if the set of transitions changed. Stale animations continue
// to blend on a timer, and then remove themselves when finished.
it->second->setStale();
// If our transitions changed we need to add new animations for any transitions that
// don't exist yet. If a new transition conflicts with a currently running stale transition, then we will not add it.
// The stale transition is responsible for updating itself to the new transition if it ever gets reset or finishes.
for (const Transition* transition = targetTransitions; transition; transition = transition->next()) {
int property = transition->property();
int duration = transition->duration();
int repeatCount = transition->repeatCount();
......@@ -399,7 +407,7 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS
}
}
}
// Now that we have animation objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
RenderStyle* result = 0;
......@@ -410,11 +418,7 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS
ImplicitAnimation* allAnimation = m_animations.get(cAnimateAll);
if (allAnimation) {
allAnimation->animate(this, renderer, currentStyle, targetStyle, result);
if (transitionsChanged)
// Mark the "all" animation as stale if the set of transitions changed. Stale animations continue
// to blend on a timer, and then remove themselves when finished.
allAnimation->setStale();
// If the animation is done and we are marked as stale, then we can be removed after the
// iteration of the hashmap is finished.
if (allAnimation->finished() && allAnimation->stale())
......@@ -428,11 +432,7 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS
continue;
it->second->animate(this, renderer, currentStyle, targetStyle, result);
if (transitionsChanged)
// Mark any running animations as stale if the set of transitions changed. Stale animations continue
// to blend on a timer, and then remove themselves when finished.
it->second->setStale();
// If the animation is done and we are marked as stale, then we can be removed after the
// iteration of the hashmap is finished.
if (it->second->finished() && it->second->stale())
......@@ -447,21 +447,6 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS
delete animation;
}
if (transitionsChanged) {
// If our transitions changed we need to add new animations for any transitions that
// don't exist yet. If a new transition conflicts with a currently running stale transition, then we will not add it.
// The stale transition is responsible for updating itself to the new transition if it ever gets reset or finishes.
for (const Transition* transition = targetTransitions; transition; transition = transition->next()) {
int property = transition->property();
int duration = transition->duration();
int repeatCount = transition->repeatCount();
if (property && duration && repeatCount && !m_animations.contains(property)) {
ImplicitAnimation* animation = new ImplicitAnimation(transition);
m_animations.set(property, animation);
}
}
}
if (result)
return result;
......@@ -489,7 +474,7 @@ public:
AnimationControllerPrivate(Frame*);
~AnimationControllerPrivate();
CompositeImplicitAnimation* get(RenderObject*);
CompositeImplicitAnimation* get(RenderObject*, RenderStyle*);
bool clear(RenderObject*);
void timerFired(Timer<AnimationControllerPrivate>*);
......@@ -514,10 +499,10 @@ AnimationControllerPrivate::~AnimationControllerPrivate()
deleteAllValues(m_animations);
}
CompositeImplicitAnimation* AnimationControllerPrivate::get(RenderObject* renderer)
CompositeImplicitAnimation* AnimationControllerPrivate::get(RenderObject* renderer, RenderStyle* targetStyle)
{
CompositeImplicitAnimation* animation = m_animations.get(renderer);
if (!animation && renderer->style()->transitions()) {
if (!animation && targetStyle->transitions()) {
animation = new CompositeImplicitAnimation();
m_animations.set(renderer, animation);
}
......@@ -598,8 +583,8 @@ RenderStyle* AnimationController::updateImplicitAnimations(RenderObject* rendere
// a new style.
ASSERT(renderer->element()); // FIXME: We do not animate generated content yet.
CompositeImplicitAnimation* animation = m_data->get(renderer);
if (!animation)
CompositeImplicitAnimation* animation = m_data->get(renderer, newStyle);
if (!animation && !newStyle->transitions())
return newStyle;
RenderStyle* result = animation->animate(renderer, renderer->style(), newStyle);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment