aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <[email protected]>2025-04-01 14:24:53 +0200
committerEskil Abrahamsen Blomfeldt <[email protected]>2025-04-30 11:21:20 +0200
commit5f3b613b2ea848dfc66c00a6d91d507703a916b3 (patch)
tree45571e52ab9fa42a495dbfd9f77dbcda18f6101a
parentf52428e60023828dc20cce188e1689e3dc67c042 (diff)
Support fill-opacity and stroke-opacity in VectorImage
The alpha value of the fill and stroke colors can be animated separately in SVG. In order to support this, we introduce a specialized ColorOpacityAnimation type in a Helpers library which only overwrites the alpha channel of the target property. This requires an extra hook in the animation frame work which allows us to get the current value of the property. It should have minimal impact on any existing code, but may have additional use cases later, when we implement support for additive color animations for instance. Since the interpolator API in QVariantAnimation is public API, we add a secondary, private API for this. If we see use for it in the future, this could mature to a public API as well. Fixes: QTBUG-135322 Change-Id: I803f4e64c41e9d6dc355f2468233661885aa7f15 Reviewed-by: Eirik Aavitsland <[email protected]>
-rw-r--r--src/quick/util/qquickanimation.cpp20
-rw-r--r--src/quick/util/qquickanimation_p_p.h8
-rw-r--r--src/quickvectorimage/CMakeLists.txt14
-rw-r--r--src/quickvectorimage/generator/qquicknodeinfo_p.h4
-rw-r--r--src/quickvectorimage/generator/qquickqmlgenerator.cpp42
-rw-r--r--src/quickvectorimage/generator/qquickqmlgenerator_p.h9
-rw-r--r--src/quickvectorimage/generator/qsvgvisitorimpl.cpp24
-rw-r--r--src/quickvectorimage/helpers/qquickcoloropacityanimation.cpp103
-rw-r--r--src/quickvectorimage/helpers/qquickcoloropacityanimation_p.h45
-rw-r--r--tests/baseline/scenegraph/data/shared/svg/animateFillStrokeOpacity.svg18
-rw-r--r--tests/baseline/scenegraph/data/vectorimages/opacityAnimation.qml8
11 files changed, 277 insertions, 18 deletions
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index 12af47fb6b..118e893808 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -2709,7 +2709,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v)
for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
- if (v == 1.) {
+ if (v == qreal(1.0) && extendedInterpolator == nullptr) {
QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
} else {
if (!fromIsSourced && !fromIsDefined) {
@@ -2725,8 +2725,21 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v)
interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType);
}
}
- if (interpolator)
- QQmlPropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
+
+ QVariant interpolated;
+ if (extendedInterpolator) {
+ QVariant current = action.property.read();
+ interpolated = extendedInterpolator(action.fromValue.constData(),
+ action.toValue.constData(),
+ current,
+ v);
+
+ } else if (interpolator) {
+ interpolated = interpolator(action.fromValue.constData(), action.toValue.constData(), v);
+ }
+ QQmlPropertyPrivate::write(action.property,
+ interpolated,
+ QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
}
if (deleted)
return;
@@ -2880,6 +2893,7 @@ QAbstractAnimationJob* QQuickPropertyAnimation::transition(QQuickStateActions &a
QQuickAnimationPropertyUpdater *data = new QQuickAnimationPropertyUpdater;
data->interpolatorType = d->interpolatorType;
data->interpolator = d->interpolator;
+ data->extendedInterpolator = d->extendedInterpolator;
data->reverse = direction == Backward ? true : false;
data->fromIsSourced = false;
data->fromIsDefined = d->fromIsDefined;
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index 49f26726ee..84b7066a26 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -240,7 +240,7 @@ class Q_QUICK_EXPORT QQuickPropertyAnimationPrivate : public QQuickAbstractAnima
public:
QQuickPropertyAnimationPrivate()
: QQuickAbstractAnimationPrivate(), target(nullptr), fromIsDefined(false), toIsDefined(false), ourPropertiesDirty(false),
- defaultToInterpolatorType(0), interpolatorType(0), interpolator(nullptr), duration(250), actions(nullptr) {}
+ defaultToInterpolatorType(0), interpolatorType(0), interpolator(nullptr), extendedInterpolator(nullptr), duration(250), actions(nullptr) {}
void animationCurrentLoopChanged(QAbstractAnimationJob *job) override;
@@ -260,13 +260,14 @@ public:
bool defaultToInterpolatorType:1;
int interpolatorType;
QVariantAnimation::Interpolator interpolator;
+ typedef QVariant (*ExtendedInterpolator)(const void *from, const void *to, const QVariant &currentValue, qreal progress);
+ ExtendedInterpolator extendedInterpolator;
int duration;
QEasingCurve easing;
// for animations that don't use the QQuickBulkValueAnimator
QQuickStateActions *actions;
- static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress);
static void convertVariant(QVariant &variant, QMetaType type);
};
@@ -282,7 +283,7 @@ public:
class Q_AUTOTEST_EXPORT QQuickAnimationPropertyUpdater : public QQuickBulkValueUpdater
{
public:
- QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(nullptr), prevInterpolatorType(0), reverse(false), fromIsSourced(false), fromIsDefined(false), wasDeleted(nullptr) {}
+ QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(nullptr), extendedInterpolator(nullptr), prevInterpolatorType(0), reverse(false), fromIsSourced(false), fromIsDefined(false), wasDeleted(nullptr) {}
~QQuickAnimationPropertyUpdater() override;
void setValue(qreal v) override;
@@ -292,6 +293,7 @@ public:
QQuickStateActions actions;
int interpolatorType; //for Number/ColorAnimation
QVariantAnimation::Interpolator interpolator;
+ QQuickPropertyAnimationPrivate::ExtendedInterpolator extendedInterpolator;
int prevInterpolatorType; //for generic
bool reverse;
bool fromIsSourced;
diff --git a/src/quickvectorimage/CMakeLists.txt b/src/quickvectorimage/CMakeLists.txt
index 8f3c5c7620..868dd646ed 100644
--- a/src/quickvectorimage/CMakeLists.txt
+++ b/src/quickvectorimage/CMakeLists.txt
@@ -28,6 +28,7 @@ qt_internal_add_qml_module(QuickVectorImage
VERSION "${PROJECT_VERSION}"
PLUGIN_TARGET qquickvectorimageplugin
CLASS_NAME QtQuickVectorImagePlugin
+ IMPORTS QtQuick.VectorImage.Helpers
SOURCES
qquickvectorimage_p.h qquickvectorimage.cpp
qquickvectorimage_p_p.h
@@ -36,3 +37,16 @@ qt_internal_add_qml_module(QuickVectorImage
Qt::QuickVectorImageGeneratorPrivate
Qt::SvgPrivate
)
+
+qt_internal_add_qml_module(QuickVectorImageHelpers
+ URI "QtQuick.VectorImage.Helpers"
+ VERSION "${PROJECT_VERSION}"
+ PLUGIN_TARGET qquickvectorimagehelpersplugin
+ NO_PLUGIN_OPTIONAL
+ CLASS_NAME QtQuickVectorImageHelpersPlugin
+ SOURCES
+ helpers/qquickcoloropacityanimation_p.h helpers/qquickcoloropacityanimation.cpp
+ LIBRARIES
+ Qt::QuickPrivate
+ Qt::QuickVectorImageGeneratorPrivate
+)
diff --git a/src/quickvectorimage/generator/qquicknodeinfo_p.h b/src/quickvectorimage/generator/qquicknodeinfo_p.h
index 95dbdc9fef..44226d6a78 100644
--- a/src/quickvectorimage/generator/qquicknodeinfo_p.h
+++ b/src/quickvectorimage/generator/qquicknodeinfo_p.h
@@ -53,6 +53,7 @@ struct StrokeStyle
qreal dashOffset = 0;
QList<qreal> dashArray;
QQuickAnimatedProperty color = QQuickAnimatedProperty(QVariant::fromValue(QColorConstants::Transparent));
+ QQuickAnimatedProperty opacity = QQuickAnimatedProperty(QVariant::fromValue(qreal(1.0)));
qreal width = 1.0;
static StrokeStyle fromPen(const QPen &p)
@@ -74,6 +75,7 @@ struct PathNodeInfo : NodeInfo
QPainterPath painterPath;
Qt::FillRule fillRule = Qt::FillRule::WindingFill;
QQuickAnimatedProperty fillColor = QQuickAnimatedProperty(QVariant::fromValue(QColor{}));
+ QQuickAnimatedProperty fillOpacity = QQuickAnimatedProperty(QVariant::fromValue(qreal(1.0)));
StrokeStyle strokeStyle;
QGradient grad;
QTransform fillTransform;
@@ -89,7 +91,9 @@ struct TextNodeInfo : NodeInfo
QFont font;
Qt::Alignment alignment;
QQuickAnimatedProperty fillColor = QQuickAnimatedProperty(QVariant::fromValue(QColor{}));
+ QQuickAnimatedProperty fillOpacity = QQuickAnimatedProperty(QVariant::fromValue(qreal(1.0)));
QQuickAnimatedProperty strokeColor = QQuickAnimatedProperty(QVariant::fromValue(QColor{}));
+ QQuickAnimatedProperty strokeOpacity = QQuickAnimatedProperty(QVariant::fromValue(qreal(1.0)));
};
struct AnimateColorNodeInfo : NodeInfo
diff --git a/src/quickvectorimage/generator/qquickqmlgenerator.cpp b/src/quickvectorimage/generator/qquickqmlgenerator.cpp
index ae77b178f3..72b6b51035 100644
--- a/src/quickvectorimage/generator/qquickqmlgenerator.cpp
+++ b/src/quickvectorimage/generator/qquickqmlgenerator.cpp
@@ -260,7 +260,8 @@ void QQuickQmlGenerator::generateGradient(const QGradient *grad)
void QQuickQmlGenerator::generatePropertyAnimation(const QQuickAnimatedProperty &property,
const QString &targetName,
- const QString &propertyName)
+ const QString &propertyName,
+ AnimationType animationType)
{
if (property.animationCount() > 1) {
stream() << "ParallelAnimation {";
@@ -295,10 +296,17 @@ void QQuickQmlGenerator::generatePropertyAnimation(const QQuickAnimatedProperty
const int time = it.key();
const QVariant &value = it.value();
- if (value.typeId() == QMetaType::QColor)
- stream() << "ColorAnimation {";
- else
- stream() << "PropertyAnimation {";
+ switch (animationType) {
+ case AnimationType::Auto:
+ if (value.typeId() == QMetaType::QColor)
+ stream() << "ColorAnimation {";
+ else
+ stream() << "PropertyAnimation {";
+ break;
+ case AnimationType::ColorOpacity:
+ stream() << "ColorOpacityAnimation {";
+ break;
+ };
m_indentLevel++;
stream() << "target: " << targetName;
@@ -318,13 +326,23 @@ void QQuickQmlGenerator::generatePropertyAnimation(const QQuickAnimatedProperty
if (!(animation.flags & QQuickAnimatedProperty::PropertyAnimation::FreezeAtEnd)) {
stream() << "ScriptAction {";
m_indentLevel++;
- stream() << "script: " << targetName << "." << propertyName << " = ";
+ stream() << "script: ";
+
+ switch (animationType) {
+ case AnimationType::Auto:
+ stream(SameLine) << targetName << "." << propertyName << " = ";
+ break;
+ case AnimationType::ColorOpacity:
+ stream(SameLine) << targetName << "." << propertyName << ".a = ";
+ break;
+ };
QVariant value = property.defaultValue();
if (value.typeId() == QMetaType::QColor)
stream(SameLine) << "\"" << value.toString() << "\"";
else
stream(SameLine) << value.toReal();
+
m_indentLevel--;
stream() << "}";
}
@@ -372,14 +390,17 @@ void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainte
static int counter = 0;
const QColor strokeColor = info.strokeStyle.color.defaultValue().value<QColor>();
- const bool noPen = strokeColor == QColorConstants::Transparent && !info.strokeStyle.color.isAnimated();
+ const bool noPen = strokeColor == QColorConstants::Transparent
+ && !info.strokeStyle.color.isAnimated()
+ && !info.strokeStyle.opacity.isAnimated();
if (pathSelector == QQuickVectorImageGenerator::StrokePath && noPen)
return;
const QColor fillColor = info.fillColor.defaultValue().value<QColor>();
const bool noFill = info.grad.type() == QGradient::NoGradient
&& fillColor == QColorConstants::Transparent
- && !info.fillColor.isAnimated();
+ && !info.fillColor.isAnimated()
+ && !info.fillOpacity.isAnimated();
if (pathSelector == QQuickVectorImageGenerator::FillPath && noFill)
return;
@@ -464,7 +485,9 @@ void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainte
stream() << "}";
generatePropertyAnimation(info.strokeStyle.color, shapePathId, QStringLiteral("strokeColor"));
+ generatePropertyAnimation(info.strokeStyle.opacity, shapePathId, QStringLiteral("strokeColor"), AnimationType::ColorOpacity);
generatePropertyAnimation(info.fillColor, shapePathId, QStringLiteral("fillColor"));
+ generatePropertyAnimation(info.fillOpacity, shapePathId, QStringLiteral("fillColor"), AnimationType::ColorOpacity);
counter++;
}
@@ -504,7 +527,9 @@ void QQuickQmlGenerator::generateTextNode(const TextNodeInfo &info)
stream() << "id: " << textItemId;
generatePropertyAnimation(info.fillColor, textItemId, QStringLiteral("color"));
+ generatePropertyAnimation(info.fillOpacity, textItemId, QStringLiteral("color"), AnimationType::ColorOpacity);
generatePropertyAnimation(info.strokeColor, textItemId, QStringLiteral("styleColor"));
+ generatePropertyAnimation(info.strokeOpacity, textItemId, QStringLiteral("styleColor"), AnimationType::ColorOpacity);
if (info.isTextArea) {
stream() << "x: " << info.position.x();
@@ -886,6 +911,7 @@ bool QQuickQmlGenerator::generateRootNode(const StructureNodeInfo &info)
stream() << "// " << comment;
stream() << "import QtQuick";
+ stream() << "import QtQuick.VectorImage.Helpers";
stream() << "import QtQuick.Shapes" << Qt::endl;
stream() << "Item {";
m_indentLevel++;
diff --git a/src/quickvectorimage/generator/qquickqmlgenerator_p.h b/src/quickvectorimage/generator/qquickqmlgenerator_p.h
index 334e4cfb31..d65bd4ccc5 100644
--- a/src/quickvectorimage/generator/qquickqmlgenerator_p.h
+++ b/src/quickvectorimage/generator/qquickqmlgenerator_p.h
@@ -96,9 +96,16 @@ private:
void generateTransform(const QTransform &xf);
void generatePathContainer(const StructureNodeInfo &info);
void generateAnimateTransform(const QString &targetName, const NodeInfo &info);
+
+ enum class AnimationType {
+ Auto = 0,
+ ColorOpacity = 1
+ };
+
void generatePropertyAnimation(const QQuickAnimatedProperty &property,
const QString &targetName,
- const QString &propertyName);
+ const QString &propertyName,
+ AnimationType animationType = AnimationType::Auto);
QStringView indent();
enum StreamFlags { NoFlags = 0x0, SameLine = 0x1 };
diff --git a/src/quickvectorimage/generator/qsvgvisitorimpl.cpp b/src/quickvectorimage/generator/qsvgvisitorimpl.cpp
index f9e9c70de3..5bdbdeae4f 100644
--- a/src/quickvectorimage/generator/qsvgvisitorimpl.cpp
+++ b/src/quickvectorimage/generator/qsvgvisitorimpl.cpp
@@ -940,11 +940,23 @@ void QSvgVisitorImpl::visitTextNode(const QSvgText *node)
}
{
+ QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("fill-opacity"));
+ if (!animations.isEmpty())
+ applyAnimationsToProperty(animations, &info.fillOpacity, calculateInterpolatedValue);
+ }
+
+ {
QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("stroke"));
if (!animations.isEmpty())
applyAnimationsToProperty(animations, &info.strokeColor, calculateInterpolatedValue);
}
+ {
+ QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("stroke-opacity"));
+ if (!animations.isEmpty())
+ applyAnimationsToProperty(animations, &info.strokeOpacity, calculateInterpolatedValue);
+ }
+
info.position = node->position();
info.size = node->size();
info.font = font;
@@ -1215,10 +1227,22 @@ void QSvgVisitorImpl::fillColorAnimationInfo(const QSvgNode *node, PathNodeInfo
}
{
+ QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("fill-opacity"));
+ if (!animations.isEmpty())
+ applyAnimationsToProperty(animations, &info.fillOpacity, calculateInterpolatedValue);
+ }
+
+ {
QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("stroke"));
if (!animations.isEmpty())
applyAnimationsToProperty(animations, &info.strokeStyle.color, calculateInterpolatedValue);
}
+
+ {
+ QList<AnimationPair> animations = collectAnimations(node, QStringLiteral("stroke-opacity"));
+ if (!animations.isEmpty())
+ applyAnimationsToProperty(animations, &info.strokeStyle.opacity, calculateInterpolatedValue);
+ }
}
void QSvgVisitorImpl::fillTransformAnimationInfo(const QSvgNode *node, NodeInfo &info)
diff --git a/src/quickvectorimage/helpers/qquickcoloropacityanimation.cpp b/src/quickvectorimage/helpers/qquickcoloropacityanimation.cpp
new file mode 100644
index 0000000000..7aa7f8ef6f
--- /dev/null
+++ b/src/quickvectorimage/helpers/qquickcoloropacityanimation.cpp
@@ -0,0 +1,103 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickcoloropacityanimation_p.h"
+
+#include <QtQuick/private/qquickanimation_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlmodule QtQuick.VectorImage.Helpers
+ \title Qt Quick Vector Image Helpers QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types used by VectorImage and related tools.
+ \since 6.10
+
+ This module contains types used in scenes generated by \l{VectorImage}, \l{svgtoqml} and related
+ tools. The types are made to replicate specialized behavior defined by the vector graphics file
+ formats it loads and are not intended to be generally useful.
+
+ To use the types in this module, import the module with the following line:
+
+ \qml
+ import QtQuick.VectorImage.Helpers
+ \endqml
+
+ \section1 QML Types
+*/
+
+static QVariant opacityInterpolator(const QColor &from,
+ const QColor &to,
+ const QVariant &current,
+ qreal progress)
+{
+ QColor color = current.value<QColor>();
+
+ qreal fromAlpha = from.alphaF();
+ qreal toAlpha = to.alphaF();
+
+ color.setAlphaF(fromAlpha + (toAlpha - fromAlpha) * progress);
+ return QVariant::fromValue(color);
+}
+
+/*!
+ \qmltype ColorOpacityAnimation
+ \inqmlmodule QtQuick.VectorImage.Helpers
+ \inherits Item
+ \brief Animates the alpha value of a color without modifying the rest of the color.
+
+ This type will animate the alpha value of a color without modifying the other components. It
+ is used to support the \c fill-opacity and \c stroke-opacity properties of SVG, which can be
+ animated separately from the opacity of the shape itself.
+*/
+QQuickColorOpacityAnimation::QQuickColorOpacityAnimation(QObject *parent)
+ : QQuickPropertyAnimation(parent)
+{
+ Q_D(QQuickPropertyAnimation);
+ d->defaultToInterpolatorType = true;
+ d->interpolatorType = QMetaType::QColor;
+ d->extendedInterpolator = reinterpret_cast<QQuickPropertyAnimationPrivate::ExtendedInterpolator>(reinterpret_cast<void(*)()>(opacityInterpolator));
+}
+
+/*!
+ \qmlproperty real QtQuick.VectorImage.Helpers::ColorOpacityAnimation::from
+
+ The value of the color's alpha channel at the start of the animation.
+*/
+qreal QQuickColorOpacityAnimation::from() const
+{
+ Q_D(const QQuickPropertyAnimation);
+ return d->from.value<QColor>().alphaF();
+}
+
+void QQuickColorOpacityAnimation::setFrom(qreal from)
+{
+ QColor color = Qt::red;
+ color.setAlphaF(from);
+
+ QQuickPropertyAnimation::setFrom(color);
+}
+
+/*!
+ \qmlproperty real QtQuick.VectorImage.Helpers::ColorOpacityAnimation::to
+
+ The value of the color's alpha channel at the end of the animation.
+*/
+qreal QQuickColorOpacityAnimation::to() const
+{
+ Q_D(const QQuickPropertyAnimation);
+ return d->to.value<QColor>().alphaF();
+}
+
+void QQuickColorOpacityAnimation::setTo(qreal to)
+{
+ QColor color = Qt::yellow;
+ color.setAlphaF(to);
+
+ QQuickPropertyAnimation::setTo(color);
+}
+
+QT_END_NAMESPACE
+
+#include <moc_qquickcoloropacityanimation_p.cpp>
diff --git a/src/quickvectorimage/helpers/qquickcoloropacityanimation_p.h b/src/quickvectorimage/helpers/qquickcoloropacityanimation_p.h
new file mode 100644
index 0000000000..11f2b53c4d
--- /dev/null
+++ b/src/quickvectorimage/helpers/qquickcoloropacityanimation_p.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKOPACITYANIMATION_P_H
+#define QQUICKOPACITYANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuick/private/qquickanimation_p.h>
+#include <QtQuickVectorImageHelpers/qtquickvectorimagehelpersexports.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICKVECTORIMAGEHELPERS_EXPORT QQuickColorOpacityAnimation : public QQuickPropertyAnimation
+{
+ Q_OBJECT
+
+ Q_DECLARE_PRIVATE(QQuickPropertyAnimation)
+ Q_PROPERTY(qreal from READ from WRITE setFrom)
+ Q_PROPERTY(qreal to READ to WRITE setTo)
+ QML_NAMED_ELEMENT(ColorOpacityAnimation)
+
+public:
+ QQuickColorOpacityAnimation(QObject *parent = nullptr);
+
+ qreal from() const;
+ void setFrom(qreal from);
+
+ qreal to() const;
+ void setTo(qreal to);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKOPACITYANIMATION_P_H
+
diff --git a/tests/baseline/scenegraph/data/shared/svg/animateFillStrokeOpacity.svg b/tests/baseline/scenegraph/data/shared/svg/animateFillStrokeOpacity.svg
new file mode 100644
index 0000000000..0612f6d7df
--- /dev/null
+++ b/tests/baseline/scenegraph/data/shared/svg/animateFillStrokeOpacity.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+ <style>
+ @keyframes opacity {
+ 0% {fill-opacity: 0; stroke-opacity: 0; }
+ 1% {fill-opacity: 0.75; stroke-opacity: 0.5; }
+ 100% {fill-opacity: 0.75; stroke-opacity: 0.5; }
+ }
+
+ rect {
+ animation-duration: 50s;
+ animation-name: opacity;
+ animation-iteration-count: 1;
+ }
+
+ </style>
+ <rect width="100" height="100" fill="green" stroke="red" stroke-width="6"/>
+
+</svg>
diff --git a/tests/baseline/scenegraph/data/vectorimages/opacityAnimation.qml b/tests/baseline/scenegraph/data/vectorimages/opacityAnimation.qml
index 4a4af0ffe4..b46cba920e 100644
--- a/tests/baseline/scenegraph/data/vectorimages/opacityAnimation.qml
+++ b/tests/baseline/scenegraph/data/vectorimages/opacityAnimation.qml
@@ -4,18 +4,20 @@ import QtQuick.VectorImage
Rectangle {
id: topLevelItem
width: 200
- height: 100
+ height: 200
ListModel {
id: renderers
ListElement { renderer: VectorImage.GeometryRenderer; src: "../shared/svg/animateOpacity.svg" }
ListElement { renderer: VectorImage.CurveRenderer; src: "../shared/svg/animateOpacity.svg" }
+ ListElement { renderer: VectorImage.GeometryRenderer; src: "../shared/svg/animateFillStrokeOpacity.svg" }
+ ListElement { renderer: VectorImage.CurveRenderer; src: "../shared/svg/animateFillStrokeOpacity.svg" }
}
- Row {
+ Grid {
+ columns: 2
Repeater {
model: renderers
-
VectorImage {
layer.enabled: true
layer.samples: 4