Last active
June 14, 2023 15:37
-
-
Save oKcerG/a3c57ea24d43c45e90263f31a3f912f6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import QtQuick 2.15 | |
import QtQml 2.15 | |
Behavior { | |
id: root | |
property QtObject fadeTarget: targetProperty.object | |
property string fadeProperty: "opacity" | |
property var fadeProperties: [fadeProperty] | |
property var exitValue: 0 | |
property var enterValue: 0 | |
property int fadeDuration: 300 | |
property string easingType: "Quad" | |
property bool delayWhile: false | |
onDelayWhileChanged: { | |
if (!delayWhile) | |
sequentialAnimation.finished(); | |
} | |
readonly property Component shaderEffectSourceWrapperComponent: Item { | |
id: ses | |
property alias shaderEffectSource: shaderEffectSource | |
property alias sourceItem: shaderEffectSource.sourceItem | |
parent: sourceItem.parent | |
x: sourceItem.x | |
y: sourceItem.y | |
ShaderEffectSource { | |
id: shaderEffectSource | |
transformOrigin: sourceItem.transformOrigin | |
hideSource: true | |
live: false | |
width: sourceItem.width | |
height: sourceItem.height | |
} | |
} | |
readonly property Component defaultExitAnimation: NumberAnimation { | |
properties: root.fadeProperties.join(',') | |
duration: root.fadeDuration | |
to: root.exitValue | |
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["In"+root.easingType] | |
} | |
property Component exitAnimation: defaultExitAnimation | |
readonly property Component defaultEnterAnimation: NumberAnimation { | |
properties: root.fadeProperties.join(',') | |
duration: root.fadeDuration | |
from: root.enterValue | |
to: root.fadeTarget[root.fadeProperties[0]] | |
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["Out"+root.easingType] | |
} | |
property Component enterAnimation: defaultEnterAnimation | |
SequentialAnimation { | |
id: sequentialAnimation | |
ScriptAction { | |
script: { | |
const exitItem = shaderEffectSourceWrapperComponent.createObject(null, { sourceItem: root.fadeTarget }); | |
const exitShaderEffectSource = exitItem.shaderEffectSource; | |
if (exitAnimation === root.defaultExitAnimation) | |
root.fadeProperties.forEach(p => exitShaderEffectSource[p] = root.fadeTarget[p]); | |
exitShaderEffectSource.width = root.fadeTarget.width; | |
exitShaderEffectSource.height = root.fadeTarget.height; | |
const exitAnimationInstance = exitAnimation.createObject(root, { target: exitItem.shaderEffectSource }); | |
exitAnimationInstance.finished.connect(() => { | |
sequentialAnimation.finished.disconnect(exitAnimationInstance.start); | |
exitAnimationInstance.target = null; | |
exitItem.destroy(); | |
exitAnimationInstance.destroy(); | |
}); | |
sequentialAnimation.finished.connect(exitAnimationInstance.start); | |
} | |
} | |
PauseAnimation { | |
duration: 5 // figure out how to wait on a signal in an animation (for ShaderEffectSource update) | |
} | |
PropertyAction {} | |
ScriptAction { | |
script: { | |
const enterItem = shaderEffectSourceWrapperComponent.createObject(null, { sourceItem: root.fadeTarget }); | |
const enterShaderEffectSource = enterItem.shaderEffectSource; | |
if (enterAnimation === root.defaultEnterAnimation) | |
root.fadeProperties.forEach(p => enterShaderEffectSource[p] = root.enterValue); | |
enterShaderEffectSource.live = true; | |
const enterAnimationInstance = enterAnimation.createObject(root, { target: enterItem.shaderEffectSource }); | |
enterAnimationInstance.finished.connect(() => { | |
sequentialAnimation.finished.disconnect(enterAnimationInstance.start); | |
enterAnimationInstance.target = null; | |
enterItem.destroy(); | |
enterAnimationInstance.destroy(); | |
}) | |
sequentialAnimation.finished.connect(enterAnimationInstance.start); | |
if (!root.delayWhile) | |
sequentialAnimation.finished(); | |
} | |
} | |
} | |
} |
This file contains hidden or 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
import QtQuick 2.15 | |
import QtQuick.Window 2.15 | |
import QtQuick.Controls 2.15 | |
import QtQuick.Layouts 1.12 | |
Window { | |
width: 500 | |
height: columnLayout.implicitHeight + 40 | |
visible: true | |
title: "CrossFadeBehavior" | |
component BigCenteredLabel: Label { | |
Layout.preferredWidth: 50 | |
font.pixelSize: 30 | |
horizontalAlignment: Text.AlignHCenter | |
verticalAlignment: Text.AlignVCenter | |
} | |
component EmojiImage: Image { | |
Layout.preferredWidth: 50 | |
fillMode: Image.PreserveAspectFit | |
cache: false | |
horizontalAlignment: Image.AlignHCenter | |
verticalAlignment: Image.AlignVCenter | |
readonly property url smilingFaceUrl: "https://deelay.me/20/https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/60/google/56/white-smiling-face_263a.png" | |
readonly property url winkingFaceUrl: "https://deelay.me/20/https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/60/google/56/winking-face_1f609.png" | |
} | |
component DescriptionRow: RowLayout { | |
Layout.fillWidth: true | |
property alias description: descriptionLabel.text | |
Label { | |
id: descriptionLabel | |
font.pixelSize: 12 | |
Layout.fillWidth: true | |
} | |
} | |
component TitleSeparator: RowLayout { | |
spacing: 20 | |
property alias title: titleLabel.text | |
Rectangle { | |
Layout.fillWidth: true | |
Layout.alignment: Qt.AlignCenter | |
height: 1 | |
color: "darkgrey" | |
} | |
Label { | |
id: titleLabel | |
font.pixelSize: 20 | |
Layout.alignment: Qt.AlignCenter | |
} | |
Rectangle { | |
Layout.fillWidth: true | |
Layout.alignment: Qt.AlignCenter | |
height: 1 | |
color: "darkgrey" | |
} | |
} | |
id: root | |
property int counter: 0 | |
Timer { | |
id: timer | |
interval: 1000 | |
repeat: true | |
onTriggered: root.counter++ | |
} | |
Timer { | |
running: true | |
interval: 2000 | |
onTriggered: timer.start() | |
} | |
ColumnLayout { | |
id: columnLayout | |
anchors.fill: parent | |
anchors.margins: 20 | |
spacing: 20 | |
TitleSeparator { title: "Usage on text change" } | |
DescriptionRow { | |
description: "No Behavior" | |
BigCenteredLabel { | |
text: root.counter | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior (on opacity by default)" | |
BigCenteredLabel { | |
text: root.counter | |
CrossFadeBehavior on text {} | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior on scale" | |
BigCenteredLabel { | |
text: root.counter | |
CrossFadeBehavior on text { | |
fadeProperty: "scale" | |
} | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior on scale and opacity" | |
BigCenteredLabel { | |
text: root.counter | |
CrossFadeBehavior on text { | |
fadeProperties: ["scale", "opacity"] | |
} | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior with custom animations" | |
BigCenteredLabel { | |
text: root.counter | |
CrossFadeBehavior on text { | |
id: textCfb | |
exitAnimation: ParallelAnimation { | |
id: exit | |
property Item target | |
NumberAnimation { | |
target: exit.target | |
property: "opacity" | |
to: 0 | |
easing.type: Easing.InQuad | |
} | |
NumberAnimation { | |
target: exit.target | |
property: "x" | |
to: textCfb.fadeTarget.width | |
easing.type: Easing.InQuad | |
} | |
} | |
enterAnimation: ParallelAnimation { | |
id: enter | |
property Item target | |
NumberAnimation { | |
target: enter.target | |
property: "opacity" | |
from: 0 | |
to: 1 | |
easing.type: Easing.InQuad | |
} | |
NumberAnimation { | |
target: enter.target | |
property: "x" | |
from: -textCfb.fadeTarget.width | |
to: 0 | |
easing.type: Easing.OutQuad | |
} | |
} | |
} | |
} | |
} | |
TitleSeparator { title: "Usage on slow image source change" } | |
DescriptionRow { | |
description: "No Behavior" | |
EmojiImage { | |
source: root.counter % 2 === 0 ? smilingFaceUrl : winkingFaceUrl | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior" | |
EmojiImage { | |
source: root.counter % 2 === 0 ? smilingFaceUrl : winkingFaceUrl | |
CrossFadeBehavior on source { } | |
} | |
} | |
DescriptionRow { | |
description: "CrossFadeBehavior with delayWhile loading" | |
EmojiImage { | |
source: root.counter % 2 === 0 ? smilingFaceUrl : winkingFaceUrl | |
CrossFadeBehavior on source { | |
delayWhile: fadeTarget.status === Image.Loading | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment