or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

accessibility.mdanimation.mdannotation.mdar.mdcontrols.mdenvironment.mdindex.mdloading.mdscene-graph.md
tile.json

loading.mddocs/

Model Loading and Display

Core functionality for loading and displaying 3D models with optimized performance and user experience features.

Capabilities

Model Source

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>

Loading Poster

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();

Loading Behavior

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>

Model Reveal

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>

Credentials

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>

Events

Load Event

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.
});

Progress Event

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}%`;
});

Error Event

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();
  }
});

Model Visibility Event

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();
  }
});

Performance Considerations

Lazy Loading

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>

Progressive Enhancement

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>

Preloading Critical Models

For hero models or critical content, use eager loading:

<model-viewer 
  src="models/hero.glb"
  loading="eager"
  reveal="auto">
</model-viewer>