dioxus_material/
use_ripple.rs1use 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
7pub 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}