euv 动画与过渡效果
动画是现代 Web 用户界面中不可或缺的一部分。它们提供视觉反馈、引导用户注意力,让应用感觉精致且响应迅速。euv 提供了一套全面的动画系统,支持 CSS 过渡、内置关键帧动画、条件动画和自定义关键帧注入。本文将探讨 euv 中所有可用的动画功能及其有效使用方法。
CSS 过渡
CSS 过渡是为 euv 组件添加动画的最简单方式。CSS 过渡在指定的持续时间内平滑地在两个属性值之间进行插值。你在元素上定义过渡,浏览器自动处理中间帧。
在 euv 中,你可以在 html! 模板中的任何元素上应用 CSS 过渡。过渡适用于任何可动画的 CSS 属性,包括 opacity、transform、background-color、width、height 等。
要使用过渡,通常需要在元素上定义以下 CSS 属性:
transition-property:要动画化的 CSS 属性(如opacity、transform、all)。transition-duration:动画持续的时间(如0.3s)。transition-timing-function:缓动曲线(如ease、ease-in-out、linear)。transition-delay:动画开始前的可选延迟。
当 CSS 属性发生变化时触发过渡——例如,当添加或删除类时,或者当通过响应式信号更新样式属性时。
内置关键帧动画
euv 附带了一组预构建的 CSS 关键帧动画,你可以将其应用于任何元素。这些动画涵盖了常见的 UI 模式,可以直接使用,无需编写任何 CSS:
- euv-spin:360 度旋转动画,适用于加载指示器和刷新图标。
- euv-fade-in:从透明到不透明的淡入效果,非常适合元素在屏幕上出现时使用。
- euv-scale-in:从小到大的缩放动画,理想用于模态框和弹出窗口。
- euv-pulse:脉冲缩放动画,非常适合吸引用户注意通知或警告。
- euv-slide-up:从下方滑入的动画,常用于底部弹出层和消息提示。
- euv-slide-left:从右侧滑入的动画,适合侧边面板和导航抽屉。
- euv-fade-in-up:淡入加上滑动画的组合,下拉菜单和工具提示的理想选择。
- euv-progress:进度条动画,适用于加载条和完成指示器。
- euv-shimmer:闪烁高光效果,常用于骨架屏加载占位符。
要应用这些动画中的任何一个,只需将对应的类添加到你的元素上。这些关键帧动画定义在 euv 的内置 CSS 中,开箱即用。
条件动画
条件动画允许你根据组件状态触发动画。在 euv 中,这通常通过基于响应式信号有条件地应用 CSS 类或样式来实现。
例如,你可能希望元素在首次出现时淡入,在移除时淡出。通过基于信号切换 CSS 类,可以控制动画何时播放:
let shared_text: Signal<String> = use_signal(|| "Type here...".to_string());
在这个示例中,shared_text 信号保存当前状态。你可以在 html! 模板中使用此信号有条件地应用动画类。当信号变化时,类会被添加或移除,触发 CSS 过渡或关键帧动画。
条件动画与 watch! 宏结合使用时尤为强大,watch! 宏可以观察状态变化并触发副作用:
watch!(celsius, |celsius_value: f64| {
fahrenheit.set(celsius_value * 9.0 / 5.0 + 32.0);
});
在这里,watch! 宏观察 celsius 信号并自动更新 fahrenheit 信号。你可以扩展此模式来触发动画——例如,当值跨越阈值时闪烁视觉指示器。
使用 Css::inject_css() 自定义关键帧
虽然内置动画涵盖了许多常见用例,但你可能需要针对特定设计需求定制动画。euv 为此提供了 Css::inject_css() 函数。
Css::inject_css() 允许你在运行时将任意 CSS 注入页面,包括自定义的 @keyframes 定义。这让你可以完全控制动画,而无需离开 Rust 代码。
要创建自定义动画:
- 使用
Css::inject_css()定义你的@keyframesCSS。 - 使用
animationCSS 属性或class!宏将动画应用于元素。
例如,你可以创建一个自定义弹跳动画:
// 注入自定义关键帧
Css::inject_css("@keyframes custom-bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}");
然后在模板中应用它。注入的 CSS 会添加到文档的样式表中,页面上的所有元素都可以使用。
进度条动画
euv-progress 关键帧动画专为进度条场景设计。它创建一个平滑、连续的动画,直观地指示进度。
进度条动画通常用于:
- 文件上传进度:显示文件已上传的百分比。
- 加载指示器:显示数据获取或处理的进度。
- 多步骤表单:指示用户在多步骤流程中当前处于哪一步。
- 任务完成度:显示长时间运行任务的整体完成百分比。
euv-progress 动画可以与响应式信号结合使用,创建随着数据变化实时更新的动态进度条。
动画最佳实践
在 euv 中使用动画时,请遵循以下最佳实践:
-
简单状态变化使用 CSS 过渡:如果你只需要平滑地改变一个属性值(如透明度或颜色),CSS 过渡是性能最好的选择。
-
优先使用内置关键帧动画:在编写自定义 CSS 之前,先检查内置动画(
euv-spin、euv-fade-in、euv-scale-in、euv-pulse、euv-slide-up、euv-slide-left、euv-fade-in-up、euv-progress、euv-shimmer)是否能满足需求。 -
适度使用条件动画:虽然为每个状态变化添加动画很吸引人,但过多的动画会分散注意力。只对用户有意义的反馈进行动画处理。
-
优先使用 transform 和 opacity:这些属性由 GPU 加速,提供最流畅的动画。避免动画化
width、height、margin或padding等触发布局重新计算的属性。 -
在低端设备上测试:在高台式机上流畅运行的动画可能在移动设备上卡顿。始终在目标硬件上测试动画。
-
尊重用户偏好:一些用户偏好减少动画。考虑尊重
prefers-reduced-motion媒体查询,通过条件性地禁用动画。
将动画与响应式信号结合
euv 动画系统的真正威力在于将其与响应式信号系统结合使用。通过用信号驱动 CSS 类和样式,你可以创建响应用户输入、数据变化和应用状态的实时动画。
考虑以下模式:
let shared_text: Signal<String> = use_signal(|| "Type here...".to_string());
pub fn child_input(text_signal: Signal<String>, count_signal: Signal<i32>) -> VirtualNode {
html! {
div {
input {
r#type: "text"
value: text_signal.get()
oninput: on_input_value(text_signal)
}
}
}
}
text_signal 信号驱动输入框的值。当用户输入时,on_input_value 更新信号,进而更新任何其他读取同一信号的元素。你可以使用此模式来触发动画——例如,在数据获取时为骨架屏添加 euv-shimmer 类,当数据到达时切换为 euv-fade-in。
动画事件处理函数
euv 提供了事件处理函数,让你响应动画生命周期事件:
onanimationstart:CSS 动画开始时触发。onanimationend:CSS 动画完成时触发。onanimationiteration:CSS 动画每次迭代完成时触发(用于重复动画)。ontransitionend:CSS 过渡完成时触发。
这些事件处理函数使你能够链式连接动画、在动画完成后触发操作,或协调不同元素之间的多个动画。
总结
euv 提供了一套全面的动画系统,涵盖现代 Web 开发中所有常见的动画需求:
- CSS 过渡,用于平滑的属性插值。
- 内置关键帧动画(
euv-spin、euv-fade-in、euv-scale-in、euv-pulse、euv-slide-up、euv-slide-left、euv-fade-in-up、euv-progress、euv-shimmer),用于常见 UI 模式。 - 条件动画,由响应式信号驱动,用于状态相关的视觉效果。
- 自定义关键帧,通过
Css::inject_css()实现高级动画需求。 - 进度条动画,用于加载和完成指示器。
- 动画事件处理函数(
onanimationstart、ontransitionend等),用于生命周期管理。
通过将这些动画能力与 euv 的响应式信号系统结合,你可以创建丰富、交互性强且视觉上吸引人的用户界面,流畅地响应用户输入和数据变化。