[Interest] To a truly smooth progress bar (QML)
Jason H
jhihn at gmx.com
Wed Apr 13 16:09:51 CEST 2016
I am trying to come up with a very smooth yet accurate progress bar. My code for the 1 second update interval use case is down below.
The use case of this bar is that there is a regular interval that the value is updated, either from a timer, or a consistent CPU-bound process. Another example would be a seek bar from the video player which updates it's position every second. To this end, I try to control the size change through velocity. The SmoothedAnimation though uses a InOutQuad, and not Linear for eading. Changing it to Linear helps, but I've never been able to get it to smoothly continue past an update boundary. I've tried various smoothing techniques (like Exponential moving average) to try to smooth this out, but It's never perfect, and im post cases makes it worse. Can I get it to be perfect? I don't care so much that the bar is absolutely numerically accurate, it can be a few pixels off, but it shouldn't be wildly inaccurate.
Thanks.
import QtQuick 2.0
Rectangle {
property real percent: 0
property color barColor: "white"
property real lastUpdateTime: -1
property real lastUpdateValue: 0
property alias smooth: smoothBehavior.enabled
property alias velocity: numAnim.velocity
color:"transparent"
onPercentChanged:
{
smoothBehavior.enabled = lastUpdateValue < percent
if (!smoothBehavior.enabled)
numAnim.complete()
}
Rectangle {
color: barColor
height: parent.height
width: parent.width * percent
antialiasing: true
}
Behavior on percent {
id: smoothBehavior
onEnabledChanged: console.debug("smoothBehavior", enabled)
SmoothedAnimation {
id: numAnim
easing.type: Easing.Linear
duration:1050 //average of just less than 1 update per second, ~1060ms.
reversingMode: SmoothedAnimation.Sync
}
}
}
== the code for updating the velocity dynamically ==
ProgressBar {
property real lastUpdateTime: -1
property real lastUpdateValue: 0
onPercentChanged: {
var now = new Date().getTime()/1000;
if (lastUpdateTime != -1) {
var dt = now - lastUpdateTime;
var dv = percent - lastUpdateValue ;
var v = dv / dt ;
console.log(percent, "velocity (pps):", v*width, "d%:", dv, "dt:", dt, "w:", width, "%/s:", v)
if (v > 0) {
velocity = v*width;
} else if (v < 0) {
velocity = 1000000 //reversingMode: Sync doesn't seem to work?
}
}
lastUpdateTime = now;
lastUpdateValue = percent;
}
}
More information about the Interest
mailing list