dioxus_material/
use_ripple.rs

1use dioxus::prelude::*;
2use dioxus_resize_observer::use_size;
3use dioxus_spring::{use_animated, use_spring_signal, UseSpringRef, };
4use dioxus_use_mounted::{use_mounted, UseMounted};
5use std::time::Duration;
6
7/// Hook to create a ripple from a container and animated component.
8pub fn use_ripple(duration: Duration) -> UseRipple {
9    let is_pressed = use_signal(|| false);
10
11    let container_ref = use_mounted();
12    let content_rect = use_size(container_ref);
13    let size = content_rect.width().max(content_rect.height()) * 1.2;
14
15    let ( value_ref, spring_ref) = use_spring_signal([0f32; 2]);
16    let animated_ref = use_mounted();
17
18    use_animated(animated_ref, value_ref, |[size, opacity]| {
19        format!(
20            r"
21            width: {size}px;
22            height: {size}px;
23            opacity: {opacity};
24            position: absolute;
25            top: 50%;
26            left: 50%;
27            transform: translate(-50%, -50%);
28            border-radius: 50%;
29            background: rgba(150, 150, 150, 0.5);
30            "
31        )
32    });
33
34    UseRipple {
35        spring_ref,
36        size,
37        is_pressed,
38        duration,
39        container_ref,
40        animated_ref,
41    }
42}
43
44#[derive(Clone, Copy)]
45pub struct UseRipple {
46    pub spring_ref: UseSpringRef<[f32; 2]>,
47    pub size: f64,
48    pub is_pressed: Signal<bool>,
49    pub duration: Duration,
50    pub container_ref: UseMounted,
51    pub animated_ref: UseMounted,
52}
53
54impl UseRipple {
55    pub fn onmousedown(&mut self) {
56        self.spring_ref.animate([self.size as _, 1.], self.duration);
57        self.is_pressed.set(true)
58    }
59
60    pub fn onmouseup(&mut self) -> bool {
61        if (self.is_pressed)() {
62            self.spring_ref.queue([self.size as _, 0.], self.duration);
63            self.spring_ref.queue([0., 0.], Duration::ZERO);
64            self.is_pressed.set(false);
65            true
66        } else {
67            false
68        }
69    }
70
71    pub fn onmouseleave(&mut self) {
72        if (self.is_pressed)() {
73            self.spring_ref.animate([0., 0.], self.duration);
74            self.is_pressed.set(false)
75        }
76    }
77}