Create animated gradient arrow



  • Hi,
    I want to create animated gradient arrow. I used the following code, but it does not show animated gradient.

    Canvas {
    id: arrowDown
            width: parent.height/3
            height: width
            antialiasing: true
            anchors.centerIn: parent
    
            property color secondaryColor: "blue"
    
            property real centerWidth: width / 2
            property real centerHeight: height / 2
            property real radius: (Math.min(arrowDown.width, arrowDown.height)*2) / (2*Math.PI)
    
            onSecondaryColorChanged: requestPaint()
            onVisibleChanged: requestPaint()
    
            onPaint: {
                var ctx = getContext("2d");
                ctx.save();
                ctx.clearRect(0, 0, arrowDown.width, arrowDown.height);
                ctx.beginPath();
    
                ctx.lineWidth = 8;
                ctx.moveTo(arrowDown.centerWidth,
                           arrowDown.centerHeight-arrowDown.radius/2);
                ctx.strokeStyle = secondaryColor
    
                ctx.lineTo(arrowDown.centerWidth,
                           arrowDown.centerHeight+arrowDown.radius/2);
    
                ctx.lineTo(arrowDown.centerWidth+arrowDown.centerWidth/4,
                           arrowDown.centerHeight+arrowDown.radius/4);
    
                ctx.moveTo(arrowDown.centerWidth,
                           arrowDown.centerHeight+arrowDown.radius/2);
                ctx.lineTo(arrowDown.centerWidth-arrowDown.centerWidth/4,
                           arrowDown.centerHeight+arrowDown.radius/4);
    
                var gradient = ctx.createLinearGradient(0, 0, 100, 100);
                gradient.addColorStop(0.3, Qt.rgba(1, 0, 0, 1));
                gradient.addColorStop(0.7, "white");
    
                ctx.stroke();
                ctx.restore();
            }
    
            Timer {
                interval: 200
                repeat: true
                running: true
    
                onTriggered: {
                   ???
                    arrowDown.requestPaint()
                }
            }
        }
    
    

  • Moderators

    @neda What kind of animation is it? Are you animating color, position or something else?



  • @p3c0

    Animating color and position

    I wrote this, but is it best code?

    property bool animate: false
        Canvas {
            id: arrowDown
            
            width: parent.height/3
            height: width
            antialiasing: true
            anchors.centerIn: parent
    
            //property color primaryColor: "silver"
            property color secondaryColor: "steelblue"
    
            property real centerWidth: width / 2
            property real centerHeight: height / 2
            property real radius: (Math.min(arrowDown.width, arrowDown.height)*2) / (2*Math.PI)
    
            //onPrimaryColorChanged: requestPaint()
            onSecondaryColorChanged: requestPaint()
            onVisibleChanged: requestPaint()
    
            property double pos: 0.5
    
            onPaint: {
                var ctx = getContext("2d");
                ctx.save();
                ctx.clearRect(0, 0, arrowDown.width, arrowDown.height);
                ctx.beginPath();
    
                ctx.lineWidth = 10;
                ctx.moveTo(arrowDown.centerWidth,
                           arrowDown.centerHeight-arrowDown.radius/2);
                ctx.strokeStyle = secondaryColor
    
                ctx.lineTo(arrowDown.centerWidth,
                           arrowDown.centerHeight+arrowDown.radius/2);
    
                ctx.lineTo(arrowDown.centerWidth+arrowDown.centerWidth/4,
                           arrowDown.centerHeight+arrowDown.radius/4);
    
                ctx.moveTo(arrowDown.centerWidth,
                           arrowDown.centerHeight+arrowDown.radius/2);
                ctx.lineTo(arrowDown.centerWidth-arrowDown.centerWidth/4,
                           arrowDown.centerHeight+arrowDown.radius/4);
    
                ctx.stroke();
                ctx.restore();
    
                var grd = ctx.createLinearGradient(arrowDown.centerWidth,
                                                   arrowDown.centerHeight-arrowDown.radius/2,
                                                   arrowDown.centerWidth,
                                                   arrowDown.centerHeight+arrowDown.radius/2);
                grd.addColorStop(0, "steelblue");
                grd.addColorStop(arrowDown.pos, "silver");
                grd.addColorStop(1,"steelblue");
                ctx.fillStyle=grd;
                ctx.fillRect(arrowDown.centerWidth-5,
                             arrowDown.centerHeight-arrowDown.radius/2,
                             10,
                             arrowDown.radius);
            }
            onPosChanged: {
                arrowDown.requestPaint();
            }
            NumberAnimation {
                id: anim
                running: true
                target: arrowDown
                property: "pos"
                duration: 1000
                from: 0.9
                to: 0.1
                easing.type: Easing.InOutQuad
    
                onStopped: {
                    var temp = anim.from;
                    anim.from = anim.to;
                    anim.to = temp;
                    anim.running = true;
                }
            }
    
            Timer {
                interval: 200
                repeat: true
                running: true
    
                onTriggered: {
                    if(animate===true)
                        arrowDown.centerHeight+=10;
                    else
                        arrowDown.centerHeight-=10;
    
                    animate=!animate;
                    arrowDown.requestPaint()
                }
            }
        }
    
    

  • Moderators

    @neda Unfortunately I was not able to make it work. But from the observation I see you are using both NumberAnimation and Timer at same time. How about using ParallelAnimation and using 2 NumberAnimation's instead ?



  • This post is deleted!


  • @p3c0

    Thank you very much.

    Image {
            id: pic
            source: "arrowDown.png"
            ParallelAnimation {
                loops: Animation.Infinite
                    running: true
                    NumberAnimation { target: pic; property: "opacity"; to: 0; duration: 2000 ;loops: Animation.Infinite}
                    NumberAnimation { target: pic; property: "y"; to: 100 ; duration: 2000;loops: Animation.Infinite }
                }
        }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.