Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Repaint Canvas during PropertyAnimation



  • Hello.
    I have this small problem trying to repaint a canvas that uses a property (angle) to draw a pie. I would like to animate the pie going around, like so...
    0_1539185475673_pie1.png
    1_1539185475674_pie2.png

    Below is my code. So what I did was to create a property called 'curAngle' (a real) that the Canvas uses to draw the above pie. I then created a PropertyAnimation to animate the light-blue part of the pie to grow. As you can see, it's not great. I animate the curAngle to increment by one, use the onStopped event to repaint the Canvas, then restart the animation again.
    I use another property 'filling' that is set to true/false in onPressed and onReleased mouse events respectively.
    I know this isn't best practice. Could anyone suggest a better and more elegant way to do this? A down-side in the way I've done it is that I can't really set how quickly I want the increment to happen.

    Thank you!

    Here's the code.

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
    
        id: mainWindow
    
        visible: true
        width: 640
        height: 480
        title: qsTr("Pie animation")
    
        Rectangle {
            id: panelRect
    
            property bool filling: false
    
            width: parent.width * 0.5
            height: width
            anchors.centerIn: parent
    
            function convert(a) {return a*(Math.PI/180);}
    
            MouseArea {
                anchors.fill: panelRect
                onPressed: {
                    panelRect.filling = true;
                    fillAnimation.running = true;
                }
                onReleased: {
                    panelRect.filling = false;
                }
            }
    
            Canvas {
                id: theCanvas
                anchors.fill: panelRect
                rotation: -90
    
                property real curAngle: 0
    
                property color inactiveColor: '#25969E'
                property color activeColor: '#33EFFF'
    
                onPaint: {
                    var ctx = getContext('2d');
                    ctx.reset();
    
                    var centreX = panelRect.width / 2;
                    var centreY = panelRect.height / 2;
    
                    ctx.beginPath();
                    ctx.fillStyle = activeColor;
                    ctx.moveTo(centreX, centreY);
                    ctx.arc(centreX, centreY, panelRect.width / 2, 0, panelRect.convert(curAngle), false);
                    ctx.lineTo(centreX, centreY);
                    ctx.fill();
    
                    ctx.beginPath();
                    ctx.fillStyle = inactiveColor;
                    ctx.moveTo(centreX, centreY);
                    ctx.arc(centreX, centreY, panelRect.width / 2, panelRect.convert(curAngle), Math.PI * 2, false);
                    ctx.lineTo(centreX, centreY);
                    ctx.fill();
                }
            }
        }
    
        PropertyAnimation {
            id: fillAnimation
            target: theCanvas
            properties: 'curAngle'
            to: theCanvas.curAngle + 1
            duration: 10
    
            onStopped: {
                theCanvas.requestPaint();
                if( panelRect.filling ) {
                    if( theCanvas.curAngle === 360 ) {
                        theCanvas.curAngle = 0;
                    }
                    fillAnimation.running = true;
                }
                
            }
        }
    
    }
    


  • I feel so silly...

    property real curAngle: 0
    
    // the part I was missing...
    onCurAngleChanged: theCanvas.requestPaint()
    
    PropertyAnimation {
        id: animatePie
        target: theCanvas.curAngle
        from: 0
        to: 180
        duration: 1000
    }
    

    Wish someone could have pointed this out to me before.
    I guess there's lots of QtQuick I still need to learn.


Log in to reply