Is there a standard QML component using which several items created in Repeater can be animated one after the other with some delay (i.e. not simultaneously)? So far I could only come up with a Timer based solution like below:
import QtQuick 6.3
Item {
width: 600; height: 400
Row {
anchors.fill: parent
spacing: 5
Repeater {
id: _repeater
anchors.fill: parent
model: 10
delegate: Rectangle {
id: _rect
width: 50; height: 50
color: "green"
function animate() {_anim.start()}
SequentialAnimation {
id: _anim
NumberAnimation {target: _rect; property: "height"; from: 50; to: 150}
NumberAnimation {target: _rect; property: "height"; from: 150; to: 50}
}
}
}
}
Timer {
id: _timer
property var indexes
repeat: true
interval: 150
onTriggered: {
if (indexes.length !== 0) {
_repeater.itemAt(indexes.shift()).animate()
} else
stop()
}
}
MouseArea {
anchors.fill: parent
onClicked: {
_timer.indexes = [1, 2, 3, 4]
_timer.start()
}
}
}
CodePudding user response:
I would use Timeline for that, this is a small example:
import QtQuick
import QtQuick.Timeline
import QtQuick.Controls
Window {
width: 500
height: 400
visible: true
Component {
id: keyframeComponent
KeyframeGroup {
property int startFrame: 0
property int endFrame: 0
property int startValue: 0
property: "height"
Keyframe { frame: startFrame; value: startValue }
Keyframe { frame: (startFrame endFrame) / 2; value: 300 }
Keyframe { frame: endFrame; value: startValue }
}
}
Row {
width: parent.width
height: 300
spacing: 1
Repeater {
model: 10
Rectangle {
id: rect
width: 49
height: Math.round(Math.random() * parent.height)
color: "orange"
Component.onCompleted: {
var startFrame = Math.round(Math.random() * 100);
var endFrame = Math.round(Math.random() * 100);
if(startFrame > endFrame)
{
var temp = endFrame;
endFrame = startFrame;
startFrame = temp;
}
var group = keyframeComponent.createObject(timelineAnimation, {
startFrame: startFrame,
endFrame: endFrame,
startValue: rect.height,
target: rect });
timeline.keyframeGroups.push(group);
}
}
}
}
Button {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: 10
text: "Start"
onClicked: {
timelineAnimation.start();
}
}
Timeline {
id: timeline
startFrame: 0
endFrame: 100
enabled: true
animations: [
TimelineAnimation {
duration: 1000;
from: 0;
to: 100;
running: false;
id: timelineAnimation
}
]
keyframeGroups: []
}
}
Here I create KeyframeGroup
dynamically but you can create that statically of course.
CodePudding user response:
Since you're already using SequentialAnimation and NumberAnimation you do not need to use Timer. You just insert a dummy animation and set a duration to help delay your animation, e.g.
import QtQuick
import QtQuick.Controls
Page {
Repeater {
model: 10
Rectangle {
id: _rect
color: "green"
x: index * 60 50
y: 50
width: 50
height: 50
property real dummy: 0
SequentialAnimation {
running: true
NumberAnimation {target: _rect; property: "dummy"; from: 50; to: 150; duration: index * 100 }
NumberAnimation {target: _rect; property: "height"; from: 50; to: 150}
NumberAnimation {target: _rect; property: "height"; from: 150; to: 50}
}
}
}
}
You can Try it Online!
CodePudding user response:
Since you're already using SequentialAnimation and NumberAnimation you do not need to use Timer. You just insert a dummy animation and set a duration to help delay your animation, e.g.
import QtQuick
import QtQuick.Controls
Page {
id: page
background: Rectangle { color: "#848895" }
Repeater {
model: 10
Rectangle {
id: _rect
border.color: "white"
color: Qt.lighter("green", 1.0 index * 0.3)
x: index * 60 50
y: 50
width: 50
height: 50
property real dummy: 0
SequentialAnimation {
running: true
NumberAnimation {target: _rect; property: "dummy"; from: 50; to: 150; duration: index * 100 }
NumberAnimation {target: _rect; property: "height"; from: 50; to: 150}
NumberAnimation {target: _rect; property: "height"; from: 150; to: 50}
}
}
}
}
You can Try it Online!