Opinionated canvas-based model viewer from BabylonPress, built with @babylonjs/lite.
The viewer creates a WebGPU Babylon Lite scene, loads one glTF/GLB model at a time, frames it with Babylon Lite's default camera helper, and exposes a small TypeScript API for embedding the viewer in an application.
It uses a class-based API similar to traditional Babylon Viewer integrations, while keeping the implementation focused on Babylon Lite and a single canvas.
It supports remote model URLs, local Blob and ArrayBuffer sources, clear-color control, optional transparent canvas compositing, animation group playback controls, screenshot capture, and lifecycle callbacks. The feature set is intentionally minimal, but it can suit a broad range of 3D applications.
More capabilities are planned for a future pure functional viewer and composable helper functions that can be imported on demand.
- Homepage: v1.babylonpress.org
- npm: @litools/babylonpress-lite-viewer
- Repository: eldinor/babylonpress-lite-viewer
- Issues: GitHub issues
- Uses
@babylonjs/liteonly. - Loads remote
.glband.gltfURLs. - Loads local uploaded GLB files as
BloborArrayBufferobjects. - Keeps only one model scene active at a time.
- Frames each loaded model with a default ArcRotate camera.
- Supports an optional scene clear color.
- Includes TypeScript declarations.
This package requires a browser with WebGPU support. If navigator.gpu is unavailable, initialization throws an error.
The canvas should have an explicit size through CSS or layout:
#viewer {
width: 100%;
height: 100%;
}npm i @litools/babylonpress-lite-viewer<canvas id="viewer"></canvas>import { createLiteViewerForCanvas } from "@litools/babylonpress-lite-viewer";
const canvas = document.querySelector("#viewer") as HTMLCanvasElement;
const details = await createLiteViewerForCanvas(canvas, {
source: "https://playground.babylonjs.com/scenes/BoomBox.glb",
});The returned details object contains the viewer instance plus the underlying Babylon Lite engine, scene, and camera.
Use viewer.getState() when an integration needs the current lifecycle state.
loadModel disposes the current scene and creates a new scene before adding the next model. This keeps only one loaded model active, and the new model is framed automatically.
await details.viewer.loadModel("/models/chair.glb");loadModel also accepts a Blob or ArrayBuffer, so it can load a GLB file selected by the user.
<input id="file" type="file" accept=".glb,model/gltf-binary" />const fileInput = document.querySelector("#file") as HTMLInputElement;
fileInput.addEventListener("change", async () => {
const file = fileInput.files?.[0];
if (!file) return;
await details.viewer.loadModel(file);
});Use LiteViewer directly when you want to control construction and initialization separately.
import { LiteViewer } from "@litools/babylonpress-lite-viewer";
const viewer = new LiteViewer(canvas, {
autoStart: false,
});
await viewer.initialize();
await viewer.loadModel("/models/model.glb");
viewer.start();type LiteViewerOptions = {
source?: string | Blob | ArrayBuffer;
lightIntensity?: number;
clearColor?: LiteViewerClearColor;
alphaMode?: "opaque" | "premultiplied";
autoPlayAnimations?: boolean;
autoStart?: boolean;
onInitialized?: (details: LiteViewerDetails) => void;
onLoaded?: (details: LiteViewerDetails) => void;
onError?: (error: unknown) => void;
};Animation groups returned by getAnimationGroups() use the exported
LiteViewerAnimationGroup type.
Optional model source to load during initialization. It can be a URL string, Blob, or ArrayBuffer.
Intensity for the default hemispheric light. Defaults to 1.
Optional scene clear color. Defaults to DEFAULT_CLEAR_COLOR.
clearColor: { r: 0.02, g: 0.02, b: 0.025, a: 1 }Set alphaMode to "premultiplied" if clearColor.a < 1 should make the canvas transparent over page content.
Change the clear color after initialization with:
details.viewer.setClearColor({ r: 0.1, g: 0.1, b: 0.12, a: 1 });Canvas alpha compositing mode. Defaults to "opaque".
Controls whether loaded glTF animation groups start automatically. Defaults to true. Set it to false to stop all animation groups after a model is loaded.
Controls whether the render loop starts automatically after initialization. It defaults to true; set it to false when you want to call viewer.start() manually.
onInitializedruns after the engine, scene, and camera are ready.onLoadedruns after a model is loaded.onErrorruns when initialization or model loading fails.
Creates a LiteViewer, initializes it, and returns LiteViewerDetails.
const details = await createLiteViewerForCanvas(canvas, options);const viewer = new LiteViewer(canvas, options);Methods:
initialize()initializes WebGPU, the engine, scene, light, and camera.loadModel(source)loads a URL,Blob, orArrayBufferand frames the model automatically.getAnimationGroups()returns animation groups loaded with the active model.playAnimationGroup(name)stops other groups and starts the named animation group.pauseAnimations()pauses all animation groups loaded with the active model.stopAnimations()stops all animation groups loaded with the active model.captureScreenshot()captures the current viewer canvas.getState()returns the current viewer lifecycle state.setClearColor(color)updates the active scene clear color.start()starts rendering.stop()stops rendering.dispose()disposes the scene and engine.
Install dependencies:
npm installRun the demo:
npm run demoBuild the package:
npm run buildBuild the demo page:
npm run build:demoRun tests:
npm testRun package consumption smoke test:
npm run test:packageGenerate API docs:
npm run docsCheck the npm package contents:
npm pack --dry-runThe basic canvas demo is in examples/basic-canvas. It loads BoomBox by default and includes two more remote samples plus a GLB upload button.
Screenshot capture uses Babylon Lite's canvas readback. Saved screenshots are opaque; transparent canvas alpha is not preserved in the image data.
npm run demo:basic-canvasNo license has been specified yet.