summary refs log tree commit diff
path: root/resources/qml/ui/Ripple.qml
blob: 911b88cf750ab65df642cbaecf33f1db24ace70f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick
import QtQuick.Controls

Item {
    id: ripple

    property color color: "#22000000"
    property real maxRadius: Math.max(width, height)
    readonly property real radiusAnimationRate: 0.05
    readonly property real radiusTailAnimationRate: 0.5
    readonly property real opacityAnimationDuration: 300
    property var rippleTarget: parent

    anchors.fill: parent

    PointHandler {
        id: ph

        onGrabChanged: (_, point) => {
            circle.centerX = point.position.x
            circle.centerY = point.position.y
        }

        target: Rectangle {
            id: backgroundLayer
            parent: rippleTarget

            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"

                        SequentialAnimation {
                            //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 }

                            NumberAnimation {
                                id: radius_animation

                                target: circle
                                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: circle
                                    properties: "radius"
                                    to: ripple.maxRadius
                                    duration: ripple.maxRadius / ripple.radiusTailAnimationRate

                                    easing {
                                        type: Easing.Linear
                                    }

                                }

                                NumberAnimation {
                                    id: opacity_animation

                                    target: circle
                                    properties: "opacity"
                                    to: 0
                                    duration: ripple.opacityAnimationDuration

                                    easing {
                                        type: Easing.InQuad
                                    }

                                }

                            }
                            PropertyAction { target: circle; property: "visible"; value: false }
                        }
                    }
                ]
            }
        }
    }
}