diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-09-08 04:16:04 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-09-08 04:16:04 (GMT) |
commit | fb4eb36e78a9d9337fd3decf70a6c13774ba551a (patch) | |
tree | c708b5fb420bf27461122cf8b326b952eb379efd /src/declarative/util | |
parent | ef35caa4f08d10f214d4068328072e432882827e (diff) | |
download | Qt-fb4eb36e78a9d9337fd3decf70a6c13774ba551a.zip Qt-fb4eb36e78a9d9337fd3decf70a6c13774ba551a.tar.gz Qt-fb4eb36e78a9d9337fd3decf70a6c13774ba551a.tar.bz2 |
SpringAnimation velocity animation stop logic was fragile.
Rather than stopping the animation when the target was reached, calculate
the duration it will take. This eliminates the possibility of rounding
errors causing the animation to stop at the wrong time.
Task-number: QTBUG-13044
Reviewed-by: Aaron Kennedy
Diffstat (limited to 'src/declarative/util')
-rw-r--r-- | src/declarative/util/qdeclarativespringanimation.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp index fce4097..e0fc45d 100644 --- a/src/declarative/util/qdeclarativespringanimation.cpp +++ b/src/declarative/util/qdeclarativespringanimation.cpp @@ -62,10 +62,12 @@ public: struct SpringAnimation { SpringAnimation() - : currentValue(0), to(0), velocity(0){} + : currentValue(0), to(0), velocity(0), start(0), duration(0) {} qreal currentValue; qreal to; qreal velocity; + int start; + int duration; }; QHash<QDeclarativeProperty, SpringAnimation> activeAnimations; @@ -135,7 +137,6 @@ void QDeclarativeSpringAnimationPrivate::tick(int time) bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &property, SpringAnimation &animation, int elapsed) { - qreal srcVal = animation.to; bool stop = false; @@ -192,18 +193,14 @@ bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &pro animation.currentValue += moveBy; if (haveModulus) animation.currentValue = fmod(animation.currentValue, modulus); - if (animation.currentValue > animation.to) { - animation.currentValue = animation.to; - stop = true; - } } else { animation.currentValue -= moveBy; if (haveModulus && animation.currentValue < 0.0) animation.currentValue = fmod(animation.currentValue, modulus) + modulus; - if (animation.currentValue < animation.to) { - animation.currentValue = animation.to; - stop = true; - } + } + if (lastTime - animation.start >= animation.duration) { + animation.currentValue = animation.to; + stop = true; } } @@ -222,8 +219,18 @@ void QDeclarativeSpringAnimationPrivate::updateMode() mode = Track; else if (spring > 0.) mode = Spring; - else + else { mode = Velocity; + QHash<QDeclarativeProperty, SpringAnimation>::iterator it; + for (it = activeAnimations.begin(); it != activeAnimations.end(); ++it) { + SpringAnimation &animation = *it; + animation.start = lastTime; + qreal dist = qAbs(animation.currentValue - animation.to); + if (haveModulus && dist > modulus / 2) + dist = modulus - fmod(dist, modulus); + animation.duration = dist / velocityms; + } + } } /*! @@ -378,6 +385,7 @@ void QDeclarativeSpringAnimation::setModulus(qreal modulus) if (d->modulus != modulus) { d->haveModulus = modulus != 0.0; d->modulus = modulus; + d->updateMode(); emit modulusChanged(); } } @@ -429,10 +437,17 @@ void QDeclarativeSpringAnimation::transition(QDeclarativeStateActions &actions, QDeclarativeSpringAnimationPrivate::SpringAnimation &animation = d->activeAnimations[property]; animation.to = d->actions->at(i).toValue.toReal(); + animation.start = d->lastTime; if (d->fromIsDefined) animation.currentValue = d->actions->at(i).fromValue.toReal(); else animation.currentValue = property.read().toReal(); + if (d->mode == QDeclarativeSpringAnimationPrivate::Velocity) { + qreal dist = qAbs(animation.currentValue - animation.to); + if (d->haveModulus && dist > d->modulus / 2) + dist = d->modulus - fmod(dist, d->modulus); + animation.duration = dist / d->velocityms; + } } } } |