Core functionality for loading and displaying 3D models with optimized performance and user experience features.
The primary property for loading 3D models from URLs.
/**
* URL path to the 3D model file (glTF or GLB format)
* Supports both relative and absolute URLs
*/
src: string;Usage:
const modelViewer = document.querySelector('model-viewer');
modelViewer.src = 'models/astronaut.glb';<model-viewer src="https://cdn.example.com/models/robot.glb"></model-viewer>Display a poster image while the model loads.
/**
* URL to poster image displayed while model loads
* Recommended to use same aspect ratio as the model viewer
*/
poster: string;
/**
* Programmatically dismiss the poster to reveal the model
*/
dismissPoster(): void;
/**
* Show the poster image (reverse of dismissPoster)
*/
showPoster(): void;
/**
* Whether the model has finished loading (readonly)
*/
readonly loaded: boolean;
/**
* Whether the model is currently visible to the user (readonly)
*/
readonly modelIsVisible: boolean;
/**
* Get the dimensions of the loaded model's bounding box
* @returns Vector3D representing width, height, and depth
*/
getDimensions(): Vector3D;
/**
* Get the center point of the model's bounding box
* @returns Vector3D representing the center position
*/
getBoundingBoxCenter(): Vector3D;Usage:
<model-viewer
src="models/chair.glb"
poster="images/chair-poster.jpg">
</model-viewer>// Dismiss poster programmatically
const modelViewer = document.querySelector('model-viewer');
modelViewer.dismissPoster();Control when and how the model loads.
/**
* Controls loading behavior
* - 'auto': Load immediately when src is set
* - 'lazy': Load when element enters viewport
* - 'eager': Load immediately, even if not visible
*/
loading: 'auto' | 'lazy' | 'eager';Usage:
<!-- Load when visible (performance optimization) -->
<model-viewer src="models/large-model.glb" loading="lazy"></model-viewer>
<!-- Load immediately for critical models -->
<model-viewer src="models/hero-model.glb" loading="eager"></model-viewer>Control when the loaded model becomes visible.
/**
* Controls when model becomes visible after loading
* - 'auto': Show immediately after loading
* - 'interaction': Show after user interaction
* - 'manual': Show only via dismissPoster() call
*/
reveal: 'auto' | 'interaction' | 'manual';Usage:
<!-- Require user interaction before showing model -->
<model-viewer
src="models/surprise.glb"
reveal="interaction"
poster="images/click-to-reveal.jpg">
</model-viewer>Include credentials in cross-origin model requests.
/**
* Include credentials (cookies, authorization headers) in requests
* Useful for loading models from authenticated endpoints
*/
withCredentials: boolean;Usage:
<model-viewer
src="https://secure-cdn.com/private/model.glb"
with-credentials>
</model-viewer>Fired when the model has finished loading successfully.
interface LoadEvent extends Event {
type: 'load';
}Usage:
modelViewer.addEventListener('load', (event) => {
console.log('Model loaded successfully');
// Access model properties, start animations, etc.
});Fired during model loading to indicate progress.
interface ProgressEvent extends Event {
type: 'progress';
detail: {
totalProgress: number; // 0 to 1
loaded: number; // bytes loaded
total: number; // total bytes
};
}Usage:
modelViewer.addEventListener('progress', (event) => {
const progress = event.detail.totalProgress * 100;
console.log(`Loading: ${progress.toFixed(1)}%`);
// Update progress bar
progressBar.style.width = `${progress}%`;
});Fired when model loading fails.
interface ErrorEvent extends Event {
type: 'error';
detail: {
type: 'webgl-unsupported' | 'fetch-failure' | 'parse-failure';
sourceError: Error;
};
}Usage:
modelViewer.addEventListener('error', (event) => {
console.error('Model loading failed:', event.detail.type);
// Show fallback content
if (event.detail.type === 'webgl-unsupported') {
showWebGLFallback();
}
});Fired when model visibility changes.
interface ModelVisibilityEvent extends Event {
type: 'model-visibility';
detail: {
visible: boolean;
};
}Usage:
modelViewer.addEventListener('model-visibility', (event) => {
if (event.detail.visible) {
// Model is now visible, safe to start animations
modelViewer.play();
}
});Use loading="lazy" for models that may not be immediately visible:
<model-viewer
src="models/detail-model.glb"
loading="lazy"
poster="images/placeholder.jpg">
</model-viewer>Provide fallback content for unsupported browsers:
<model-viewer src="models/product.glb">
<img src="images/product-fallback.jpg" alt="Product image" slot="poster">
<div slot="error">
<p>3D model not supported in your browser.</p>
<img src="images/product-2d.jpg" alt="Product">
</div>
</model-viewer>For hero models or critical content, use eager loading:
<model-viewer
src="models/hero.glb"
loading="eager"
reveal="auto">
</model-viewer>