diff --git a/.config/quickshell/modules/common/widgets/PrimaryTabButton.qml b/.config/quickshell/modules/common/widgets/PrimaryTabButton.qml index e5993d8e0..6b865cf77 100644 --- a/.config/quickshell/modules/common/widgets/PrimaryTabButton.qml +++ b/.config/quickshell/modules/common/widgets/PrimaryTabButton.qml @@ -12,11 +12,73 @@ TabButton { property string buttonIcon property bool selected: false property int tabContentWidth: contentItem.children[0].implicitWidth + property int rippleDuration: 1000 height: buttonBackground.height PointingHandInteraction {} - background: Rectangle { + component RippleAnim: NumberAnimation { + duration: rippleDuration + easing.type: Appearance.animation.elementMoveEnter.type + easing.bezierCurve: Appearance.animation.elementMoveEnter.bezierCurve + } + + MouseArea { + anchors.fill: parent + onPressed: (event) => { + + const {x,y} = event + const stateY = buttonBackground.y; + rippleAnim.x = x; + rippleAnim.y = y - stateY; + + const dist = (ox,oy) => ox*ox + oy*oy + const stateEndY = stateY + buttonBackground.height + rippleAnim.radius = Math.sqrt(Math.max(dist(0, stateY), dist(0, stateEndY), dist(width, stateY), dist(width, stateEndY))) + + rippleAnim.restart(); + event.accepted = false + } + } + + SequentialAnimation { + id: rippleAnim + + property real x + property real y + property real radius + + PropertyAction { + target: ripple + property: "x" + value: rippleAnim.x + } + PropertyAction { + target: ripple + property: "y" + value: rippleAnim.y + } + PropertyAction { + target: ripple + property: "opacity" + value: 0.1 + } + ParallelAnimation { + RippleAnim { + target: ripple + properties: "implicitWidth,implicitHeight" + from: 0 + to: rippleAnim.radius * 2 + } + RippleAnim { + target: ripple + property: "opacity" + to: 0 + } + } + } + + background: ClippingRectangle { id: buttonBackground radius: Appearance.rounding.small implicitHeight: 50 @@ -29,6 +91,19 @@ TabButton { easing.bezierCurve: Appearance.animation.elementMove.bezierCurve } } + + Rectangle { + id: ripple + + radius: Appearance.rounding.full + color: button.current ? Appearance.m3colors.m3primary : Appearance.m3colors.m3onSurface + opacity: 0 + + transform: Translate { + x: -ripple.width / 2 + y: -ripple.height / 2 + } + } } contentItem: Item { anchors.centerIn: buttonBackground