Image
Renders a 2D image as a textured quad in the scene. Width/height are in world units. Texture loading is handled by the image system, which populates ImageComponent.texture and ImageComponent.object asynchronously.
Editor inspector

Properties
| Property | Type | Description |
|---|---|---|
path | string | Source URL or localasset:// path of the image file. |
width | number | Width of the rendered quad in world units. |
height | number | Height of the rendered quad in world units. |
texture | THREE.Texture | null | Loaded texture, populated asynchronously by the image system. null until loaded. |
object | THREE.Object3D | null | Live three.js object representing the textured quad. null until built. |
API reference
- Class:
ImageComponent - Source:
core/components/Image.ts
Scripting examples
Component access patterns
Use this.getComponent(X) to access a component on the entity this script is attached to. Use this.world.getEntityByName to find another entity by name, then this.world.getComponent to read its component:
// Component on the entity this script is on
const image = this.getComponent(ImageComponent);
// Component on another entity, found by its scene name
const other = this.world.getEntityByName("Banner");
if (other) {
const image = this.world.getComponent(other.entityId, ImageComponent);
}Smooth resize toward a target size
Lerp the image quad's dimensions toward inspector-defined target values, useful for animated UI reveals or zoom effects.
import { Behaviour, ImageComponent } from "@relu-interactives/spatial-ecs";
import type { FloatInput } from "@relu-interactives/spatial-ecs";
export default class ImageResizer extends Behaviour {
data = {
targetWidth: 2 as FloatInput,
targetHeight: 2 as FloatInput,
speed: 3 as FloatInput,
};
protected onUpdate() {
const image = this.getComponent(ImageComponent);
if (!image) return;
const k = this.data.speed * this.deltaTime;
image.width += (this.data.targetWidth - image.width) * k;
image.height += (this.data.targetHeight - image.height) * k;
}
}Show or hide based on a flag
Drive the quad's visibility from the inspector or from game logic via Object3DRef.
import { Behaviour, ImageComponent, Object3DRef } from "@relu-interactives/spatial-ecs";
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
export default class ImageVisibility extends Behaviour {
data = {
visible: true as BooleanInput,
};
protected onUpdate() {
const image = this.getComponent(ImageComponent);
if (!image?.object) return; // wait for texture load
const ref = this.getComponent(Object3DRef);
if (ref) ref.visibility = this.data.visible;
}
}Via ComponentInput in the inspector
You can also pick this component from the inspector using a ComponentInput field. Assign any entity in the inspector and the field resolves to the live ImageComponent instance at runtime.
import {
Behaviour,
ImageComponent,
type ComponentInput,
} from "@relu-interactives/spatial-ecs";
export default class Example extends Behaviour {
data = {
targetImage: {
type: "component",
value: null,
} as unknown as ComponentInput,
};
protected onUpdate() {
const image = this.data.targetImage.value as ImageComponent | null;
if (!image) return;
// Use the live component instance.
}
}Via EntityInput in the inspector
Alternatively, pick an entity from the inspector using an EntityInput field and then read the component off that entity via world.getComponent:
import {
Behaviour,
ImageComponent,
type EntityInput,
type WorldEntityView,
} from "@relu-interactives/spatial-ecs";
export default class Example extends Behaviour {
data = {
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
};
protected onUpdate() {
const entity = this.data.targetEntity.value as WorldEntityView | null;
if (!entity) return;
const image = this.world.getComponent(
entity.entityId,
ImageComponent,
) as ImageComponent | null;
if (!image) return;
// Use the component on the picked entity.
}
}
