Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Create animated gradient arrow
Qt 6.11 is out! See what's new in the release blog

Create animated gradient arrow

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 2 Posters 2.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    neda
    wrote on last edited by neda
    #1

    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()
                }
            }
        }
    
    
    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

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

      157

      N 1 Reply Last reply
      0
      • p3c0P p3c0

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

        N Offline
        N Offline
        neda
        wrote on last edited by neda
        #3

        @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()
                    }
                }
            }
        
        
        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          @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 ?

          157

          N 2 Replies Last reply
          1
          • p3c0P p3c0

            @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 ?

            N Offline
            N Offline
            neda
            wrote on last edited by neda
            #5
            This post is deleted!
            1 Reply Last reply
            0
            • p3c0P p3c0

              @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 ?

              N Offline
              N Offline
              neda
              wrote on last edited by neda
              #6

              @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 }
                          }
                  }
              
              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved