Skip to content

Resources And Media

Media APIs are feature-gated. Enable only what the app needs.

FeaturePublic APIs
rasterImage, ImageData, StreamingImage, Video, and raw RGBA/native image transport.
imageEnables raster plus image decoding and image-backed style helpers.
svgSvg, SvgData.
resourcesResourceLoader, resource-backed image/SVG constructors, resource roots.
markdownMarkdown parsing and Markdown::mount.

App owns the glyph engine. Load fonts before running the window.

let mut app = lurq::app::App::new();
app.load_font_file(std::path::Path::new("assets/Inter.ttf"));
app.load_fonts_dir(std::path::Path::new("assets/fonts"));
app.register_font("ui", "Inter");

Text uses TextStyle.

use lurq::{
components::Text,
layout::text_style::{FontStyle, FontWeight, TextStyle},
node::color::Color,
};
Text::styled(
"Hello",
TextStyle {
font_family: "ui".into(),
font_size: 18.0,
line_height: 1.25,
weight: FontWeight::Bold,
style: FontStyle::Normal,
color: Color::from_hex("#e5e7eb"),
..TextStyle::default()
},
)

With image, load from bytes, files, or raw RGBA.

use lurq::{components::Image, images::ImageData};
let image = ImageData::from_file("assets/photo.jpg").unwrap();
Image::new(image).size(240.0, 160.0)

Supported formats come from the image dependency configuration: PNG, JPEG, WebP, GIF, BMP, and TIFF. GIF and animated WebP preserve animation frames.

Raw RGBA only requires raster (also enabled by canvas and image):

let pixels = vec![255; 64 * 64 * 4];
let image = ImageData::from_rgba(pixels, 64, 64);

Streaming RGBA uses a stable image identity and uploads new pixels when the buffer version changes:

use lurq::{components::Image, images::StreamingImage};
let stream = StreamingImage::new_rgba(vec![0; 64 * 64 * 4], 64, 64);
stream.update_rgba(|pixels| {
pixels[0] = 255;
pixels[1] = 128;
pixels[2] = 0;
pixels[3] = 255;
});
Image::new(stream.image_data())

With image and resources, let the runtime load files relative to the resource root.

let mut app = lurq::app::App::new();
app.set_resource_root(std::path::PathBuf::from("assets"));
let avatar = lurq::components::Image::from_resource("avatar.png");

The first frame may render while the resource is pending. The loader caches successful results according to ResourceConfig.

Background images use the same feature pair:

use lurq::{components::Rect, node::BackgroundSize};
Rect::new(320.0, 180.0)
.background_image("hero.jpg")
.background_size(BackgroundSize::Cover)

Or use helper shortcuts:

Rect::new(320.0, 180.0).background_cover()
Rect::new(320.0, 180.0).background_contain()

Slider track and thumb styles can also use resource-backed background images:

use lurq::components::Slider;
Slider::new(value)
.track(|style| style.background_image("ui/track.png").background_cover())
.thumb(|style| style.background_image("ui/thumb.png").background_cover())

With svg, construct SVGs from bytes or strings.

use lurq::{components::Svg, node::color::Color, svg::SvgData};
let icon = SvgData::from_str(r#"<svg viewBox="0 0 24 24"></svg>"#)
.with_fill(Color::from_hex("#a855f7"));
Svg::new(icon).size(24.0, 24.0)

With svg and resources:

Svg::from_resource("icons/search.svg").size(18.0, 18.0)

SvgData supports fill, stroke, and opacity overrides.

ResourceLoader::load_resource(path, config) returns:

  • Pending while async load is in progress,
  • Loaded(Arc<Vec<u8>>) when bytes are ready,
  • Error(ResourceError) for not found, network, OS, or unknown errors.

Local paths are resolved under App::set_resource_root(...) when set. Remote http:// and https:// URLs are loaded through ureq.

use std::sync::Arc;
use lurq::resources::{LoadResourceResult, ResourceConfig};
let loader = lurq::resources::ResourceLoader::new();
let path: Arc<str> = Arc::from("data.json");
match loader.load_resource(&path, Some(ResourceConfig { ttl: 60, retries: 1 })) {
LoadResourceResult::Pending => {}
LoadResourceResult::Loaded(bytes) => println!("{} bytes", bytes.len()),
LoadResourceResult::Error(error) => println!("{error:?}"),
}

Most app code should prefer the higher-level resource-backed Image and Svg constructors.

Enable markdown to parse and render Markdown through a retained component:

use lurq::components::{Markdown, MarkdownProps};
Markdown::mount(
ctx,
MarkdownProps::new("# Notes\n\nRead the **release notes**.")
.selectable(true)
.on_link_click(|link| println!("{}", link.destination())),
)

Use MarkdownProps::style(...) for the base text style, .theme(...) for block styling, and .width(...) for a width constraint. Link callbacks decide how the application opens or routes destinations. The demo’s /markdown route exercises the component.