fix: animate lock cover art

This commit is contained in:
2 * r + 2 * t 2026-06-02 18:35:54 +10:00
parent 318d20fec2
commit 57123a5c8c
3 changed files with 60 additions and 52 deletions

View file

@ -0,0 +1,56 @@
import QtQuick
import Quickshell
import qs.components
Image {
id: root
property bool hadPrevious
function maybeStartInAnim(): void {
if (!opacityInAnim.running && status === Image.Ready) {
opacityInAnim.type = hadPrevious ? Anim.DefaultEffects : Anim.StandardLarge;
opacityInAnim.start();
}
}
asynchronous: true
fillMode: Image.PreserveAspectCrop
sourceSize: {
const dpr = (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1;
return Qt.size(width * dpr, height * dpr);
}
retainWhileLoading: true
opacity: 0
onStatusChanged: maybeStartInAnim()
Anim on opacity {
id: opacityInAnim
running: false
to: 1
}
Behavior on source {
SequentialAnimation {
Anim {
target: root
property: "opacity"
to: 0
type: Anim.FastEffects
}
PropertyAction {
target: root
property: "hadPrevious"
value: root.source
}
PropertyAction {}
ScriptAction {
script: root.maybeStartInAnim()
}
}
}
}

View file

@ -8,6 +8,7 @@ import Caelestia.Config
import qs.components
import qs.components.controls
import qs.components.effects
import qs.components.images
import qs.services
Item {
@ -92,66 +93,16 @@ Item {
}
}
Image {
FadeImage {
id: image
anchors.fill: parent
source: Players.getArtUrl(Players.active)
asynchronous: true
fillMode: Image.PreserveAspectCrop
sourceSize: {
const dpr = (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1;
return Qt.size(width * dpr, height * dpr);
}
layer.enabled: true
layer.effect: Mask {
maskSource: shapeWrapper
}
retainWhileLoading: true
opacity: 0
onStatusChanged: {
if (!opacityInAnim.running && image.status === Image.Ready) {
opacityInAnim.type = root.hadPrevious ? Anim.DefaultEffects : Anim.StandardLarge;
opacityInAnim.start();
}
}
Anim on opacity {
id: opacityInAnim
running: false
to: 1
type: Anim.DefaultEffects
}
Behavior on source {
SequentialAnimation {
Anim {
target: image
property: "opacity"
to: 0
type: Anim.FastEffects
}
PropertyAction {
target: root
property: "hadPrevious"
value: image.source
}
PropertyAction {}
ScriptAction {
script: {
if (!opacityInAnim.running && image.status === Image.Ready) {
opacityInAnim.type = root.hadPrevious ? Anim.DefaultEffects : Anim.StandardLarge;
opacityInAnim.start();
}
}
}
}
}
}
}

View file

@ -5,6 +5,7 @@ import Caelestia.Components
import Caelestia.Config
import qs.components
import qs.components.controls
import qs.components.images
import qs.services
StyledClippingRect {
@ -16,7 +17,7 @@ StyledClippingRect {
radius: Tokens.rounding.extraLarge
color: Colours.tPalette.m3surfaceContainer
Image {
FadeImage {
anchors.fill: parent
source: Players.getArtUrl(Players.active)