forked from qt-creator/qt-creator
Use QEasing instead of Bezier to paint the curve segments
This way "failure state" is reflected in the appearance of the curve item Change-Id: I997f86f1a6072eaf65c77f2df0afd53a80dc0d0e Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
7675296fcf
commit
d72e18da2d
@@ -224,6 +224,23 @@ QPainterPath CurveSegment::path() const
|
||||
return path;
|
||||
}
|
||||
|
||||
void CurveSegment::extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const
|
||||
{
|
||||
auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) {
|
||||
QPointF slope(end.x() - start.x(), end.y() - start.y());
|
||||
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
|
||||
};
|
||||
|
||||
QVector<QPointF> points = curve.toCubicSpline();
|
||||
int numSegments = points.count() / 3;
|
||||
for (int i = 0; i < numSegments; i++) {
|
||||
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));
|
||||
QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1));
|
||||
QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2));
|
||||
path.cubicTo(p1, p2, p3);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveSegment::extend(QPainterPath &path) const
|
||||
{
|
||||
if (interpolation() == Keyframe::Interpolation::Linear) {
|
||||
@@ -232,23 +249,11 @@ void CurveSegment::extend(QPainterPath &path) const
|
||||
path.lineTo(QPointF(m_right.position().x(), m_left.position().y()));
|
||||
path.lineTo(m_right.position());
|
||||
} else if (interpolation() == Keyframe::Interpolation::Bezier) {
|
||||
path.cubicTo(m_left.rightHandle(), m_right.leftHandle(), m_right.position());
|
||||
extendWithEasingCurve(path, easingCurve());
|
||||
} else if (interpolation() == Keyframe::Interpolation::Easing) {
|
||||
auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) {
|
||||
QPointF slope(end.x() - start.x(), end.y() - start.y());
|
||||
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
|
||||
};
|
||||
|
||||
QVariant data = m_right.data();
|
||||
if (data.isValid() && data.type() == static_cast<int>(QMetaType::QEasingCurve)) {
|
||||
QVector<QPointF> points = data.value<QEasingCurve>().toCubicSpline();
|
||||
int numSegments = points.count() / 3;
|
||||
for (int i = 0; i < numSegments; i++) {
|
||||
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));
|
||||
QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1));
|
||||
QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2));
|
||||
path.cubicTo(p1, p2, p3);
|
||||
}
|
||||
extendWithEasingCurve(path, data.value<QEasingCurve>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ public:
|
||||
|
||||
void extend(QPainterPath &path) const;
|
||||
|
||||
void extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const;
|
||||
|
||||
QEasingCurve easingCurve() const;
|
||||
|
||||
std::vector<QPointF> extrema() const;
|
||||
|
||||
@@ -206,6 +206,13 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(
|
||||
QEasingCurve curve = frame.data().toEasingCurve();
|
||||
if (curve.toCubicSpline().count() == 3) {
|
||||
DesignTools::Keyframe &previous = out.back();
|
||||
#if 0
|
||||
// Do not resolve when two adjacent keyframes have the same value.
|
||||
if (qFuzzyCompare(previous.position().y(), frame.position().y())) {
|
||||
out.push_back(frame);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position());
|
||||
previous.setRightHandle(acurve.keyframeAt(0).rightHandle());
|
||||
out.push_back(acurve.keyframeAt(1));
|
||||
|
||||
Reference in New Issue
Block a user