优化导航栏动画

This commit is contained in:
lsy 2025-01-10 21:10:21 +08:00
parent cd67ab3f2e
commit b75433cdbd

View File

@ -1,5 +1,4 @@
use super::Toggle; use super::Toggle;
use crate::utils::dom::{add_element_class, get_document, remove_element_class};
use crate::Route; use crate::Route;
use dioxus::{logger::tracing, prelude::*}; use dioxus::{logger::tracing, prelude::*};
use wasm_bindgen::{prelude::Closure, JsCast}; use wasm_bindgen::{prelude::Closure, JsCast};
@ -9,14 +8,15 @@ pub fn Navbar() -> Element {
let mut progress_signal = use_signal(|| 0); let mut progress_signal = use_signal(|| 0);
let mut progress_hover = use_signal(|| false); let mut progress_hover = use_signal(|| false);
// 监听滚动事件
use_effect(move || { use_effect(move || {
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
let document = get_document().unwrap(); let document = window.document().unwrap();
let document_element = document.document_element().unwrap(); let document_element = document.document_element().unwrap();
let closure: Closure<dyn FnMut(_)> = Closure::wrap(Box::new(move |_: web_sys::Event| {
if progress_hover() { let closure: Closure<dyn FnMut(_)> = {
return; Closure::wrap(Box::new(move |_: web_sys::Event| {
}
let screen_height = document_element.scroll_height() as f64; let screen_height = document_element.scroll_height() as f64;
let inner_height = window.inner_height().unwrap().as_f64().unwrap(); let inner_height = window.inner_height().unwrap().as_f64().unwrap();
let scrool_height = window.scroll_y().unwrap(); let scrool_height = window.scroll_y().unwrap();
@ -28,18 +28,16 @@ pub fn Navbar() -> Element {
0.0 0.0
}; };
let percent = (percent.clamp(0.0, 1.0) * 100.0) as i32; let percent = (percent.clamp(0.0, 1.0) * 100.0) as i32;
if percent > 0 {
let _ = remove_element_class("nav .progress", "hidden");
} else {
let _ = add_element_class("nav .progress", "hidden");
}
progress_signal.set(percent); progress_signal.set(percent);
}) as Box<dyn FnMut(_)>); }) as Box<dyn FnMut(_)>)
};
document document
.add_event_listener_with_callback("scroll", closure.as_ref().unchecked_ref()) .add_event_listener_with_callback("scroll", closure.as_ref().unchecked_ref())
.unwrap(); .unwrap();
closure.forget(); closure.forget();
}); });
rsx! { rsx! {
nav { nav {
class: "border-red-500 bg-slate-400 text-xl fixed top-0 left-0 right-0", class: "border-red-500 bg-slate-400 text-xl fixed top-0 left-0 right-0",
@ -75,25 +73,32 @@ pub fn Navbar() -> Element {
width: 30 width: 30
} }
div { div {
class:"progress bg-accent h-7 p-2 rounded-full text-xs flex items-center justify-center min-w-7 transition-all duration-300 hidden", class: "progress bg-accent h-7 rounded-full text-xs flex items-center justify-center transition-all duration-300 overflow-hidden",
onmouseenter:move|_|{ style: if progress_signal() > 0 {
format!("opacity: 1; transform: translateX(0); width: {}px;", if progress_signal()==100 { "70" } else { "28" })
} else {
"opacity: 0; transform: translateX(100%); width: 0px".to_string()
},
onmouseenter: move |_| {
progress_hover.set(true); progress_hover.set(true);
}, },
onmouseleave:move|_|{ onmouseleave: move |_| {
progress_hover.set(false); progress_hover.set(false);
}, },
onclick:move|_|{ onclick: move |_| {
progress_hover.set(false); progress_hover.set(false);
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
window.scroll_to_with_x_and_y(0.0, 0.0); window.scroll_to_with_x_and_y(0.0, 0.0);
}, },
div {
class: "px-2 whitespace-nowrap transition-opacity duration-150",
style: "opacity: 1",
{ {
if progress_hover(){ if progress_hover() {
"".to_string() "".to_string()
} }
else{ else{
if progress_signal()==100{ if progress_signal()==100 {
"返回顶部".to_string() "返回顶部".to_string()
} }
else { else {
@ -105,6 +110,7 @@ pub fn Navbar() -> Element {
} }
} }
} }
}
div { div {
class:"w-[80%] mx-auto mt-14", class:"w-[80%] mx-auto mt-14",
Outlet::<Route> {} Outlet::<Route> {}