Background images
The backgroundImage style paints a texture as part of a node's own
background: over its backgroundColor and gradients, under its content and
children. The source is an asset path or a texture the app registered on the
Rust side. A background image never affects layout.
Usage
<node
style={{
width: 150,
height: 96,
borderRadius: 10,
backgroundColor: "#1a1b26",
backgroundImage: { src: "images/parrot.png" },
}}
/>The value is always an object with a src; there is no string shorthand.
| Field | Type | Default | Effect |
|---|---|---|---|
src |
string or { texture: string } |
required | Asset path, or a registered texture name |
mode |
"stretch", "repeat", "repeatX", "repeatY" |
"stretch" |
How the texture fills the node |
scale |
number |
1 |
Tile size multiplier in the repeat modes |
tint |
color | white | Multiplied with every texel |
A value without src, or a bare string, is ignored with a
backgroundImage warning; the rest of the style still applies.
Sources
- A string
srcis an asset path loaded by Bevy'sAssetServer, relative to the app's asset folder, as for<image>. Any format your Bevy build can load works. { texture: "name" }shows a texture registered in theRenderTargetsresource. Until the name is registered the node shows nothing, and it picks the texture up as soon as it appears.
TSX
<node
style={{
width: 190,
height: 130,
backgroundImage: { src: { texture: "checker" }, mode: "repeat" },
}}
/>Rust
use bevy::asset::RenderAssetUsages;
use bevy::prelude::*;
use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat};
use bevy_react::RenderTargets;
fn register_checker(
mut targets: ResMut<RenderTargets>,
mut images: ResMut<Assets<Image>>,
) {
let image = Image::new_fill(
Extent3d { width: 2, height: 2, depth_or_array_layers: 1 },
TextureDimension::D2,
&[122, 162, 247, 255],
TextureFormat::Rgba8UnormSrgb,
RenderAssetUsages::default(),
);
targets.register("checker", images.add(image));
}Registered textures are meant for static content: an image you generated or
loaded once. To show a camera's live output, use
<portal>.
Fit and tiling
- The image fills the node's content box, inside the border and the
padding. With padding, the
backgroundColorshows around it. "stretch"fills that box exactly, ignoring the texture's aspect ratio."repeat"tiles the texture on both axes at its own size, one texel per logical pixel on every display, timesscale."repeatX"tiles horizontally and stretches vertically;"repeatY"the reverse.scaleonly applies to the repeat modes (0.5tiles at half size). Under"stretch"it is ignored with abackgroundImagewarning.borderRadiusclips the image in"stretch"mode but not in the repeat modes.- An unknown
modefalls back to"stretch"with abackgroundImagewarning.
Tint and opacity
tint multiplies every texel, like an <image>'s tint. opacity on the
node fades the image with the rest of the node's fills (see
Opacity).
tint accepts an { animated } interpolateColor binding in the base
style, driven every frame without re-rendering React:
function Glowing() {
const t = useSharedValue(0);
useEffect(() => {
t.value = withRepeat(withTiming(1, { duration: 1600 }), { reverse: true });
}, [t]);
const tint = interpolateColor(t, [0, 1], ["#ffffff", "#7aa2f7"]);
return (
<node
style={{
width: 150,
height: 96,
backgroundImage: { src: "images/parrot.png", tint: { animated: tint } },
}}
/>
);
}scale does not animate: an { animated } wrapper on it is accepted but
has no effect.
Behavior
- While the asset loads, the node's
backgroundColorand gradients show, and nothing reflows when the texture arrives. - A
hoverStyle,pressStyleorfocusStylevalue replaces the wholebackgroundImage(all its fields) and swaps instantly; there is no transition. imageRenderingcontrols how an asset-path source is resampled when drawn smaller or larger than its own size.<image>,<canvas>,<portal>,<surface>and<svg>own their node's image: on thembackgroundImageis ignored with astyleIgnoredwarning. Wrap them in a<node>to give them a background.
Limits
- No
object-fitor position: the image either stretches to the content box or tiles from its top-left corner. - A
{ texture }source is not watched for changes. A texture that changes every frame still shows inside normal UI, but inside a cached composited layer it freezes on the last captured frame. - A background never resizes a render target created with automatic resolution; give such targets a fixed resolution.
imageRenderingmodes are refused on a{ texture }source.
See backgroundImage in
the style reference.
bevy-react