diff --git a/src/lib.rs b/src/lib.rs index 07c2325..34259d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ mod table; mod teleport; mod theme; mod utils; +mod wave; pub use button::*; pub use checkbox::*; @@ -20,3 +21,4 @@ pub use slider::*; pub use space::*; pub use table::*; pub use theme::Theme; +pub use wave::*; diff --git a/src/wave/mod.rs b/src/wave/mod.rs new file mode 100644 index 0000000..7e9746f --- /dev/null +++ b/src/wave/mod.rs @@ -0,0 +1,30 @@ +use crate::utils::mount_style::mount_style; +use leptos::*; +use stylers::style_sheet_str; + +#[component] +pub fn Wave(cx: Scope, children: Children) -> impl IntoView { + let class_name = mount_style("wave", || style_sheet_str!("./src/wave/wave.css")); + let (css_vars, set_css_vars) = create_signal(cx, String::new()); + let wave_ref = create_node_ref::(cx); + wave_ref.on_load(cx, move |wave| { + wave.on(ev::mousedown, move |ev| { + wave_ref.on_load(cx, move |wave| { + let rect = wave.get_bounding_client_rect(); + let client_x = f64::from(ev.client_x()); + let client_y = f64::from(ev.client_y()); + set_css_vars.set(format!( + "--x: {}px; --y: {}px", + client_x - rect.left(), + client_y - rect.top() + )); + }) + }); + }); + view! { + cx, class=class_name, +
+ { children(cx) } +
+ } +} diff --git a/src/wave/wave.css b/src/wave/wave.css new file mode 100644 index 0000000..1e28f33 --- /dev/null +++ b/src/wave/wave.css @@ -0,0 +1,38 @@ +.melt-wave { + position: relative; +} +.melt-wave::before { + content: ""; + display: block; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + transition: 0.2s; + background: #fff; + opacity: 0; +} +.melt-wave:active::before { + opacity: 0.2; +} +.melt-wave::after { + content: ""; + display: block; + position: absolute; + width: 200%; + height: 100%; + left: var(--x, 0); + top: var(--y, 0); + background-image: radial-gradient(circle, #fff 10%, transparent 10.01%); + background-repeat: no-repeat; + background-position: 50%; + transform: translate(-50%, -50%) scale(10); + opacity: 0; + transition: transform 0.8s, opacity 0.8s; +} +.melt-wave:active::after { + transform: translate(-50%, -50%) scale(0); + opacity: 0.3; + transition: 0s; +}