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

Animation working in reverse ??



  • I am trying to implement a simple screensaver for an embedded application so I thought I'd use animation to move a logo around the screen. Once I'd got my head around PropertyAnimation etc, all was working fine. Basically it moves the graphic (replaced with rectangle in code shown for simplicity) top left -> bottom right -> top right -> bottom left -> top left. With everything in the main.qml file as shown all works fine:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window {
    
        id: root
        width: 640
        height: 480
        visible: true
        title: qsTr("Screen Saver")
        color: "black"
    
        readonly property int _margin: 50
    
        Rectangle {
            id: rect
            width: 100
            height: 100
            x: _margin
            y: _margin
        }
    
        SequentialAnimation {
            id: sequAnim
            loops: Animation.Infinite
            running: true
    
            readonly property int _left_x: _margin
            readonly property int _right_x: root.width - rect.width - root._margin
            readonly property int _top_y: root._margin
            readonly property int _bottom_y: root.height - rect.height - root._margin
            readonly property int _duration: 3000
    
            ParallelAnimation {
    
                PropertyAnimation {
                    target: rect
                    property: "x"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._right_x
                }
    
                PropertyAnimation {
                    target: rect
                    property: "y"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._bottom_y
                }
            }
    
            PropertyAnimation {
                target: rect
                property: "y"
                duration: sequAnim._duration
                easing.type: Easing.InOutQuad
                to: sequAnim._top_y
            }
    
    
            ParallelAnimation {
    
                PropertyAnimation {
                    target: rect
                    property: "x"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._left_x
                }
    
                PropertyAnimation {
                    target: rect
                    property: "y"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._bottom_y
                }
            }
    
            PropertyAnimation {
                target: rect
                property: "y"
                duration: sequAnim._duration
                easing.type: Easing.InOutQuad
                to: sequAnim._top_y
            }
    
        }
    }
    

    However, if I move all the animation stuff out of the main.qml into ScreenSaver.qml and call this from main.qml, it appears to work with reversed co-ordinates and disappears off to the upper left of the main window:

    main.qml

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window {
    
        id: root
        width: 640
        height: 480
        visible: true
        title: qsTr("Screen Saver")
        color: "black"
    
        ScreenSaver {
            anchors.fill: parent
        }
    
    }
    
    

    and ScreenSaver.qml

    import QtQuick 2.0
    
    Item {
    
        id: root
    
        readonly property int _margin: 50
    
        Rectangle {
            id: rect
            width: 100
            height: 100
            x: _margin
            y: _margin
        }
    
        SequentialAnimation {
            id: sequAnim
            loops: Animation.Infinite
            running: true
    
            readonly property int _left_x: _margin
            readonly property int _right_x: root.width - rect.width - root._margin
            readonly property int _top_y: root._margin
            readonly property int _bottom_y: root.height - rect.height - root._margin
            readonly property int _duration: 3000
    
            ParallelAnimation {
    
                PropertyAnimation {
                    target: rect
                    property: "x"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._right_x
                }
    
                PropertyAnimation {
                    target: rect
                    property: "y"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._bottom_y
                }
            }
    
            PropertyAnimation {
                target: rect
                property: "y"
                duration: sequAnim._duration
                easing.type: Easing.InOutQuad
                to: sequAnim._top_y
            }
    
    
            ParallelAnimation {
    
                PropertyAnimation {
                    target: rect
                    property: "x"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._left_x
                }
    
                PropertyAnimation {
                    target: rect
                    property: "y"
                    duration: sequAnim._duration
                    easing.type: Easing.InOutQuad
                    to: sequAnim._bottom_y
                }
            }
    
            PropertyAnimation {
                target: rect
                property: "y"
                duration: sequAnim._duration
                easing.type: Easing.InOutQuad
                to: sequAnim._top_y
            }
        }
    }
    

    Can anyone shed any light on what's happening here because it's had me scratching my head for most of the day!

    Thanks,
    Alan



  • Update:

    I've found that if I hard-code the propert values for _left_x, _right_x, etc it works OK.

    I also added this code within the top-level Item in ScreenSaver.qml to report the values calculated by the SequentialAnimation:

        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log("Left X: " + sequAnim._left_x)
                console.log("Right X: " + sequAnim._right_x)
                console.log("Top Y: " + sequAnim._top_y)
                console.log("Bottom Y: " + sequAnim._bottom_y)
            }
        }
    

    ... and it reports all positive values as expected. Hard coding these values makes it work as expect but this is less than ideal as it would mean changing the values if I use a different screen size for example.



  • OK, I think I've cracked it but I'd appreciate it if someone can advise me if I've come up with the best solution.

    It appears that at the time of creation the root object of ScreenSaver.qml has dimensions of 0x0 and as a result, the properties of SequentialAnimation are calculated as negative values and are passed down to the to property of the enclosed PropertyAnimation objects.

    I got round it by adding a targetHeight and targetWidth property to the root item in ScreenSaver.qml and then set these values to the width and height of the main window in main.qml

    I would be interested if others would have done it differently?


Log in to reply