1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-06 21:48:30 -04:00

animations: add DankColorAnimation helper to properly animate between

colors with different alpha values
fixes #2720
This commit is contained in:
bbedward
2026-07-03 15:36:45 -04:00
parent 3253adb6dd
commit 930a36bcfc
7 changed files with 95 additions and 41 deletions
@@ -1,7 +1,6 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell
import qs.Common import qs.Common
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
@@ -319,13 +318,13 @@ FocusScope {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
radius: height / 2 radius: height / 2
color: categoryChip.isSelected ? Theme.primary : chipArea.containsMouse ? Theme.surfaceHover : Theme.surfaceVariantAlpha color: chipColor.value
Behavior on color { DankColorAnimation {
ColorAnimation { id: chipColor
duration: root._fastDuration to: categoryChip.isSelected ? Theme.primary : chipArea.containsMouse ? Theme.surfaceHover : Theme.surfaceVariantAlpha
easing.type: Theme.standardEasing duration: root._fastDuration
} easingType: Theme.standardEasing
} }
StyledText { StyledText {
+7 -7
View File
@@ -191,21 +191,21 @@ FloatingWindow {
width: isActive ? dotSize * 3 : dotSize width: isActive ? dotSize * 3 : dotSize
height: dotSize height: dotSize
radius: dotSize / 2 radius: dotSize / 2
color: isActive ? Theme.primary : Theme.surfaceTextAlpha color: dotColor.value
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
DankColorAnimation {
id: dotColor
to: isActive ? Theme.primary : Theme.surfaceTextAlpha
duration: Theme.shortDuration
}
Behavior on width { Behavior on width {
NumberAnimation { NumberAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing easing.type: Theme.emphasizedEasing
} }
} }
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
}
}
} }
} }
} }
@@ -1283,10 +1283,15 @@ Item {
readonly property color requestedColor: isActive ? activeColor : isUrgent ? urgentColor : isPlaceholder ? Theme.surfaceTextLight : isHovered ? Theme.withAlpha(unfocusedColor, 0.7) : isOccupied ? occupiedColor : unfocusedColor readonly property color requestedColor: isActive ? activeColor : isUrgent ? urgentColor : isPlaceholder ? Theme.surfaceTextLight : isHovered ? Theme.withAlpha(unfocusedColor, 0.7) : isOccupied ? occupiedColor : unfocusedColor
property color displayColor: requestedColor
property bool colorAnimationReady: false property bool colorAnimationReady: false
onRequestedColorChanged: Qt.callLater(() => delegateRoot.displayColor = delegateRoot.requestedColor) readonly property color displayColor: pillColor.value
DankColorAnimation {
id: pillColor
to: delegateRoot.requestedColor
animated: delegateRoot.colorAnimationReady
}
Item { Item {
id: dragHandler id: dragHandler
@@ -1560,14 +1565,6 @@ Item {
} }
} }
Behavior on color {
enabled: delegateRoot.colorAnimationReady
ColorAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on border.width { Behavior on border.width {
NumberAnimation { NumberAnimation {
duration: Theme.mediumDuration duration: Theme.mediumDuration
+7 -11
View File
@@ -424,26 +424,22 @@ Item {
id: surface id: surface
anchors.fill: parent anchors.fill: parent
radius: rowItem.dragging ? Theme.cornerRadius + 6 : Theme.cornerRadius radius: rowItem.dragging ? Theme.cornerRadius + 6 : Theme.cornerRadius
color: { color: surfaceColor.value
if (rowItem.dragging)
return Theme.secondaryContainer;
const base = Theme.surfaceContainer;
return Theme.withAlpha(base, rowItem.isEnabled ? 0.7 : 0.4);
}
border.width: rowItem.dragging ? 2 : 1 border.width: rowItem.dragging ? 2 : 1
border.color: rowItem.dragging ? Theme.primary : Theme.outlineHeavy border.color: rowItem.dragging ? Theme.primary : Theme.outlineHeavy
DankColorAnimation {
id: surfaceColor
to: rowItem.dragging ? Theme.secondaryContainer : Theme.withAlpha(Theme.surfaceContainer, rowItem.isEnabled ? 0.7 : 0.4)
duration: Theme.shortDuration
}
Behavior on radius { Behavior on radius {
NumberAnimation { NumberAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
}
}
Behavior on border.color { Behavior on border.color {
ColorAnimation { ColorAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration
@@ -279,7 +279,7 @@ Column {
scale: delegateItem.dragging ? 1.02 : 1.0 scale: delegateItem.dragging ? 1.02 : 1.0
transformOrigin: Item.Center transformOrigin: Item.Center
radius: delegateItem.dragging ? Theme.cornerRadius + 6 : Theme.cornerRadius radius: delegateItem.dragging ? Theme.cornerRadius + 6 : Theme.cornerRadius
color: delegateItem.dragging ? Theme.secondaryContainer : Theme.withAlpha(Theme.surfaceContainer, modelData.enabled ? 0.7 : 0.4) color: itemColor.value
border.color: delegateItem.dragging ? Theme.primary : Theme.outlineHeavy border.color: delegateItem.dragging ? Theme.primary : Theme.outlineHeavy
border.width: delegateItem.dragging ? 2 : 1 border.width: delegateItem.dragging ? 2 : 1
@@ -295,10 +295,10 @@ Column {
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
Behavior on color { DankColorAnimation {
ColorAnimation { id: itemColor
duration: Theme.shortDuration to: delegateItem.dragging ? Theme.secondaryContainer : Theme.withAlpha(Theme.surfaceContainer, modelData.enabled ? 0.7 : 0.4)
} duration: Theme.shortDuration
} }
Behavior on border.color { Behavior on border.color {
ColorAnimation { ColorAnimation {
+1 -1
View File
@@ -44,7 +44,7 @@ Rectangle {
return Theme.withAlpha(root.textColor, 0.20); return Theme.withAlpha(root.textColor, 0.20);
if (hovered) if (hovered)
return Theme.withAlpha(root.textColor, 0.12); return Theme.withAlpha(root.textColor, 0.12);
return "transparent"; return Theme.withAlpha(root.textColor, 0);
} }
Behavior on color { Behavior on color {
+62
View File
@@ -0,0 +1,62 @@
import QtQuick
import qs.Common
// Premultiplied-alpha color tween: bind `to`, read `value`. Plain
// ColorAnimation lerps raw RGBA and flashes when the endpoints differ
// in both color and alpha (translucent <-> opaque).
QtObject {
id: root
property color to
property bool animated: true
property int duration: Theme.mediumDuration
property int easingType: Theme.emphasizedEasing
property color _from: to
property color _target: to
property real _mix: 1
property bool _ready: false
readonly property color value: {
const from = _from;
const target = _target;
const alpha = from.a + (target.a - from.a) * _mix;
if (alpha <= 0)
return Qt.rgba(target.r, target.g, target.b, 0);
const mix = (a, b) => (a * from.a + (b * target.a - a * from.a) * _mix) / alpha;
return Qt.rgba(mix(from.r, target.r), mix(from.g, target.g), mix(from.b, target.b), alpha);
}
readonly property NumberAnimation _anim: NumberAnimation {
target: root
property: "_mix"
from: 0
to: 1
duration: root.duration
easing.type: root.easingType
}
onToChanged: {
if (!_ready || !animated) {
_anim.stop();
_from = to;
_target = to;
_mix = 1;
return;
}
if (Qt.colorEqual(to, _target))
return;
const current = value;
_anim.stop();
_from = current;
_target = to;
_mix = 0;
_anim.restart();
}
Component.onCompleted: {
_from = to;
_target = to;
_ready = true;
}
}