diff options
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Widgets/DankRipple.qml')
| -rw-r--r-- | raveos-hyprland-theme/theme-data/dms/Widgets/DankRipple.qml | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Widgets/DankRipple.qml b/raveos-hyprland-theme/theme-data/dms/Widgets/DankRipple.qml new file mode 100644 index 0000000..94501d1 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/dms/Widgets/DankRipple.qml @@ -0,0 +1,104 @@ +import QtQuick +import qs.Common + +Item { + id: root + + property color rippleColor: Theme.primary + property real cornerRadius: 0 + property bool enableRipple: typeof SettingsData !== "undefined" ? (SettingsData.enableRippleEffects ?? true) : true + + property real _rippleX: 0 + property real _rippleY: 0 + property real _rippleMaxRadius: 0 + readonly property alias animating: rippleAnim.running + + anchors.fill: parent + + function trigger(x, y) { + if (!enableRipple || Theme.currentAnimationSpeed === SettingsData.AnimationSpeed.None) + return; + + _rippleX = x; + _rippleY = y; + + const dist = (ox, oy) => ox * ox + oy * oy; + _rippleMaxRadius = Math.sqrt(Math.max(dist(x, y), dist(x, height - y), dist(width - x, y), dist(width - x, height - y))); + + rippleAnim.restart(); + } + + SequentialAnimation { + id: rippleAnim + + PropertyAction { + target: rippleFx + property: "rippleCenterX" + value: root._rippleX + } + PropertyAction { + target: rippleFx + property: "rippleCenterY" + value: root._rippleY + } + PropertyAction { + target: rippleFx + property: "rippleRadius" + value: 0 + } + PropertyAction { + target: rippleFx + property: "rippleOpacity" + value: 0.10 + } + + ParallelAnimation { + DankAnim { + target: rippleFx + property: "rippleRadius" + from: 0 + to: root._rippleMaxRadius + duration: Theme.expressiveDurations.expressiveDefaultSpatial + easing.bezierCurve: Theme.expressiveCurves.standardDecel + } + SequentialAnimation { + PauseAnimation { + duration: Math.round(Theme.expressiveDurations.expressiveDefaultSpatial * 0.6) + } + DankAnim { + target: rippleFx + property: "rippleOpacity" + to: 0 + duration: Theme.expressiveDurations.expressiveDefaultSpatial + easing.bezierCurve: Theme.expressiveCurves.standard + } + } + } + } + + ShaderEffect { + id: rippleFx + visible: rippleAnim.running + + property real rippleCenterX: 0 + property real rippleCenterY: 0 + property real rippleRadius: 0 + property real rippleOpacity: 0 + + x: Math.max(0, rippleCenterX - rippleRadius) + y: Math.max(0, rippleCenterY - rippleRadius) + width: Math.max(0, Math.min(root.width, rippleCenterX + rippleRadius) - x) + height: Math.max(0, Math.min(root.height, rippleCenterY + rippleRadius) - y) + + property real widthPx: width + property real heightPx: height + property real cornerRadiusPx: root.cornerRadius + property real offsetX: x + property real offsetY: y + property real parentWidth: root.width + property real parentHeight: root.height + property vector4d rippleCol: Qt.vector4d(root.rippleColor.r, root.rippleColor.g, root.rippleColor.b, root.rippleColor.a) + + fragmentShader: Qt.resolvedUrl("../Shaders/qsb/ripple.frag.qsb") + } +} |