Skip to content
Permalink
Browse files
[web-animations] support interpolation of <color> custom properties
https://bugs.webkit.org/show_bug.cgi?id=249400

Reviewed by Antti Koivisto.

* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/animation/custom-property-animation-color-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/animation/custom-property-animation-color.html:
* Source/WebCore/animation/CSSPropertyAnimation.cpp:
(WebCore::blendSyntaxValues):
(WebCore::blendedCSSCustomPropertyValue):
(WebCore::blendCustomProperty):
(WebCore::CSSPropertyAnimation::propertyRequiresBlendingForAccumulativeIteration):

Canonical link: https://commits.webkit.org/257929@main
  • Loading branch information
graouts committed Dec 15, 2022
1 parent c08063e commit f468157282274052408d0a96e6faf01be99776d8
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 10 deletions.
@@ -0,0 +1,7 @@

PASS Animating a custom property of type <color>
PASS Animating a custom property of type <color> with a single keyframe
PASS Animating a custom property of type <color> with additivity
PASS Animating a custom property of type <color> with a single keyframe and additivity
PASS Animating a custom property of type <color> with iterationComposite

@@ -9,12 +9,49 @@
animation_test({
syntax: "<color>",
inherits: false,
initialValue: "red"
initialValue: "black"
}, {
keyframes: ["blue", "green"],
expected: "rgb(0, 64, 128)"
keyframes: ["rgb(100, 100, 100)", "rgb(200, 200, 200)"],
expected: "rgb(150, 150, 150)"
}, 'Animating a custom property of type <color>');

// Need to test accumulation, iterationComposite, etc.
animation_test({
syntax: "<color>",
inherits: false,
initialValue: "rgb(100, 100, 100)"
}, {
keyframes: "rgb(200, 200, 200)",
expected: "rgb(150, 150, 150)"
}, 'Animating a custom property of type <color> with a single keyframe');

animation_test({
syntax: "<color>",
inherits: false,
initialValue: "rgb(100, 100, 100)"
}, {
composite: "add",
keyframes: ["rgb(50, 50, 50)", "rgb(150, 150, 150)"],
expected: "rgb(200, 200, 200)"
}, 'Animating a custom property of type <color> with additivity');

animation_test({
syntax: "<color>",
inherits: false,
initialValue: "rgb(100, 100, 100)"
}, {
composite: "add",
keyframes: "rgb(150, 150, 150)",
expected: "rgb(175, 175, 175)"
}, 'Animating a custom property of type <color> with a single keyframe and additivity');

animation_test({
syntax: "<color>",
inherits: false,
initialValue: "black"
}, {
iterationComposite: "accumulate",
keyframes: ["rgb(0, 0, 0)", "rgb(100, 100, 100)"],
expected: "rgb(250, 250, 250)"
}, 'Animating a custom property of type <color> with iterationComposite');

</script>
@@ -3913,20 +3913,27 @@ static void blendStandardProperty(const CSSPropertyBlendingClient& client, CSSPr
}
}

static std::optional<CSSCustomPropertyValue::SyntaxValue> blendSyntaxValues(const CSSCustomPropertyValue::SyntaxValue& from, const CSSCustomPropertyValue::SyntaxValue& to, const CSSPropertyBlendingContext& blendingContext)
static std::optional<CSSCustomPropertyValue::SyntaxValue> blendSyntaxValues(const RenderStyle& fromStyle, const RenderStyle& toStyle, const CSSCustomPropertyValue::SyntaxValue& from, const CSSCustomPropertyValue::SyntaxValue& to, const CSSPropertyBlendingContext& blendingContext)
{
if (std::holds_alternative<Length>(from) && std::holds_alternative<Length>(to))
return blendFunc(std::get<Length>(from), std::get<Length>(to), blendingContext);

if (std::holds_alternative<StyleColor>(from) && std::holds_alternative<StyleColor>(to)) {
auto& fromStyleColor = std::get<StyleColor>(from);
auto& toStyleColor = std::get<StyleColor>(to);
if (!RenderStyle::isCurrentColor(fromStyleColor) || !RenderStyle::isCurrentColor(toStyleColor))
return blendFunc(fromStyle.colorResolvingCurrentColor(fromStyleColor), toStyle.colorResolvingCurrentColor(toStyleColor), blendingContext);
}

return std::nullopt;
}

static Ref<CSSCustomPropertyValue> blendedCSSCustomPropertyValue(const CSSCustomPropertyValue& from, const CSSCustomPropertyValue& to, const CSSPropertyBlendingContext& blendingContext)
static Ref<CSSCustomPropertyValue> blendedCSSCustomPropertyValue(const RenderStyle& fromStyle, const RenderStyle& toStyle, const CSSCustomPropertyValue& from, const CSSCustomPropertyValue& to, const CSSPropertyBlendingContext& blendingContext)
{
if (std::holds_alternative<CSSCustomPropertyValue::SyntaxValue>(from.value()) && std::holds_alternative<CSSCustomPropertyValue::SyntaxValue>(to.value())) {
auto& fromSyntaxValue = std::get<CSSCustomPropertyValue::SyntaxValue>(from.value());
auto& toSyntaxValue = std::get<CSSCustomPropertyValue::SyntaxValue>(to.value());
if (auto blendedSyntaxValue = blendSyntaxValues(fromSyntaxValue, toSyntaxValue, blendingContext))
if (auto blendedSyntaxValue = blendSyntaxValues(fromStyle, toStyle, fromSyntaxValue, toSyntaxValue, blendingContext))
return CSSCustomPropertyValue::createForSyntaxValue(from.name(), WTFMove(*blendedSyntaxValue));
}

@@ -3960,13 +3967,13 @@ static void blendCustomProperty(const CSSPropertyBlendingClient& client, const A
{
auto [fromValue, toValue] = customPropertyValuesForBlending(client, customProperty, from.nonInheritedCustomProperties().get(customProperty), to.nonInheritedCustomProperties().get(customProperty));
if (fromValue && toValue)
destination.setNonInheritedCustomPropertyValue(customProperty, blendedCSSCustomPropertyValue(*fromValue, *toValue, blendingContext));
destination.setNonInheritedCustomPropertyValue(customProperty, blendedCSSCustomPropertyValue(from, to, *fromValue, *toValue, blendingContext));
}

{
auto [fromValue, toValue] = customPropertyValuesForBlending(client, customProperty, from.inheritedCustomProperties().get(customProperty), to.inheritedCustomProperties().get(customProperty));
if (fromValue && toValue)
destination.setInheritedCustomPropertyValue(customProperty, blendedCSSCustomPropertyValue(*fromValue, *toValue, blendingContext));
destination.setInheritedCustomPropertyValue(customProperty, blendedCSSCustomPropertyValue(from, to, *fromValue, *toValue, blendingContext));
}
}

@@ -4015,10 +4022,12 @@ bool CSSPropertyAnimation::propertyRequiresBlendingForAccumulativeIteration(cons
auto& fromSyntaxValue = std::get<CSSCustomPropertyValue::SyntaxValue>(from->value());
auto& toSyntaxValue = std::get<CSSCustomPropertyValue::SyntaxValue>(to->value());

// FIXME: we need to also ensure we blend for iterationComposite for <color>, <transform-list>, <filter-value-list> and <shadow>.
// FIXME: we need to also ensure we blend for iterationComposite for <transform-list>, <filter-value-list> and <shadow>.
return WTF::switchOn(fromSyntaxValue, [toSyntaxValue](const Length& fromLength) {
ASSERT(std::holds_alternative<Length>(toSyntaxValue));
return lengthsRequireBlendingForAccumulativeIteration(fromLength, std::get<Length>(toSyntaxValue) );
}, [] (const StyleColor&) {
return true;
}, [] (auto&) {
return false;
});

0 comments on commit f468157

Please sign in to comment.