Simplify Ripple effect and make it easier to use everywhere

This commit is contained in:
Nicolas Werner 2022-01-02 06:22:27 +01:00
parent 87ba5796bc
commit 1c83ce1e79
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
6 changed files with 106 additions and 163 deletions

View file

@ -47,17 +47,6 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
visible: Settings.useIdenticon && img.status != Image.Ready visible: Settings.useIdenticon && img.status != Image.Ready
source: Settings.useIdenticon ? ("image://jdenticon/" + (userid !== "" ? userid : roomid) + "?radius=" + (Settings.avatarCircles ? 100 : 25)) : "" source: Settings.useIdenticon ? ("image://jdenticon/" + (userid !== "" ? userid : roomid) + "?radius=" + (Settings.avatarCircles ? 100 : 25)) : ""
MouseArea {
anchors.fill: parent
Ripple {
rippleTarget: parent
color: Qt.rgba(Nheko.colors.alternateBase.r, Nheko.colors.alternateBase.g, Nheko.colors.alternateBase.b, 0.5)
}
}
} }
Image { Image {
@ -118,4 +107,8 @@ Rectangle {
onSingleTapped: avatar.clicked(eventPoint) onSingleTapped: avatar.clicked(eventPoint)
} }
Ripple {
color: Qt.rgba(Nheko.colors.alternateBase.r, Nheko.colors.alternateBase.g, Nheko.colors.alternateBase.b, 0.5)
}
} }

View file

@ -129,10 +129,9 @@ Popup {
if (popup.completerName == "room") if (popup.completerName == "room")
popup.completionSelected(model.roomid); popup.completionSelected(model.roomid);
} }
Ripple { }
rippleTarget: mouseArea Ripple {
color: Qt.rgba(Nheko.colors.base.r, Nheko.colors.base.g, Nheko.colors.base.b, 0.5) color: Qt.rgba(Nheko.colors.base.r, Nheko.colors.base.g, Nheko.colors.base.b, 0.5)
}
} }
DelegateChooser { DelegateChooser {

View file

@ -39,8 +39,6 @@ AbstractButton {
Ripple { Ripple {
color: Qt.rgba(buttonTextColor.r, buttonTextColor.g, buttonTextColor.b, 0.5) color: Qt.rgba(buttonTextColor.r, buttonTextColor.g, buttonTextColor.b, 0.5)
clip: false
rippleTarget: button
} }
} }

View file

@ -4,6 +4,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import "./dialogs" import "./dialogs"
import "./ui"
import Qt.labs.platform 1.1 as Platform import Qt.labs.platform 1.1 as Platform
import QtQml 2.12 import QtQml 2.12
import QtQuick 2.15 import QtQuick 2.15
@ -137,6 +138,10 @@ Page {
required property bool isDirect required property bool isDirect
required property string directChatOtherUserId required property string directChatOtherUserId
Ripple {
color: Qt.rgba(Nheko.colors.dark.r, Nheko.colors.dark.g, Nheko.colors.dark.b, 0.5)
}
height: avatarSize + 2 * Nheko.paddingMedium height: avatarSize + 2 * Nheko.paddingMedium
width: ListView.view.width width: ListView.view.width
state: "normal" state: "normal"

View file

@ -42,8 +42,6 @@ AbstractButton {
Ripple { Ripple {
color: Qt.rgba(buttonTextColor.r, buttonTextColor.g, buttonTextColor.b, 0.5) color: Qt.rgba(buttonTextColor.r, buttonTextColor.g, buttonTextColor.b, 0.5)
clip: false
rippleTarget: button
} }
} }

View file

@ -4,179 +4,129 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import QtQuick 2.10 import QtQuick 2.15
import QtQuick.Controls 2.3 import QtQuick.Controls 2.15
Item { Item {
id: ripple id: ripple
property alias clip: backgroundLayer.clip
property real radius: 0
property color color: "#22000000" property color color: "#22000000"
property real maxRadius: Math.max(width, height) property real maxRadius: Math.max(width, height)
readonly property real radiusAnimationRate: 0.05 readonly property real radiusAnimationRate: 0.05
readonly property real radiusTailAnimationRate: 0.5 readonly property real radiusTailAnimationRate: 0.5
readonly property real opacityAnimationDuration: 300 readonly property real opacityAnimationDuration: 300
readonly property real diameter: radius * 2
property real centerX
property real centerY
property var rippleTarget: parent property var rippleTarget: parent
function start() {
console.log("Starting ripple animation");
ripple.state = "ACTIVE";
}
function stop() {
console.log("Stopping ripple animation");
ripple.state = "NORMAL";
}
anchors.fill: parent anchors.fill: parent
state: "NORMAL"
states: [ PointHandler {
State { id: ph
name: "NORMAL"
}, onGrabChanged: {
State { circle.centerX = point.position.x
name: "ACTIVE" circle.centerY = point.position.y
} }
]
transitions: [
Transition {
from: "NORMAL"
to: "ACTIVE"
SequentialAnimation { target: Rectangle {
ScriptAction { id: backgroundLayer
script: { parent: rippleTarget
ripple.opacity = 1;
ripple.visible = true; anchors.fill: parent
color: "transparent"
clip: true
Rectangle {
id: circle
property real centerX
property real centerY
x: centerX - radius
y: centerY - radius
height: radius*2
width: radius*2
radius: 0
color: ripple.color
state: ph.active ? "ACTIVE" : "NORMAL"
states: [
State {
name: "NORMAL"
},
State {
name: "ACTIVE"
} }
} ]
transitions: [
Transition {
from: "NORMAL"
to: "ACTIVE"
NumberAnimation { SequentialAnimation {
id: radius_animation //PropertyAction { target: circle; property: "centerX"; value: ph.point.position.x }
//PropertyAction { target: circle; property: "centerY"; value: ph.point.position.y }
PropertyAction { target: circle; property: "visible"; value: true }
PropertyAction { target: circle; property: "opacity"; value: 1 }
target: ripple NumberAnimation {
properties: "radius" id: radius_animation
from: 0
to: ripple.maxRadius
duration: ripple.maxRadius / ripple.radiusAnimationRate
easing { target: circle
type: Easing.OutQuad properties: "radius"
} from: 0
to: ripple.maxRadius
duration: ripple.maxRadius / ripple.radiusAnimationRate
} easing {
type: Easing.OutQuad
}
} }
},
Transition {
from: "ACTIVE"
to: "NORMAL"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
id: radius_tail_animation
target: ripple
properties: "radius"
to: ripple.maxRadius
duration: ripple.maxRadius / ripple.radiusTailAnimationRate
easing {
type: Easing.Linear
} }
} },
Transition {
from: "ACTIVE"
to: "NORMAL"
NumberAnimation { SequentialAnimation {
id: opacity_animation ParallelAnimation {
NumberAnimation {
id: radius_tail_animation
target: ripple target: circle
properties: "opacity" properties: "radius"
to: 0 to: ripple.maxRadius
duration: ripple.opacityAnimationDuration duration: ripple.maxRadius / ripple.radiusTailAnimationRate
easing { easing {
type: Easing.InQuad type: Easing.Linear
}
}
NumberAnimation {
id: opacity_animation
target: ripple
properties: "opacity"
to: 0
duration: ripple.opacityAnimationDuration
easing {
type: Easing.InQuad
}
}
}
PropertyAction { target: circle; property: "visible"; value: false }
} }
} }
]
}
ScriptAction {
script: {
ripple.visible = false;
}
}
} }
} }
]
Connections {
// Button
// Default to center
function onPressed(mouse) {
// MouseArea
if (mouse) {
ripple.centerX = mouse.x;
ripple.centerY = mouse.y;
} else if (rippleTarget.pressX) {
ripple.centerX = rippleTarget.pressX;
ripple.centerY = rippleTarget.pressY;
} else {
ripple.centerX = width / 2;
ripple.centerY = height / 2;
}
ripple.start();
}
function onReleased() {
ripple.stop();
}
function onExited() {
ripple.stop();
}
function onCanceled() {
ripple.stop();
}
function onClicked() {
ripple.stop();
}
target: rippleTarget
ignoreUnknownSignals: true
} }
Rectangle {
id: backgroundLayer
anchors.fill: parent
color: "transparent"
clip: true
Rectangle {
id: circle
x: ripple.centerX - ripple.radius
y: ripple.centerY - ripple.radius
height: ripple.diameter
width: ripple.diameter
radius: ripple.radius
color: ripple.color
}
}
} }