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