1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtCore/QPointF>
5#include "QSplineSeries"
6#include "private/qsplinecontrolanimation_p.h"
7#include "private/qsplineseries_p.h"
8
9/*!
10 \qmltype SplineControlAnimation
11 \inqmlmodule QtGraphs
12 \ingroup graphs_qml_2D
13 \brief An animation type which signifies the animation for spline control points.
14
15SplineControlAnimation is an animation type derived from QVariantAnimation which defines how spline control points
16are animated. It can make use of QVariantAnimation functionality and properties for its animations, such as \c duration
17and \c easing. These animations are housed inside a QParallelAnimationGroup and hence will run in parallel.
18This animation will not affect the main points of the SplineSeries, but only the two control handles
19on either side of the point. Each of the control points are linearly interpolated in succession.
20
21This example shows how to use both a SplineControlPointAnimation and a
22GraphPointAnimation to define animations for both the main series of points and the
23control points of a SplineSeries:
24
25\snippet doc_src_qmlgraphs.cpp 13
26
27\sa GraphTransition, GraphPointAnimation
28
29*/
30QSplineControlAnimation::QSplineControlAnimation(QObject *parent)
31 : QXYSeriesAnimation(parent)
32{
33 setDuration(800);
34 setEasingCurve(QEasingCurve::OutCubic);
35}
36
37QSplineControlAnimation::~QSplineControlAnimation() {}
38
39QGraphAnimation::GraphAnimationType QSplineControlAnimation::animationType()
40{
41 return QGraphAnimation::GraphAnimationType::ControlPoint;
42}
43
44void QSplineControlAnimation::setAnimatingValue(const QVariant &start, const QVariant &end)
45{
46 setStartValue(start);
47 setEndValue(end);
48}
49
50QVariant QSplineControlAnimation::interpolated(const QVariant &start,
51 const QVariant &end,
52 qreal progress) const
53{
54 auto startList = qvariant_cast<QList<QPointF>>(v: start);
55 auto endList = qvariant_cast<QList<QPointF>>(v: end);
56 auto interpolateList = QList<QPointF>();
57
58 for (int i = 0; i < qMin(a: startList.size(), b: endList.size()); ++i) {
59 interpolateList.push_back(
60 t: {qreal(startList[i].x() * (1.0 - progress) + endList[i].x() * progress),
61 qreal(startList[i].y() * (1.0 - progress) + endList[i].y() * progress)});
62 }
63
64 return QVariant::fromValue(value: interpolateList);
65}
66
67void QSplineControlAnimation::animate()
68{
69 // Hierarchy should look like GraphAnimation -> ParallelAnimationGroup -> GraphTransition -> SplineSeries
70 auto series = qobject_cast<QSplineSeries *>(object: parent()->parent()->parent());
71
72 if (!series || series->points().size() < 1)
73 return;
74
75 auto pointList = series->points();
76 auto &cPoints = series->d_func()->m_controlPoints;
77
78 if (animating() == QGraphAnimation::AnimationState::Playing)
79 end();
80
81 setAnimating(QGraphAnimation::AnimationState::Playing);
82
83 auto oldPoints = cPoints;
84
85 series->d_func()->calculateSplinePoints();
86
87 while (oldPoints.size() < cPoints.size()) {
88 // Each point corresponds to a 2n - 1 control point pair other than the first
89 // (Except when there are only 2 points)
90 // 0 ---- 0
91 // 1 ---- 1
92 // ---- 2
93 // 2 ---- 3
94 // ---- 4 ...
95 QPointF point = pointList[oldPoints.size() / 2];
96 oldPoints.append(t: point);
97 }
98
99 auto varStart = QVariant::fromValue(value: oldPoints);
100 auto varEnd = QVariant::fromValue(value: cPoints);
101
102 setAnimatingValue(start: varStart, end: varEnd);
103}
104
105void QSplineControlAnimation::end()
106{
107 auto series = qobject_cast<QSplineSeries *>(object: parent()->parent()->parent());
108
109 if (!series || animating() == QGraphAnimation::AnimationState::Stopped)
110 return;
111
112 setAnimating(QGraphAnimation::AnimationState::Stopped);
113 stop();
114
115 series->d_func()->calculateSplinePoints();
116
117 emit series->update();
118}
119
120void QSplineControlAnimation::valueUpdated(const QVariant &value)
121{
122 auto series = qobject_cast<QSplineSeries *>(object: parent()->parent()->parent());
123
124 if (!series)
125 return;
126
127 auto &cPoints = series->d_func()->m_controlPoints;
128 auto points = qvariant_cast<QList<QPointF>>(v: value);
129
130 for (int i = 0; i < qMin(a: points.size(), b: cPoints.size()); ++i)
131 cPoints.replace(i, t: points[i]);
132
133 emit series->update();
134}
135

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtgraphs/src/graphs2d/animation/qsplinecontrolanimation.cpp