by_components/effects/mod.rs
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
#![allow(non_snake_case)]
use dioxus::prelude::*;
/// A component that creates a shadow effect on hover.
///
/// # Example
///
/// ```rust
/// use dioxus::prelude::*;
/// use by_components::effects::HoverEffects;
///
/// #[component]
/// pub fn App() -> Element {
/// rsx! {
/// div {
/// HoverEffects {}
/// button { "Hover me" }
/// a { "Hover me" }
/// div { class: "hover-effect", "hover me" }
/// div { "Don't hover me" }
/// }
/// }
/// }
/// ```
///
/// # Output
///
/// It shows a shadow effect on all of <button/> and <a/> tags.
/// It also shows a shadow effect on the element starting with the class name "hover-effect".
#[component]
pub fn HoverEffects() -> Element {
#[cfg(feature = "web")]
use_effect(move || {
tracing::debug!("shadow mounted");
use wasm_bindgen::prelude::*;
use web_sys::*;
let document = web_sys::window().unwrap().document().unwrap();
let shadow = document.get_element_by_id("shadow").unwrap();
let closure = Closure::wrap(Box::new(move |event: web_sys::Event| {
if let Ok(event) = event.dyn_into::<MouseEvent>() {
if let Some(target) = event.target() {
if let Ok(el) = target.dyn_into::<HtmlElement>() {
if (el.tag_name().to_lowercase().as_str() == "button")
|| (el.tag_name().to_lowercase().as_str() == "a")
|| el
.class_name()
.split(" ")
.collect::<Vec<&str>>()
.contains(&"hover-effect")
{
let x = event.client_x();
let y = event.client_y();
shadow
.set_attribute("style", &format!("left: {}px; top: {}px; position: absolute; width: 50px; height: 50px; background: radial-gradient(circle, rgba(100, 100, 100, 0.5), rgba(0, 0, 0, 0)); border-radius: 50%; pointer-events: none; transform: translate(-50%, -50%); mix-blend-mode: screen; opacity: 0.7; filter: blur(15px); z-index: 9999; ", x, y))
.unwrap();
} else {
shadow.set_attribute("style", "display: none;").unwrap();
}
}
}
}
}) as Box<dyn FnMut(web_sys::Event)>);
document
.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
});
rsx! {
div { id: "shadow" }
}
}