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. Rotating DropShadow
Qt 6.11 is out! See what's new in the release blog

Rotating DropShadow

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 2 Posters 1.3k 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.
  • M Offline
    M Offline
    Mark81
    wrote on last edited by
    #1

    I'm quite new to QtGraphicalEffect. Please consider this short code:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtGraphicalEffects 1.0
    
    Window {
        visible: true
        property double spinAngle: 0
    
        Image {
            id: imgBackground
            source: "file:///images/background.png"
    
            Image {
                id: imgSpinner
                source: "file:///images/spinner.png"
                x: imgBackground.width / 2 - imgSpinner.width / 2
                y: 260
                visible: false
                antialiasing: true
            }
    
            DropShadow {
                 id: sdwSpinner
                 anchors.fill: imgSpinner
                 horizontalOffset: 8
                 verticalOffset: 8
                 radius: 4.0
                 samples: 17
                 color: "#AA000000"
                 source: imgSpinner
    
                 transform: Rotation {
                     id: rotSpinner
                 }
    
                 SequentialAnimation {
                     id: anim1
                     PropertyAction { target: rotSpinner; property: "origin.x"; value: imgSpinner.width / 2 }
                     PropertyAction { target: rotSpinner; property: "origin.y"; value: 240 }
                     NumberAnimation { target: rotSpinner; property: "angle"; easing.type: Easing.Linear; to: 360; duration: 1000 }
                 }
            }
    
            MouseArea {
                anchors.fill: parent;
                onClicked: {
                    anim1.loops = Animation.Infinite
                    anim1.start()
                }
            }
        }
    }
    

    It just paint an image (spinner) over a background and when you click with the mouse, the spinner start rotating.
    The problem is the DropShadow rotates with the image, instead of being projected to the same direction I specified initially (offset 8,8 px).

    What is the right way to animate a DropShadow in the way it is recalculated when it rotates?

    raven-worxR 1 Reply Last reply
    -1
    • M Mark81

      I'm quite new to QtGraphicalEffect. Please consider this short code:

      import QtQuick 2.9
      import QtQuick.Window 2.2
      import QtGraphicalEffects 1.0
      
      Window {
          visible: true
          property double spinAngle: 0
      
          Image {
              id: imgBackground
              source: "file:///images/background.png"
      
              Image {
                  id: imgSpinner
                  source: "file:///images/spinner.png"
                  x: imgBackground.width / 2 - imgSpinner.width / 2
                  y: 260
                  visible: false
                  antialiasing: true
              }
      
              DropShadow {
                   id: sdwSpinner
                   anchors.fill: imgSpinner
                   horizontalOffset: 8
                   verticalOffset: 8
                   radius: 4.0
                   samples: 17
                   color: "#AA000000"
                   source: imgSpinner
      
                   transform: Rotation {
                       id: rotSpinner
                   }
      
                   SequentialAnimation {
                       id: anim1
                       PropertyAction { target: rotSpinner; property: "origin.x"; value: imgSpinner.width / 2 }
                       PropertyAction { target: rotSpinner; property: "origin.y"; value: 240 }
                       NumberAnimation { target: rotSpinner; property: "angle"; easing.type: Easing.Linear; to: 360; duration: 1000 }
                   }
              }
      
              MouseArea {
                  anchors.fill: parent;
                  onClicked: {
                      anim1.loops = Animation.Infinite
                      anim1.start()
                  }
              }
          }
      }
      

      It just paint an image (spinner) over a background and when you click with the mouse, the spinner start rotating.
      The problem is the DropShadow rotates with the image, instead of being projected to the same direction I specified initially (offset 8,8 px).

      What is the right way to animate a DropShadow in the way it is recalculated when it rotates?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Mark81
      i think the only possibility is to counter-rotate the shadow along the item rotation, so it appears that the shadow looks static.
      Please someone correct me if i am wrong and if there is a better/easier solution.

      Heres an example:

      import QtQuick 2.9
      import QtQuick.Window 2.2
      import QtGraphicalEffects 1.0
      
      Window {
          visible: true
      
          width: 800
          height: 600
      
          Image {
              id: imgSpinner
              source: "qrc:///qt_logo.png"
              x: 100
              y: 50
              visible: true
              antialiasing: true
      
              layer.enabled: true
              layer.effect: DropShadow
              {
                  transparentBorder: true
      
                  horizontalOffset: baseOffset + Math.cos(-angleRad)*imgSpinner.width
                  verticalOffset: baseOffset + Math.sin(-angleRad)*imgSpinner.height
      
                  property real baseOffset: 8
                  property real angleRad: imgSpinner.rotation*(2* Math.PI/360)
              }
          }
      
          ParallelAnimation {
              id: anim1
              NumberAnimation { target: imgSpinner; property: "rotation"; easing.type: Easing.Linear; to: 360; duration: 1000 }
          }
      
          MouseArea {
              anchors.fill: parent;
              onClicked: {
                  anim1.loops = Animation.Infinite
                  anim1.start()
              }
          }
      }
      

      In the code you just have to fiddle around a bit to place shadow correctly. But i think it mostly does what you want (at least if i understood you correctly).
      In my example the shadow is misplaced next to the item for some reason, i haven't debugged very much into it. But at least i think this brings you very close to the your desired result.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      M 1 Reply Last reply
      2
      • raven-worxR raven-worx

        @Mark81
        i think the only possibility is to counter-rotate the shadow along the item rotation, so it appears that the shadow looks static.
        Please someone correct me if i am wrong and if there is a better/easier solution.

        Heres an example:

        import QtQuick 2.9
        import QtQuick.Window 2.2
        import QtGraphicalEffects 1.0
        
        Window {
            visible: true
        
            width: 800
            height: 600
        
            Image {
                id: imgSpinner
                source: "qrc:///qt_logo.png"
                x: 100
                y: 50
                visible: true
                antialiasing: true
        
                layer.enabled: true
                layer.effect: DropShadow
                {
                    transparentBorder: true
        
                    horizontalOffset: baseOffset + Math.cos(-angleRad)*imgSpinner.width
                    verticalOffset: baseOffset + Math.sin(-angleRad)*imgSpinner.height
        
                    property real baseOffset: 8
                    property real angleRad: imgSpinner.rotation*(2* Math.PI/360)
                }
            }
        
            ParallelAnimation {
                id: anim1
                NumberAnimation { target: imgSpinner; property: "rotation"; easing.type: Easing.Linear; to: 360; duration: 1000 }
            }
        
            MouseArea {
                anchors.fill: parent;
                onClicked: {
                    anim1.loops = Animation.Infinite
                    anim1.start()
                }
            }
        }
        

        In the code you just have to fiddle around a bit to place shadow correctly. But i think it mostly does what you want (at least if i understood you correctly).
        In my example the shadow is misplaced next to the item for some reason, i haven't debugged very much into it. But at least i think this brings you very close to the your desired result.

        M Offline
        M Offline
        Mark81
        wrote on last edited by
        #3

        @raven-worx Thanks! I will try your solution as soon as possible and I will come back with a feedback.

        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