1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qquickpathinterpolator_p.h" |
5 | |
6 | #include "qquickpath_p.h" |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | \qmltype PathInterpolator |
12 | \instantiates QQuickPathInterpolator |
13 | \inqmlmodule QtQuick |
14 | \ingroup qtquick-animation-control |
15 | \brief Specifies how to manually animate along a path. |
16 | |
17 | PathInterpolator provides \c x, \c y, and \c angle information for a particular \c progress |
18 | along a path. |
19 | |
20 | In the following example, we animate a green rectangle along a bezier path. |
21 | |
22 | \snippet qml/pathinterpolator.qml 0 |
23 | */ |
24 | |
25 | QQuickPathInterpolator::QQuickPathInterpolator(QObject *parent) : |
26 | QObject(parent), _path(nullptr), _x(0), _y(0), _angle(0), _progress(0) |
27 | { |
28 | } |
29 | |
30 | /*! |
31 | \qmlproperty Path QtQuick::PathInterpolator::path |
32 | This property holds the path to interpolate. |
33 | |
34 | For more information on defining a path see the \l Path documentation. |
35 | */ |
36 | QQuickPath *QQuickPathInterpolator::path() const |
37 | { |
38 | return _path; |
39 | } |
40 | |
41 | void QQuickPathInterpolator::setPath(QQuickPath *path) |
42 | { |
43 | if (_path == path) |
44 | return; |
45 | if (_path) |
46 | disconnect(sender: _path, SIGNAL(changed()), receiver: this, SLOT(_q_pathUpdated())); |
47 | _path = path; |
48 | connect(sender: _path, SIGNAL(changed()), receiver: this, SLOT(_q_pathUpdated())); |
49 | emit pathChanged(); |
50 | } |
51 | |
52 | /*! |
53 | \qmlproperty real QtQuick::PathInterpolator::progress |
54 | This property holds the current progress along the path. |
55 | |
56 | Typical usage of PathInterpolator is to set the progress |
57 | (often via a NumberAnimation), and read the corresponding |
58 | values for x, y, and angle (often via bindings to these values). |
59 | |
60 | Progress ranges from 0.0 to 1.0. |
61 | */ |
62 | qreal QQuickPathInterpolator::progress() const |
63 | { |
64 | return _progress; |
65 | } |
66 | |
67 | void QQuickPathInterpolator::setProgress(qreal progress) |
68 | { |
69 | progress = qMin(a: qMax(a: progress, b: (qreal)0.0), b: (qreal)1.0); |
70 | |
71 | if (progress == _progress) |
72 | return; |
73 | _progress = progress; |
74 | emit progressChanged(); |
75 | _q_pathUpdated(); |
76 | } |
77 | |
78 | /*! |
79 | \qmlproperty real QtQuick::PathInterpolator::x |
80 | \qmlproperty real QtQuick::PathInterpolator::y |
81 | |
82 | These properties hold the position of the path at \l progress. |
83 | */ |
84 | qreal QQuickPathInterpolator::x() const |
85 | { |
86 | return _x; |
87 | } |
88 | |
89 | qreal QQuickPathInterpolator::y() const |
90 | { |
91 | return _y; |
92 | } |
93 | |
94 | /*! |
95 | \qmlproperty real QtQuick::PathInterpolator::angle |
96 | |
97 | This property holds the angle of the path tangent at \l progress. |
98 | |
99 | Angles are reported clockwise, with zero degrees at the 3 o'clock position. |
100 | */ |
101 | qreal QQuickPathInterpolator::angle() const |
102 | { |
103 | return _angle; |
104 | } |
105 | |
106 | void QQuickPathInterpolator::_q_pathUpdated() |
107 | { |
108 | if (! _path) |
109 | return; |
110 | |
111 | qreal angle = 0; |
112 | const QPointF pt = _path->sequentialPointAt(p: _progress, angle: &angle); |
113 | |
114 | if (_x != pt.x()) { |
115 | _x = pt.x(); |
116 | emit xChanged(); |
117 | } |
118 | |
119 | if (_y != pt.y()) { |
120 | _y = pt.y(); |
121 | emit yChanged(); |
122 | } |
123 | |
124 | //convert to clockwise |
125 | angle = qreal(360) - angle; |
126 | if (qFuzzyCompare(p1: angle, p2: qreal(360))) |
127 | angle = qreal(0); |
128 | |
129 | if (angle != _angle) { |
130 | _angle = angle; |
131 | emit angleChanged(); |
132 | } |
133 | } |
134 | |
135 | QT_END_NAMESPACE |
136 | |
137 | #include "moc_qquickpathinterpolator_p.cpp" |
138 | |