svg() is used to render SVG (Scalable Vector Graphics) in your app. It accepts SVG data as bytes and renders it using the Skia graphics engine.
Usage
use freya::prelude::*;
use bytes::Bytes;
fn app() -> impl IntoElement {
svg(Bytes::from_static(include_bytes!("icon.svg")))
.width(48.0)
.height(48.0)
}
Builder Methods
SVG Styling
Set the SVG color (tints the entire SVG).svg(bytes).color(Color::BLUE)
Override the fill color of SVG paths.svg(bytes).fill(Color::RED)
Override the stroke color of SVG paths.svg(bytes).stroke(Color::BLACK)
svg(bytes).stroke(None) // Remove stroke
Layout
Set the SVG width.svg(bytes).width(64.0)
svg(bytes).width(Size::fill())
Set the SVG height.svg(bytes).height(64.0)
svg(bytes).height(Size::fill())
Expand to fill available space.
Set padding around the SVG.
Set margin outside the SVG.
Set minimum width.svg(bytes).min_width(32.0)
Set minimum height.svg(bytes).min_height(32.0)
Set maximum width.svg(bytes).max_width(128.0)
Set maximum height.svg(bytes).max_height(128.0)
Effects
Rotate the SVG in degrees.
Set opacity (0.0 to 1.0).
Scale the SVG.svg(bytes).scale(1.5)
svg(bytes).scale((1.5, 2.0))
Accessibility
Set the accessibility ID.
Set alternative text for screen readers.svg(icon_bytes).a11y_alt("Settings icon")
Events
Handle press/click events.svg(bytes).on_press(|_| println!("SVG clicked!"))
on_mouse_enter
EventHandler<MouseEventData>
Handle mouse enter events.
on_mouse_leave
EventHandler<MouseEventData>
Handle mouse leave events.
Examples
Basic SVG Icon
const ICON: &[u8] = include_bytes!("assets/icon.svg");
svg(Bytes::from_static(ICON))
.width(24.0)
.height(24.0)
Colored Icon
svg(Bytes::from_static(ICON))
.width(32.0)
.height(32.0)
.color(Color::from_rgb(100, 150, 255))
let mut hovered = use_state(|| false);
svg(Bytes::from_static(ICON))
.width(48.0)
.height(48.0)
.color(if hovered() { Color::BLUE } else { Color::GRAY })
.on_mouse_enter(move |_| hovered.set(true))
.on_mouse_leave(move |_| hovered.set(false))
.on_press(|_| println!("Clicked!"))
Responsive SVG
svg(Bytes::from_static(LOGO))
.width(Size::fill())
.height(Size::px(100.0))
.padding(20.0)
SVG with Custom Fill and Stroke
svg(Bytes::from_static(ICON))
.width(64.0)
.height(64.0)
.fill(Color::from_rgb(255, 200, 0))
.stroke(Color::BLACK)
Rotated SVG
let angle = use_state(|| 0.0);
use_effect(move |_| {
// Animate rotation
angle.set((angle() + 1.0) % 360.0);
});
svg(Bytes::from_static(SPINNER))
.width(32.0)
.height(32.0)
.rotate(angle())
Loading SVG at Runtime
use bytes::Bytes;
let svg_data = use_state(|| None::<Bytes>);
use_effect(move |_| {
spawn(async move {
let bytes = fetch_svg_from_url("https://example.com/icon.svg").await;
svg_data.set(Some(bytes));
});
});
if let Some(data) = svg_data() {
svg(data)
.width(48.0)
.height(48.0)
} else {
label().text("Loading...")
}
Loading SVG Data
From Static Files
const SVG_DATA: &[u8] = include_bytes!("icon.svg");
svg(Bytes::from_static(SVG_DATA))
From String
let svg_string = r#"<svg>...</svg>"#;
svg(Bytes::from(svg_string.as_bytes().to_vec()))
From File at Runtime
use std::fs;
let svg_bytes = fs::read("path/to/icon.svg").unwrap();
svg(Bytes::from(svg_bytes))
Notes
- SVG rendering is powered by Skia’s SVG library
- The SVG is automatically sized based on its viewBox and the width/height you specify
- Color operations tint the entire SVG
- Fill and stroke override the SVG’s internal colors
- For best results, use SVGs with proper viewBox attributes
- SVG data must be valid XML