Web component for easily displaying interactive 3D models with AR support across browsers and devices
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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';
}
}