Enable AR viewing experiences using WebXR, ARCore, and ARKit across different platforms and devices.
The primary control for activating AR functionality.
/**
* Enable AR viewing mode
* Shows AR button when AR is available on the device
*/
ar: boolean;
/**
* Check if AR can be activated on current device
* Consider device capabilities and browser support
*/
readonly canActivateAR: boolean;
/**
* Programmatically activate AR mode
* Returns promise that resolves when AR session starts
*/
activateAR(): Promise<void>;
/**
* Generate USDZ file for iOS AR Quick Look
* Returns promise that resolves to USDZ data URL
*/
prepareUSDZ(): Promise<string>;Usage:
<model-viewer
src="models/furniture.glb"
ar
camera-controls>
</model-viewer>// Check AR availability before showing AR features
if (modelViewer.canActivateAR) {
console.log('AR is available');
arButton.style.display = 'block';
}
// Activate AR programmatically
async function startAR() {
try {
await modelViewer.activateAR();
console.log('AR session started');
} catch (error) {
console.error('Failed to start AR:', error);
}
}Specify which AR technologies and platforms to support.
/**
* Supported AR modes (space-separated list)
* - 'webxr': WebXR Device API (modern browsers)
* - 'scene-viewer': Google Scene Viewer (Android)
* - 'quick-look': Apple Quick Look (iOS)
*/
arModes: string;Usage:
<!-- Support all AR platforms -->
<model-viewer
src="models/shoe.glb"
ar
ar-modes="webxr scene-viewer quick-look">
</model-viewer>
<!-- WebXR only for advanced features -->
<model-viewer
src="models/interactive.glb"
ar
ar-modes="webxr">
</model-viewer>Control how the model scales in AR relative to real world.
/**
* AR scaling behavior
* - 'auto': Scale based on model's real-world size metadata
* - 'fixed': Keep model at original size regardless of AR space
*/
arScale: 'auto' | 'fixed';Usage:
<!-- Furniture that should maintain real-world size -->
<model-viewer
src="models/chair.glb"
ar
ar-scale="auto">
</model-viewer>
<!-- Decorative model that should stay fixed size -->
<model-viewer
src="models/logo.glb"
ar
ar-scale="fixed">
</model-viewer>Control where and how the model can be placed in AR.
/**
* AR placement mode
* - 'floor': Place model on detected floor/ground plane
* - 'wall': Place model on detected wall surfaces
*/
arPlacement: 'floor' | 'wall';
/**
* iOS-specific source URL for USDZ format models
* Required for iOS Quick Look AR support
*/
iosSrc: string | null;
/**
* Enable XR environment features
* Provides enhanced lighting and environment integration in WebXR
*/
xrEnvironment: boolean;
/**
* Maximum texture size for AR USDZ models on iOS
* Format: size specification (e.g., "1024", "2048")
*/
arUsdzMaxTextureSize: string;Usage:
<!-- Floor-standing furniture -->
<model-viewer
src="models/table.glb"
ar
ar-placement="floor">
</model-viewer>
<!-- Wall-mounted artwork -->
<model-viewer
src="models/painting.glb"
ar
ar-placement="wall">
</model-viewer>Monitor the current state of AR functionality.
/**
* Current AR status
* - 'not-presenting': AR not active
* - 'session-started': AR session beginning
* - 'object-placed': Model placed in AR space
* - 'failed': AR activation failed
*/
readonly arStatus: ARStatus;
type ARStatus = 'not-presenting' | 'session-started' | 'object-placed' | 'failed';Usage:
// Monitor AR status changes
function updateARUI() {
switch (modelViewer.arStatus) {
case 'not-presenting':
arButton.textContent = 'View in AR';
arButton.disabled = !modelViewer.canActivateAR;
break;
case 'session-started':
arButton.textContent = 'AR Starting...';
arButton.disabled = true;
break;
case 'object-placed':
arButton.textContent = 'AR Active';
showARInstructions();
break;
case 'failed':
arButton.textContent = 'AR Failed';
showARError();
break;
}
}Fired when AR status changes during AR session lifecycle.
interface ARStatusEvent extends Event {
type: 'ar-status';
detail: {
status: ARStatus;
};
}Usage:
modelViewer.addEventListener('ar-status', (event) => {
console.log('AR status changed:', event.detail.status);
switch (event.detail.status) {
case 'session-started':
// Hide UI elements that interfere with AR
hideNormalUI();
break;
case 'object-placed':
// Model successfully placed in AR
showARSuccess();
break;
case 'not-presenting':
// AR session ended, restore normal UI
showNormalUI();
break;
}
});Monitor AR tracking quality and state.
interface ARTrackingEvent extends Event {
type: 'ar-tracking';
detail: {
tracking: 'tracking' | 'not-tracking';
};
}Usage:
modelViewer.addEventListener('ar-tracking', (event) => {
if (event.detail.tracking === 'tracking') {
// Good tracking - hide warning messages
hideTrackingWarning();
} else {
// Poor tracking - show user guidance
showTrackingWarning('Move device slowly and ensure good lighting');
}
});WebXR provides the most advanced AR features with full integration.
<model-viewer
src="models/product.glb"
ar
ar-modes="webxr"
camera-controls>
</model-viewer>Features:
Google's Scene Viewer provides AR on Android devices via Google Play Services.
<model-viewer
src="models/furniture.glb"
ar
ar-modes="scene-viewer"
ar-scale="auto">
</model-viewer>Features:
Apple's Quick Look provides AR experiences on iOS devices.
<model-viewer
src="models/shoe.glb"
ar
ar-modes="quick-look"
ios-src="models/shoe.usdz">
</model-viewer>Features:
Combine AR viewing with model animations:
<model-viewer
src="models/robot.glb"
ar
ar-modes="webxr scene-viewer quick-look"
animation-name="idle"
autoplay>
</model-viewer>// Start specific animation when entering AR
modelViewer.addEventListener('ar-status', (event) => {
if (event.detail.status === 'object-placed') {
modelViewer.animationName = 'celebrate';
modelViewer.play();
}
});Create custom AR activation button with enhanced UX:
<model-viewer src="models/product.glb" ar>
<button slot="ar-button" id="ar-button">
<img src="icons/ar-icon.svg" alt="AR">
View in your space
</button>
</model-viewer>#ar-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
transition: transform 0.2s;
}
#ar-button:hover {
transform: scale(1.05);
}
#ar-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}Provide fallbacks for devices without AR support:
function setupARExperience() {
if (modelViewer.canActivateAR) {
// Full AR experience
setupARButton();
setupARInstructions();
} else {
// Fallback to enhanced 3D viewing
setupEnhanced3D();
showARUnavailableMessage();
}
}
function setupEnhanced3D() {
// Enable advanced camera controls as fallback
modelViewer.cameraControls = true;
modelViewer.touchAction = 'pan-y';
// Add virtual environment
modelViewer.environmentImage = 'environments/studio.hdr';
modelViewer.shadowIntensity = 1;
}
// Check when model loads
modelViewer.addEventListener('load', setupARExperience);Optimize AR experience for different platforms:
function optimizeForPlatform() {
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
const isAndroid = /Android/.test(navigator.userAgent);
if (isIOS) {
// iOS optimizations
modelViewer.arModes = 'quick-look';
// Ensure USDZ version is available
if (modelViewer.iosSrc) {
console.log('iOS AR ready with USDZ');
}
} else if (isAndroid) {
// Android optimizations
modelViewer.arModes = 'scene-viewer webxr';
modelViewer.arScale = 'auto';
} else {
// Desktop/other - WebXR if available
modelViewer.arModes = 'webxr';
}
}