Created
October 4, 2022 09:05
-
-
Save mitchcurtis/4f7814ad472fb1a318502243ee3657b0 to your computer and use it in GitHub Desktop.
FrameNumberAnimation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// FrameAnimation that operates on a property, like NumberAnimation, | |
// except the duration and easing can be change while it's animating. | |
import QtQuick | |
import QtQuick.Controls | |
import QtQuick.Layouts | |
ApplicationWindow { | |
id: window | |
width: 640 | |
height: 480 | |
visible: true | |
title: qsTr("progress %1 rotation %2").arg(frameAnimation.progress.toFixed(2)).arg(rect.rotation.toFixed(2)) | |
ColumnLayout { | |
RowLayout { | |
Label { | |
text: "Speed" | |
} | |
Slider { | |
id: speedSlider | |
from: 0.1 | |
value: 1 | |
to: 2 | |
stepSize: 0.1 | |
} | |
Label { | |
text: speedSlider.value.toFixed(2) | |
} | |
Button { | |
text: "Restart" | |
onClicked: frameAnimation.restart() | |
} | |
} | |
ButtonGroup { | |
id: easingGroup | |
buttons: easingLayout.children | |
} | |
RowLayout { | |
id: easingLayout | |
RadioButton { | |
text: "Linear" | |
checked: true | |
function easingFunction(t) { | |
return t | |
} | |
} | |
RadioButton { | |
text: "InQuart" | |
function easingFunction(t) { | |
return t * t | |
} | |
} | |
RadioButton { | |
text: "EaseInQuart" | |
function easingFunction(t) { | |
t*=2.0; | |
if(t < 1) { | |
return 0.5*t*t*t; | |
} else { | |
t -= 2.0; | |
return 0.5*(t*t*t + 2); | |
} | |
} | |
} | |
} | |
Label { | |
text: "Duration: " + frameAnimation.duration.toFixed(2) | |
} | |
Label { | |
text: "Effective duration: " + frameAnimation.effectiveDurationInSeconds.toFixed(2) | |
} | |
Label { | |
text: "Distance each second: " + frameAnimation.progressEachSecond.toFixed(2) | |
} | |
} | |
Rectangle { | |
id: rect | |
x: (parent.width - width) / 2 | |
y: (parent.height - height) / 2 | |
width: 100 | |
height: 100 | |
color: "red" | |
Rectangle { | |
width: 4 | |
height: 12 | |
anchors.horizontalCenter: parent.horizontalCenter | |
} | |
} | |
component FrameNumberAnimation: FrameAnimation { | |
id: root | |
required property QtObject target | |
required property string property | |
property real duration | |
property var easingFunction | |
property real from: 0 | |
property real to: 0 | |
property real progressEachSecond: 1 / durationInSeconds | |
readonly property real durationInSeconds: duration / 1000 | |
property real effectiveDurationInSeconds: 0 | |
property real progress: 0 | |
readonly property Binding binding: Binding { | |
target: root.target | |
property: root.property | |
value: from + to * root.easingFunction(root.progress) | |
} | |
signal finished | |
function finish() { | |
progress = 0 | |
stop() | |
finished() | |
} | |
onRunningChanged: { | |
if (running) { | |
progress = 0 | |
reset() | |
} | |
} | |
onTriggered: { | |
progress += progressEachSecond * frameTime; | |
if (progress >= 1.0) | |
finish() | |
} | |
} | |
Component.onCompleted: frameAnimation.start() | |
FrameNumberAnimation { | |
id: frameAnimation | |
duration: 4000 * (1 / speedSlider.value) | |
to: 360 | |
target: rect | |
property: "rotation" | |
easingFunction: easingGroup.checkedButton.easingFunction | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment