Project Code:https://github.com/euv-dev/euv
Animations are a crucial part of modern web user interfaces. They provide visual feedback, guide user attention, and make applications feel polished and responsive. euv provides a comprehensive animation system that supports CSS transitions, built-in keyframe animations, conditional animations, and custom keyframe injection. This article explores all the animation capabilities available in euv and how to use them effectively.
CSS Transitions
CSS transitions are the simplest way to add animation to your euv components. A CSS transition smoothly interpolates between two property values over a specified duration. You define the transition on an element, and the browser handles the intermediate frames automatically.
In euv, you can apply CSS transitions to any element in your html! template. Transitions work with any animatable CSS property, including opacity, transform, background-color, width, height, and more.
To use a transition, you typically define the following CSS properties on the element:
-
transition-property: Which CSS property to animate (e.g.,opacity,transform,all). -
transition-duration: How long the animation takes (e.g.,0.3s). -
transition-timing-function: The easing curve (e.g.,ease,ease-in-out,linear). -
transition-delay: An optional delay before the animation starts.
Transitions are triggered when a CSS property changes — for example, when a class is added or removed, or when a style property is updated via a reactive signal.
Built-in Keyframe Animations
euv ships with a set of pre-built CSS keyframe animations that you can apply to any element. These animations cover common UI patterns and can be used directly without writing any CSS:
- euv-spin: A 360-degree rotation animation, useful for loading spinners and refresh indicators.
- euv-fade-in: A fade-in from transparent to opaque, great for elements appearing on screen.
- euv-scale-in: A scale-up animation from small to full size, ideal for modals and popups.
- euv-pulse: A pulsing scale animation, perfect for drawing attention to notifications or alerts.
- euv-slide-up: A slide-in from below, commonly used for bottom sheets and toast messages.
- euv-slide-left: A slide-in from the right, suitable for side panels and navigation drawers.
- euv-fade-in-up: A combined fade-in and slide-up animation, excellent for dropdown menus and tooltips.
- euv-progress: A progress bar animation, useful for loading bars and completion indicators.
- euv-shimmer: A shimmering highlight effect, often used for skeleton loading placeholders.
To apply any of these animations, simply add the corresponding class to your element. These keyframe animations are defined in euv's built-in CSS and are ready to use out of the box.
Conditional Animations
Conditional animations allow you to trigger animations based on component state. In euv, this is typically achieved by conditionally applying CSS classes or styles based on reactive signals.
For example, you might want an element to fade in when it first appears and fade out when it is removed. By toggling a CSS class based on a signal, you can control when the animation plays:
let shared_text: Signal<String> = use_signal(|| "Type here...".to_string());
In this example, the shared_text signal holds the current state. You can use this signal to conditionally apply animation classes in your html! template. When the signal changes, the class is added or removed, triggering the CSS transition or keyframe animation.
Conditional animations are particularly powerful when combined with the watch! macro, which can observe state changes and trigger side effects:
watch!(celsius, |celsius_value: f64| {
fahrenheit.set(celsius_value * 9.0 / 5.0 + 32.0);
});
Here, the watch! macro observes the celsius signal and automatically updates the fahrenheit signal. You can extend this pattern to trigger animations — for example, flashing a visual indicator when a value crosses a threshold.
Custom Keyframes with Css::inject_css()
While the built-in animations cover many common use cases, you may need custom animations for specific design requirements. euv provides the Css::inject_css() function for this purpose.
Css::inject_css() allows you to inject arbitrary CSS into the page at runtime, including custom @keyframes definitions. This gives you full control over your animations without leaving the Rust code.
To create a custom animation:
- Define your
@keyframesCSS usingCss::inject_css(). - Apply the animation to an element using the
animationCSS property or theclass!macro.
For example, you could create a custom bounce animation:
// Inject custom keyframes
Css::inject_css("@keyframes custom-bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}");
Then apply it to an element in your template. The injected CSS is added to the document's stylesheet and is available to all elements on the page.
Progress Bar Animation
The euv-progress keyframe animation is specifically designed for progress bar use cases. It creates a smooth, continuous animation that visually indicates progress.
Progress bar animations are commonly used for:
- File upload progress: Showing how much of a file has been uploaded.
- Loading indicators: Displaying the progress of data fetching or processing.
- Multi-step forms: Indicating which step the user is on in a multi-step process.
- Task completion: Showing the overall completion percentage of a long-running task.
The euv-progress animation can be combined with reactive signals to create dynamic progress bars that update in real time as data changes.
Animation Best Practices
When working with animations in euv, keep the following best practices in mind:
Use CSS transitions for simple state changes: If you just need to smoothly change a property value (like opacity or color), CSS transitions are the most performant option.
Leverage built-in keyframe animations: Before writing custom CSS, check if one of the built-in animations (
euv-spin,euv-fade-in,euv-scale-in,euv-pulse,euv-slide-up,euv-slide-left,euv-fade-in-up,euv-progress,euv-shimmer) meets your needs.Use conditional animations sparingly: While it is tempting to animate every state change, excessive animations can be distracting. Animate only the changes that provide meaningful feedback to the user.
Prefer transform and opacity: These properties are GPU-accelerated and provide the smoothest animations. Avoid animating properties like
width,height,margin, orpaddingthat trigger layout recalculations.Test on low-end devices: Animations that run smoothly on a high-end desktop may stutter on mobile devices. Always test your animations on target hardware.
Respect user preferences: Some users prefer reduced motion. Consider respecting the
prefers-reduced-motionmedia query by conditionally disabling animations.
Combining Animations with Reactive Signals
The real power of euv's animation system emerges when you combine it with the reactive signal system. By driving CSS classes and styles from signals, you can create animations that respond to user input, data changes, and application state in real time.
Consider this pattern:
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)
}
}
}
}
The text_signal signal drives the input's value. When the user types, on_input_value updates the signal, which in turn updates any other elements that read from the same signal. You can use this pattern to trigger animations — for example, adding a euv-shimmer class to a skeleton loader while data is being fetched, and switching to euv-fade-in when the data arrives.
Event Handlers for Animations
euv provides event handlers that let you respond to animation lifecycle events:
-
onanimationstart: Fired when a CSS animation starts. -
onanimationend: Fired when a CSS animation completes. -
onanimationiteration: Fired when a CSS animation iteration completes (for repeating animations). -
ontransitionend: Fired when a CSS transition completes.
These event handlers enable you to chain animations, trigger actions after animations complete, or coordinate multiple animations across different elements.
Summary
euv provides a comprehensive animation system that covers all the common animation needs in modern web development:
- CSS transitions for smooth property interpolations.
-
Built-in keyframe animations (
euv-spin,euv-fade-in,euv-scale-in,euv-pulse,euv-slide-up,euv-slide-left,euv-fade-in-up,euv-progress,euv-shimmer) for common UI patterns. - Conditional animations driven by reactive signals for state-dependent visual effects.
-
Custom keyframes via
Css::inject_css()for advanced animation requirements. - Progress bar animations for loading and completion indicators.
-
Animation event handlers (
onanimationstart,ontransitionend, etc.) for lifecycle management.
By combining these animation capabilities with euv's reactive signal system, you can create rich, interactive, and visually appealing user interfaces that respond fluidly to user input and data changes.
Project Code:https://github.com/euv-dev/euv
Top comments (0)