6

Is there anything for animating text changes? there is already animations for property changes, for example this code do the animation for properties opacity, width and scale and whenever they changed by states, they will get animations.

NumberAnimation {
    properties: "opacity, width, scale, visible"
    easing.type: Easing.OutBack; duration:500
}

However i didn't find anything for text change, for example counting from N to N+1 became animating (eg. fading out old value and fading new one). how i can animating text changes?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
e.jahandar
  • 1,715
  • 12
  • 30
  • 1
    The easiest way would be to change to opacity until the widget becomes invisible, once it is invisible, you can change the text inside and ease in again. (disclamer: I dont use QtQuick) – Croolman May 01 '17 at 11:51

3 Answers3

7

For this usecase I use Behavior with a custom Animation :

//FadeAnimation.qml
import QtQuick 2.0

SequentialAnimation {
    id: root
    property QtObject target
    property string fadeProperty: "scale"
    property int fadeDuration: 150
    property alias outValue: outAnimation.to
    property alias inValue: inAnimation.to
    property alias outEasingType: outAnimation.easing.type
    property alias inEasingType: inAnimation.easing.type
    property string easingType: "Quad"
    NumberAnimation { // in the default case, fade scale to 0
        id: outAnimation
        target: root.target
        property: root.fadeProperty
        duration: root.fadeDuration
        to: 0
        easing.type: Easing["In"+root.easingType]
    }
    PropertyAction { } // actually change the property targeted by the Behavior between the 2 other animations
    NumberAnimation { // in the default case, fade scale back to 1
        id: inAnimation
        target: root.target
        property: root.fadeProperty
        duration: root.fadeDuration
        to: 1
        easing.type: Easing["Out"+root.easingType]
    }
}

Please note that it can be done without all the added properties, but I have them to enable easy customization.

An example usage could be :

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        anchors.centerIn: parent
        color: "red"
        width: 100
        height: width
        radius: width/2
        Text {
            id: textItem
            anchors.centerIn: parent
            font.pixelSize: 30
            color: "white"
            property int foo: 0
            // ### Important part ###
            text: foo
            Behavior on foo {
                FadeAnimation {
                    target: textItem
                }
            }
            // ######################
        }
        MouseArea {
            anchors.fill: parent
            onClicked: textItem.foo++
        }
    }
}

Output : https://zippy.gfycat.com/SilentImpressiveChameleon.webm

The fadeProperty is scale by default but it also works great with opacity.


EDIT :

I've implemented this as ready-to-use components in https://github.com/okcerg/quickbehaviors

GrecKo
  • 6,615
  • 19
  • 23
1

I would suggest something like the following AnimatedText.qml:

import QtQuick 2.5

Item{
    property real progress: 0.0
    property string text0
    property string text1

    Text{
        text: text0
        opacity: 1.0 - progress
    }
    Text{
        text: text1
        opacity: progress
    }
}

Can be used as follows:

AnimatedText{
    text0: "First text"
    text1: "Second text"

    NumberAnimation on progress {
        from: 0.0
        to: 1.0
        duration: 5000
    }
}
Ayberk Özgür
  • 4,986
  • 4
  • 38
  • 58
1

I created a custom Item for this purpose with fade animation. You can edit it for any animation:

AnimatedText.qml

import QtQuick 2.7

Item {
    id: root
    width: Math.max(txt1.width, txt2.width);
    height: Math.max(txt1.height, txt2.height);
    property string text: ""
    property int currentActiveTxt: 1
    property real pointSize: 20
    Text {
        id: txt1
        font { pointSize: root.pointSize }
    }
    Text {
        id: txt2
        font { pointSize: root.pointSize }
    }

    onTextChanged: {
        if(currentActiveTxt == 1) {
            txt2.text = root.text;
            currentActiveTxt = 2;
            root.state = "txt2 is active";
        } else {
            txt1.text = root.text;
            currentActiveTxt = 1;
            root.state = "txt1 is active";
        }
    }

    states: [
        State {
            name: "txt1 is active"
            PropertyChanges {
                target: txt1
                opacity: 1.0
            }
            PropertyChanges {
                target: txt2
                opacity: 0.0
            }
        },
        State {
            name: "txt2 is active"
            PropertyChanges {
                target: txt1
                opacity: 0.0
            }
            PropertyChanges {
                target: txt2
                opacity: 1.0
            }
        }
    ]
    state: "txt1 is active"
    transitions: [
        Transition {
            from: "txt1 is active"
            to: "txt2 is active"
            NumberAnimation {
                property: "opacity"
                duration: 200
            }
        },
        Transition {
            from: "txt2 is active"
            to: "txt1 is active"
            NumberAnimation {
                property: "opacity"
                duration: 200
            }
        }
    ]
}

Sample usage:

Window {
    id:root
    visible: true
    width: 340
    height: 480
    title: qsTr("Hello World")

    AnimatedText {
        id: txt
        pointSize: 30
        anchors.left: parent.left
        anchors.top: parent.top
        anchors.margins: 10
        text: ":)"

    }

    Timer {
        interval: 1000
        running: true
        repeat: true
        property int i: 0
        onTriggered: txt.text = i++;
    }
}
S.M.Mousavi
  • 5,013
  • 7
  • 44
  • 59