diff options
| author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2025-12-18 09:32:04 +0100 |
|---|---|---|
| committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2025-12-22 14:40:12 +0100 |
| commit | 04466da863f51a852cbb19814c05016018d7ca54 (patch) | |
| tree | 27c7dab5ed5dae76eb88efb7049c844f01ed3381 /src | |
| parent | bb7391d241e186cb33b71c0cfdfb438cd5f7edf9 (diff) | |
qml generator: Reduce redundancy in animation output
Whenever three consecutive keyframes have the same value, the middle
one is redundant. Simplify the produced QML code by removing such
keyframes. The practical result is that consecutive PauseAnimations
get squashed into one.
For animated (morphing) paths, simplify further by detecting if two
consecutive paths are identical. Then the second is redundant, so drop
it and instead make the PathInterpolated factor point at the first one
for the keyframe(s) for the second.
Pick-to: 6.11
Change-Id: I7a77c73c6fd98f574fcf26f4dad45ca92a0def0b
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/quickvectorimage/generator/qquickanimatedproperty_p.h | 7 | ||||
| -rw-r--r-- | src/quickvectorimage/generator/qquickqmlgenerator.cpp | 41 |
2 files changed, 40 insertions, 8 deletions
diff --git a/src/quickvectorimage/generator/qquickanimatedproperty_p.h b/src/quickvectorimage/generator/qquickanimatedproperty_p.h index 43e6f0abae..91fb1af38e 100644 --- a/src/quickvectorimage/generator/qquickanimatedproperty_p.h +++ b/src/quickvectorimage/generator/qquickanimatedproperty_p.h @@ -18,10 +18,11 @@ #include <QMap> #include <QVariant> #include <QtGui/private/qbezier_p.h> +#include "qquickgenerator_p.h" QT_BEGIN_NAMESPACE -class QQuickAnimatedProperty +class Q_QUICKVECTORIMAGEGENERATOR_EXPORT QQuickAnimatedProperty { public: struct PropertyAnimation { @@ -48,6 +49,8 @@ public: } return true; } + + PropertyAnimation simplified() const; }; QQuickAnimatedProperty(const QVariant &defaultValue) @@ -85,7 +88,7 @@ public: if (m_animationGroups.isEmpty()) beginAnimationGroup(); - m_animations.append(animation); + m_animations.append(animation.simplified()); } qsizetype animationGroupCount() const diff --git a/src/quickvectorimage/generator/qquickqmlgenerator.cpp b/src/quickvectorimage/generator/qquickqmlgenerator.cpp index 319d8be36c..21c423eaf7 100644 --- a/src/quickvectorimage/generator/qquickqmlgenerator.cpp +++ b/src/quickvectorimage/generator/qquickqmlgenerator.cpp @@ -26,6 +26,30 @@ static QString sanitizeString(const QString &input) return s; } + +QQuickAnimatedProperty::PropertyAnimation QQuickAnimatedProperty::PropertyAnimation::simplified() const +{ + QQuickAnimatedProperty::PropertyAnimation res = *this; + int consecutiveEquals = 0; + int prevTimePoint = -1; + QVariant prevValue; + for (const auto &[timePoint, value] : frames.asKeyValueRange()) { + if (value != prevValue) { + consecutiveEquals = 1; + prevValue = value; + } else if (consecutiveEquals < 2) { + consecutiveEquals++; + } else { + // Third consecutive equal value found, remove the redundant middle one + res.frames.remove(prevTimePoint); + res.easingPerFrame.remove(prevTimePoint); + } + prevTimePoint = timePoint; + } + + return res; +} + QQuickQmlGenerator::QQuickQmlGenerator(const QString fileName, QQuickVectorImageGenerator::GeneratorFlags flags, const QString &outFileName) : QQuickGenerator(fileName, flags) , outputFileName(outFileName) @@ -859,7 +883,7 @@ void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainte QQuickAnimatedProperty pathFactor(QVariant::fromValue(0)); QString pathId = shapePathId + "_ip"_L1; - if (!info.path.isAnimated()) { + if (!info.path.isAnimated() || (info.path.animation(0).startOffset == 0 && info.path.animation(0).isConstant())) { QString svgPathString = painterPath ? QQuickVectorImageGenerator::Utils::toSvgString(*painterPath) : QQuickVectorImageGenerator::Utils::toSvgString(*quadPath); stream() << "PathSvg { path: \"" << svgPathString << "\" }"; } else { @@ -870,13 +894,18 @@ void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainte m_indentLevel++; QQuickAnimatedProperty::PropertyAnimation pathFactorAnim = info.path.animation(0); auto &frames = pathFactorAnim.frames; - int pathIdx = 0; + int pathIdx = -1; + QString lastSvg; for (auto it = frames.begin(); it != frames.end(); ++it) { QString svg = QQuickVectorImageGenerator::Utils::toSvgString(it->value<QPainterPath>()); - stream() << "\"" << svg << "\""; - if (pathIdx < frames.size() - 1) - stream(SameLine) << ","; - *it = QVariant::fromValue(pathIdx++); + if (svg != lastSvg) { + if (pathIdx >= 0) + stream(SameLine) << ","; + stream() << "\"" << svg << "\""; + ++pathIdx; + lastSvg = svg; + } + *it = QVariant::fromValue(pathIdx); } pathFactor.addAnimation(pathFactorAnim); m_indentLevel--; |
