-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS transition start value is not computed correctly #7816
Comments
Maybe related to #7781. |
Presumably we're getting incorrect values in http://mxr.mozilla.org/servo/source/components/layout/animation.rs#22 . The trick is figuring out why that's happening. |
The new style is reset to old style in property_animation.update(new_style, 0.0); then it's supposed to be set to the final style in animation.property_animation.update(&mut *Arc::make_mut(style), 1.0); But |
@pcwalton why is |
Can animations be interrupted or updated? Doesn't appear to work. Did it ever work or it's not implemented yet? |
@paulrouget I'm confused by what "reset to its initial value" means here—could you elaborate? It's not safe to call |
Sure. Keep in mind that I'm really not familiar with this code, so feel free to tell me if I'm totally off track :) I'm looking at when // Trigger transitions if necessary. This will reset `this_style` back to its old value if
// it did trigger a transition. … and in // Set the property to the initial value.
property_animation.update(new_style, 0.0); So in Without digging too much, I just assumed that it meant that when a DOM element goes from By "reset to its initial value", I meant that we do not switch to Assuming I assumed right: Like you said, we can't update it during the transition, so it's done at the end. But:
|
|
Not all of them! div {
position: absolute;
top: 10px;
left: 10px;
width: 100px;
height: 100px;
background: red;
transition: all 1000ms linear;
opacity: 0.1;
}
div.foo {
width: 200px;
opacity: 1;
transform: translateY(200px);
} 3 properties are being animated. From From Opacity and transform are properties that do not require reflow. They have that in common. So I guess that explain why they behave differently (something like OMTA in Gecko). So here, I see 3 issues, and I don't know how much they are related:
|
Commenting out this line: https://mxr.mozilla.org/servo/source/components/layout/animation.rs#33 solves all the issues mentioned above. But I'm not sure to understand why it's here in the first place. There's a very short and barely noticeable flickering at the beginning of the animation where the |
@pcwalton: can you please explain why this line is necessary: https://mxr.mozilla.org/servo/source/components/layout/animation.rs#33 Can you confirm that |
I guess we could do that on |
You can't call |
To be more specific, there is no access to the DOM during animations. It's forbidden, because JS could be running concurrently during a transition (which is the whole point of OMT animations). |
That line is trying to set the animation to its original start value, but I guess the start value for the animation isn't properly taking the cascade into account. We will need to fix the code that initializes the animation. You can't access the DOM during animations, so this has to be all set up properly in advance. |
We should keep a list of finished animations, then at the next cascade, we can update the property value. Also, if animations are not finished, we should cancel them and update the style according to the current time. @pcwalton does this require some big changes or it's just a matter of piping the right things together? In other words, do you think I can fix that or it's better if you take care of it? |
Pinging @pcwalton This is blocking browser.html progress. |
@paulrouget I don't think it'll be too tough—a medium-sized change, perhaps? |
In Something like replacing: animation.property_animation.update(&mut *Arc::make_mut(style), 1.0); with: let now = clock_ticks::precise_time_s();
let mut progress = (now - animation.start_time) / animation.duration();
if progress > 1.0 {
progress = 1.0
}
if progress > 0.0 {
animation.property_animation.update(&mut *Arc::make_mut(style), progress);
} This appears to work. We should also cancel the animation at this point (not sure how yet). Now, we also need to handle finished animations here, but finished animations are not accessible at this point. So in |
Seems reasonable to me. |
Well, I think this is beyond what I can do. Things are getting hairy when trying to cancel the animation on a property that is being modified in cascade_node. Maybe someone else can take over. Summary of what (I think) should be done:
|
@pcwalton agreed to take this |
I have a fix for this locally. Testing performance now. |
animations complete or are interrupted. This adds a new pair of reader-writer locks. I measured the performance of style recalculation on Wikipedia and the overhead of the locks was not measurable. Closes servo#7816.
Write animated values into the `ComputedValues` structures when animations complete or are interrupted. This adds a new pair of reader-writer locks. I measured the performance of style recalculation on Wikipedia and the overhead of the locks was not measurable. Closes #7816. cc @paulrouget r? @glennw <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8670) <!-- Reviewable:end -->
animations complete or are interrupted. This adds a new pair of reader-writer locks. I measured the performance of style recalculation on Wikipedia and the overhead of the locks was not measurable. Closes servo#7816.
In the example below, the
transform:translateX
value is incremented every 2 seconds. A CSS transition animates the div. But during the animation, the start value is not the value set via the style attribute, but the initial value set in the CSS rule.EDIT
Here is an example that highlight all the problems I found while working on this issue:
The text was updated successfully, but these errors were encountered: