Changeset 289454 in webkit


Ignore:
Timestamp:
Feb 8, 2022 10:25:57 PM (5 months ago)
Author:
graouts@webkit.org
Message:

[web-animations] additive and accumulation interpolation does not work correctly with implicit 0% and 100% keyframes
https://bugs.webkit.org/show_bug.cgi?id=236314

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Add some new WPT tests and mark our PASS results for the "add" case (we still fail for "accumulate").

  • web-platform-tests/web-animations/animation-model/combining-effects/effect-composition-expected.txt:
  • web-platform-tests/web-animations/animation-model/combining-effects/effect-composition.html:

Source/WebCore:

We incorrectly handled implicit keyframes for the additive and accumulate cases.

The spec says that for implicit 0% and 100% keyframes, a keyframe should be generated with a "neutral" keyframe which,
when added or accumulated with another keyframe, would yield the same style as the keyframe it's composed with. We sort
of did the right thing by cloning the underlying style for those keyframes, but then we would blame them anyway in the
composition case, whereas we should just use the underlying style as-is.

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::setAnimatedPropertiesInStyle):

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r289453 r289454  
     12022-02-08  Antoine Quint  <graouts@webkit.org>
     2
     3        [web-animations] additive and accumulation interpolation does not work correctly with implicit 0% and 100% keyframes
     4        https://bugs.webkit.org/show_bug.cgi?id=236314
     5
     6        Reviewed by Dean Jackson.
     7
     8        Add some new WPT tests and mark our PASS results for the "add" case (we still fail for "accumulate").
     9
     10        * web-platform-tests/web-animations/animation-model/combining-effects/effect-composition-expected.txt:
     11        * web-platform-tests/web-animations/animation-model/combining-effects/effect-composition.html:
     12
    1132022-02-08  Antoine Quint  <graouts@webkit.org>
    214
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/combining-effects/effect-composition-expected.txt

    r285397 r289454  
    22PASS accumulate onto the base value
    33PASS accumulate onto an underlying animation value
     4FAIL accumulate onto an underlying animation value with implicit from values assert_equals: Animated style at 50% expected "matrix(1, 0, 0, 1, 50, 50)" but got "matrix(1, 0, 0, 1, 25, 50)"
     5FAIL accumulate onto an underlying animation value with implicit to values assert_equals: Animated style at 50% expected "matrix(1, 0, 0, 1, 50, 50)" but got "matrix(1, 0, 0, 1, 25, 50)"
    46PASS Composite when mixing accumulate and replace
    57PASS accumulate specified on a keyframe overrides the composite mode of the effect
     
    79PASS add onto the base value
    810PASS add onto an underlying animation value
     11PASS add onto an underlying animation value with implicit from values
     12PASS add onto an underlying animation value with implicit to values
    913PASS Composite when mixing add and replace
    1014PASS add specified on a keyframe overrides the composite mode of the effect
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/combining-effects/effect-composition.html

    r250263 r289454  
    3939      'Animated style at 50%');
    4040  }, `${composite} onto an underlying animation value`);
     41
     42  test(t => {
     43    const div = createDiv(t);
     44    const anims = [];
     45    anims.push(div.animate({ transform: 'translateX(100px)' }, { duration: 100, composite: 'replace' }));
     46    anims.push(div.animate({ transform: 'translateY(100px)' }, { duration: 100, composite }));
     47
     48    for (const anim of anims) {
     49      anim.currentTime = 50;
     50    }
     51
     52    assert_equals(getComputedStyle(div).transform, 'matrix(1, 0, 0, 1, 50, 50)',
     53      'Animated style at 50%');
     54  }, `${composite} onto an underlying animation value with implicit from values`);
     55
     56  test(t => {
     57    const div = createDiv(t);
     58    const anims = [];
     59    anims.push(div.animate([{ offset: 1, transform: 'translateX(100px)' }], { duration: 100, composite: 'replace' }));
     60    anims.push(div.animate([{ offset: 1, transform: 'translateY(100px)' }], { duration: 100, composite }));
     61
     62    for (const anim of anims) {
     63      anim.currentTime = 50;
     64    }
     65
     66    assert_equals(getComputedStyle(div).transform, 'matrix(1, 0, 0, 1, 50, 50)',
     67      'Animated style at 50%');
     68  }, `${composite} onto an underlying animation value with implicit to values`);
    4169
    4270  test(t => {
  • trunk/Source/WebCore/ChangeLog

    r289453 r289454  
     12022-02-08  Antoine Quint  <graouts@webkit.org>
     2
     3        [web-animations] additive and accumulation interpolation does not work correctly with implicit 0% and 100% keyframes
     4        https://bugs.webkit.org/show_bug.cgi?id=236314
     5
     6        Reviewed by Dean Jackson.
     7
     8        We incorrectly handled implicit keyframes for the additive and accumulate cases.
     9
     10        The spec says that for implicit 0% and 100% keyframes, a keyframe should be generated with a "neutral" keyframe which,
     11        when added or accumulated with another keyframe, would yield the same style as the keyframe it's composed with. We sort
     12        of did the right thing by cloning the underlying style for those keyframes, but then we would blame them anyway in the
     13        composition case, whereas we should just use the underlying style as-is.
     14
     15        * animation/KeyframeEffect.cpp:
     16        (WebCore::KeyframeEffect::setAnimatedPropertiesInStyle):
     17
    1182022-02-08  Antoine Quint  <graouts@webkit.org>
    219
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r289426 r289454  
    14691469            continue;
    14701470
     1471        auto hasImplicitZeroKeyframe = !numberOfKeyframesWithZeroOffset;
     1472        auto hasImplicitOneKeyframe = !numberOfKeyframesWithOneOffset;
     1473
    14711474        // 8. If there is no keyframe in property-specific keyframes with a computed keyframe offset of 0, create a new keyframe with a computed keyframe
    14721475        //    offset of 0, a property value set to the neutral value for composition, and a composite operation of add, and prepend it to the beginning of
    14731476        //    property-specific keyframes.
    1474         if (!numberOfKeyframesWithZeroOffset) {
     1477        if (hasImplicitZeroKeyframe) {
    14751478            propertySpecificKeyframes.insert(0, &propertySpecificKeyframeWithZeroOffset);
    14761479            numberOfKeyframesWithZeroOffset = 1;
     
    14801483        //    keyframe offset of 1, a property value set to the neutral value for composition, and a composite operation of add, and append it to the end of
    14811484        //    property-specific keyframes.
    1482         if (!numberOfKeyframesWithOneOffset) {
     1485        if (hasImplicitOneKeyframe) {
    14831486            propertySpecificKeyframes.append(&propertySpecificKeyframeWithOneOffset);
    14841487            numberOfKeyframesWithOneOffset = 1;
     
    15411544        //            target property’s animation type.
    15421545        if (CSSPropertyAnimation::isPropertyAdditiveOrCumulative(cssPropertyId)) {
    1543             auto startKeyframeCompositeOperation = startKeyframe.compositeOperation().value_or(m_compositeOperation);
    1544             if (startKeyframeCompositeOperation != CompositeOperation::Replace)
    1545                 CSSPropertyAnimation::blendProperties(this, cssPropertyId, startKeyframeStyle, targetStyle, *startKeyframe.style(), 1, startKeyframeCompositeOperation);
    1546 
    1547             auto endKeyframeCompositeOperation = endKeyframe.compositeOperation().value_or(m_compositeOperation);
    1548             if (endKeyframeCompositeOperation != CompositeOperation::Replace)
    1549                 CSSPropertyAnimation::blendProperties(this, cssPropertyId, endKeyframeStyle, targetStyle, *endKeyframe.style(), 1, endKeyframeCompositeOperation);
     1546            // Only do this for the 0 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
     1547            // for composition" which really means we don't want to do anything but rather just use the underlying style which
     1548            // is already set on startKeyframe.
     1549            if (!startKeyframe.key() && !hasImplicitZeroKeyframe) {
     1550                auto startKeyframeCompositeOperation = startKeyframe.compositeOperation().value_or(m_compositeOperation);
     1551                if (startKeyframeCompositeOperation != CompositeOperation::Replace)
     1552                    CSSPropertyAnimation::blendProperties(this, cssPropertyId, startKeyframeStyle, targetStyle, *startKeyframe.style(), 1, startKeyframeCompositeOperation);
     1553            }
     1554
     1555            // Only do this for the 1 keyframe if it was provided explicitly, since otherwise we want to use the "neutral value
     1556            // for composition" which really means we don't want to do anything but rather just use the underlying style which
     1557            // is already set on endKeyframe.
     1558            if (endKeyframe.key() == 1 && !hasImplicitOneKeyframe) {
     1559                auto endKeyframeCompositeOperation = endKeyframe.compositeOperation().value_or(m_compositeOperation);
     1560                if (endKeyframeCompositeOperation != CompositeOperation::Replace)
     1561                    CSSPropertyAnimation::blendProperties(this, cssPropertyId, endKeyframeStyle, targetStyle, *endKeyframe.style(), 1, endKeyframeCompositeOperation);
     1562            }
    15501563        }
    15511564
Note: See TracChangeset for help on using the changeset viewer.