TSG
TSG

Reputation: 4617

Combine multiple QML behaviors

I wish to smoothly animate an object, whenever the x and/or y changes. I have it working (as shown below) but I couldn't figure out how to combine the x and y behaviors, so I created 2 behaviors.

Now, I want to emit a signal when the overall animation is complete (x and/or y). I could create 2 flags and test for both being set when the finished signal is emitted. But, if only one dimension animates I will be waiting forever for the second signal.

Is there a simple solution to this? (otherwise I have to preset the flags by prechecking if x or y actually will change)

Behavior on x {
    id: moveSlowlyX
    enabled: true
    NumberAnimation {
        duration: m_time
        easing.type: Easing.InOutQuad
    }
}

Behavior on y {
    id: moveSlowlyY
    enabled: true
    NumberAnimation {
        duration: m_time
        easing.type: Easing.InOutQuad
    }
}

Upvotes: 0

Views: 528

Answers (1)

fallerd
fallerd

Reputation: 1728

You can use the flag running that exists in all classes inherited from Animation to accomplish this. Use a 3rd boolean property to bind the running states from both of your animations together. This will tell when both have stopped. Here is a full working example derived from yours - the buttons make the Rectangle move on one or both axes, and the color will change while it is animating, as well as log when both animations are complete:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    id: applicationWindow
    width: 640
    height: 480
    visible: true

    Rectangle {
        id: rect
        color: animationRunning ? "blue" : "red"
        width: 100
        height: 100

        // if either animation is running (or both), this is true
        // false only when neither animation is running
        property bool animationRunning: xAnim.running || yAnim.running

        onAnimationRunningChanged: {
            if (animationRunning === false) {
                console.log("ANIMATION COMPLETE")
            }
        }

        Behavior on x {
            enabled: true
            NumberAnimation {
                id: xAnim
                duration: 500
                easing.type: Easing.InOutQuad
            }
        }

        Behavior on y {
            enabled: true
            NumberAnimation {
                id: yAnim
                duration: 500
                easing.type: Easing.InOutQuad
            }
        }
    }

    Row { // controls for visually testing/verifying logic
        Button {
            text: "move X"
            onClicked: rect.x = Math.random()* parent.width
        }
        Button {
            text: "move Y"
            onClicked: rect.y = Math.random()* parent.height
        }
        Button {
            text: "move Both"
            onClicked: {
                rect.y = Math.random()* parent.height
                rect.x = Math.random()* parent.width
            }
        }
    }
}

Upvotes: 1

Related Questions