Web component for easily displaying interactive 3D models with AR support across browsers and devices
npx @tessl/cli install tessl/npm-google--model-viewer@4.1.0Model Viewer is a web component that makes it easy to display interactive 3D models on the web and in AR. It provides a simple HTML element that can load glTF/GLB models with advanced features like lighting, animations, camera controls, and AR viewing modes.
npm install @google/model-viewerimport '@google/model-viewer';
// The custom element <model-viewer> is now availableFor dynamic imports and module access:
import { ModelViewerElement } from '@google/model-viewer';
// Access to the class directlyThree.js integration utilities:
import { CanvasTexture, FileLoader, Loader, NearestFilter } from '@google/model-viewer';
// Re-exported Three.js utilities<!-- Basic 3D model display -->
<model-viewer
src="models/astronaut.glb"
camera-controls
touch-action="pan-y">
</model-viewer>
<!-- With AR support -->
<model-viewer
src="models/astronaut.glb"
ar
ar-modes="webxr scene-viewer quick-look"
camera-controls
touch-action="pan-y">
</model-viewer>
<!-- With animations -->
<model-viewer
src="models/robot.glb"
animation-name="walking"
autoplay
camera-controls>
</model-viewer>Model Viewer is built as a Lit-based web component with a modular mixin architecture:
The component registers as <model-viewer> and combines all features through mixin composition.
Load and display glTF/GLB 3D models with automatic optimization and caching.
interface LoadingInterface {
src: string;
poster: string;
loading: 'auto' | 'lazy' | 'eager';
reveal: 'auto' | 'interaction' | 'manual';
withCredentials: boolean;
dismissPoster(): void;
}Interactive camera controls with orbit, zoom, and pan functionality.
interface ControlsInterface {
cameraControls: boolean;
cameraOrbit: string;
cameraTarget: string;
fieldOfView: string;
minCameraOrbit: string;
maxCameraOrbit: string;
interactionPrompt: 'auto' | 'when-focused' | 'none';
orbitSensitivity: number;
getCameraOrbit(): SphericalPosition;
getCameraTarget(): Vector3D;
jumpCameraToGoal(): void;
}
interface SphericalPosition {
theta: number;
phi: number;
radius: number;
toString(): string;
}Control 3D model animations with playback options and crossfading.
interface AnimationInterface {
autoplay: boolean;
animationName: string | undefined;
animationCrossfadeDuration: number;
readonly availableAnimations: Array<string>;
readonly paused: boolean;
currentTime: number;
play(options?: PlayAnimationOptions): void;
pause(): void;
appendAnimation(name: string, options?: AppendAnimationOptions): void;
}Enable AR viewing with WebXR, ARCore, and ARKit support.
interface ARInterface {
ar: boolean;
arModes: string;
arScale: 'auto' | 'fixed';
arPlacement: 'floor' | 'wall';
readonly canActivateAR: boolean;
activateAR(): Promise<void>;
}Configure lighting, shadows, and environment maps for realistic rendering.
interface EnvironmentInterface {
environmentImage: string;
skyboxImage: string;
exposure: number;
shadowIntensity: number;
shadowSoftness: number;
neutralLighting: boolean;
}Access and modify the loaded 3D model's scene graph, materials, and variants.
interface SceneGraphInterface {
variantName: string;
readonly availableVariants: Array<string>;
orientation: string;
scale: string;
exportScene(options?: ExportOptions): Promise<Blob>;
createTexture(uri: string): Promise<Texture | null>;
}Add interactive hotspots and annotations positioned in 3D space.
interface AnnotationInterface {
queryHotspot(name: string): HTMLElement | null;
positionHotspot(hotspot: HTMLElement, position: Vector3D): void;
updateHotspot(config: HotspotConfiguration): void;
}Accessibility features and structured data generation.
interface StagingInterface {
alt: string;
generateSchema: boolean;
}type ModelViewerElement = InstanceType<typeof ModelViewerElement>;
type Vector3D = {
x: number;
y: number;
z: number;
toString(): string;
};
type RGB = [number, number, number];
type RGBA = [number, number, number, number];
interface HotspotConfiguration {
name: string;
position: Vector3D;
normal?: Vector3D;
visible?: boolean;
}
interface PlayAnimationOptions {
repetitions?: number;
pingpong?: boolean;
}
interface ExportOptions {
binary?: boolean;
trs?: boolean;
onlyVisible?: boolean;
truncateDrawRange?: boolean;
embedImages?: boolean;
maxTextureSize?: number;
}
type ModelViewerTexture = any; // Three.js Texture wrapper
interface Material {
name?: string;
[key: string]: any;
}
interface Model {
// Model scene graph access
[key: string]: any;
}
interface GLTF {
// glTF specification data structure
[key: string]: any;
}
interface A11yTranslationsInterface {
left: string;
right: string;
front: string;
back: string;
'upper-left': string;
'upper-right': string;
'upper-front': string;
'upper-back': string;
'lower-left': string;
'lower-right': string;
'lower-front': string;
'lower-back': string;
}
interface Finger {
x: number;
y: number;
}/**
* Capture a screenshot of the current model view as a Blob
* @param options - Optional configuration for image capture
* @returns Promise that resolves to image Blob
*/
toBlob(options?: ToBlobOptions): Promise<Blob>;
interface ToBlobOptions {
/** MIME type for the image (default: 'image/png') */
mimeType?: string;
/** Quality argument for lossy formats (0-1) */
qualityArgument?: number;
/** Whether to maintain ideal aspect ratio */
idealAspect?: boolean;
}/**
* Global configuration for all model-viewer instances
*/
interface ModelViewerStaticInterface {
/** Location for DRACO mesh compression decoder */
dracoDecoderLocation: string;
/** Location for KTX2 texture transcoder */
ktx2TranscoderLocation: string;
/** Location for Meshopt decoder */
meshoptDecoderLocation: string;
/** Location for Lottie animation loader */
lottieLoaderLocation: string;
/** Maximum number of models to cache */
modelCacheSize: number;
/** Minimum render scale for performance */
minimumRenderScale: number;
/** Map all URLs through a callback function */
mapURLs(callback: (url: string) => string): void;
}Model Viewer dispatches custom events for various state changes and user interactions:
load - Model finished loadingprogress - Loading progress updateserror - Loading or runtime errorscamera-change - Camera position/target changesar-status - AR mode status changesmodel-visibility - Model visibility changesAll events include relevant detail data and can be handled with standard event listeners.