editorjs-3d-media
v0.0.1
Published
EditorJS block to display 3d objects in various formats (gltf, glb).
Downloads
7
Maintainers
Readme
EditorJS 3D Media Block
An EditorJS block tool for displaying interactive 3D models in various formats (glTF, GLB, USDZ, and more). Perfect for e-commerce product displays, educational content, engineering documentation, and WebXR experiences.
Features
- 📦 Multiple 3D formats - Support for GLB, glTF, USDZ, OBJ, FBX, and more
- 🎨 Customizable viewers - Choose between ModelViewer or ThreeJS renderers
- 🔄 Interactive controls - Built-in orbit, zoom, and rotation controls
- 📱 iOS AR support - Optional USDZ models for AR Quick Look
- 🖼️ Poster images - Fallback images for better loading experience
- ✍️ Captions - Optional editable captions below 3D models
- 🎯 File validation - Custom validation before upload
- 🔌 Flexible upload - Custom upload handlers for any backend
- 🎭 Custom loaders - Replace default loading UI with your own
- ⚙️ Custom attributes - Add any HTML attributes to the viewer element
Installation
npm install editorjs-3d-mediaIf using ModelViewer (default), also include the ModelViewer library:
npm install @google/model-viewerOr via CDN:
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.0.0/model-viewer.min.js"></script>Usage
Basic Setup
import EditorJS from '@editorjs/editorjs';
import Media3D from 'editorjs-3d-media';
const editor = new EditorJS({
holder: 'editorjs',
tools: {
media3d: {
class: Media3D,
config: {
uploadFile: async (file) => {
// Upload file to your server
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
return {
url: data.url, // Required: URL to the 3D model
viewer: 'modelviewer', // Required: viewer type
otherAttributes: { // Optional: additional attributes for the viewer element
poster: data.posterUrl,
'ios-src': data.iosSrcUrl
}
};
}
}
}
}
});Advanced Configuration
const editor = new EditorJS({
tools: {
media3d: {
class: Media3D,
config: {
viewer: 'modelviewer',
formatsAllowed: ['glb', 'gltf', 'usdz', 'obj'],
enableCaption: true,
autoOpenFilePicker: true,
viewerStyle: {
width: '100%',
height: '500px',
borderRadius: '12px',
backgroundColor: '#f0f0f0'
},
uploadFile: async (file) => {
// Your upload logic
return {
url: 'https://example.com/model.glb',
viewer: 'modelviewer',
otherAttributes: {
poster: 'https://example.com/poster.jpg',
'ios-src': 'https://example.com/model.usdz'
}
};
},
validateFile: (file) => {
const maxSize = 50 * 1024 * 1024; // 50MB
if (file.size > maxSize) {
return 'File size must be less than 50MB';
}
return true;
},
customLoaderElement: (file) => {
const loader = document.createElement('div');
loader.innerHTML = `
<div style="text-align: center; padding: 40px;">
<div class="spinner"></div>
<p>Uploading ${file.name}...</p>
</div>
`;
return loader;
}
}
}
}
});Output Data Format
When you save the editor content, the 3D Media block will return data in this format:
{
type: "media3d",
data: {
viewer: "modelviewer",
caption: "My 3D Model",
file: {
url: "https://example.com/model.glb"
},
attributes: {
poster: "https://example.com/poster.jpg",
"ios-src": "https://example.com/model.usdz"
}
}
}Important Details
Viewer Types
ModelViewer (Default)
- Uses Google's
<model-viewer>web component - Best for web compatibility and AR support
- Supports GLB, glTF, and USDZ formats
- Includes built-in controls and AR Quick Look for iOS
- Requires:
@google/model-viewerlibrary to be loaded
ThreeJS
- Uses Three.js for rendering
- More customizable but requires manual setup
- Note: Currently requires you to implement the rendering logic
File Upload
The uploadFile function must return a Promise that resolves to an object with:
url(required): URL to the 3D model fileviewer(required): The viewer type to use ('modelviewer' or 'threejs')otherAttributes(optional): Object containing additional HTML attributes to add to the viewer element- For ModelViewer, common attributes include
poster(preview image) andios-src(USDZ for AR Quick Look) - These attributes are applied directly to the viewer element (e.g.,
<model-viewer poster="..." ios-src="...">)
- For ModelViewer, common attributes include
File Validation
The validateFile function should:
- Return
trueif the file is valid - Return a string with an error message if invalid
- Receive the File object as parameter
Caption Support
When enableCaption is true:
- Users can add/edit captions below the 3D viewer
- Captions are saved with the block data
- Captions respect read-only mode
Auto-Open File Picker
When autoOpenFilePicker is true (default):
- File picker opens automatically when creating a new block
- Only triggers on first render
- Does not apply in read-only mode
Read-Only Mode
The block fully supports EditorJS read-only mode:
- Captions become non-editable
- Upload button is hidden
- Shows "No 3D model provided" message if no data exists
Configuration Options
| Name | Description | Type | Default |
|------|-------------|------|---------|
| viewer | 3D viewer library to use | 'modelviewer' \| 'threejs' | 'modelviewer' |
| formatsAllowed | Array of allowed 3D file format extensions | string[] | ['glb', 'gltf'] |
| enableCaption | Enable caption input below the 3D viewer | boolean | true |
| autoOpenFilePicker | Automatically open file picker on first render when empty | boolean | true |
| viewerStyle | Custom CSS styles for the 3D viewer element | Partial<CSSStyleDeclaration> | undefined |
| uploadFile | Function to handle file upload to your server | (file: File) => Promise<{url: string, viewer: Viewer, otherAttributes?: Record<string, string>}> | undefined |
| validateFile | Function to validate file before upload | (file: File) => boolean \| string | undefined |
| customLoaderElement | Custom HTML element to show during upload | (file: File) => HTMLElement | undefined |
Browser Support
- Modern browsers with ES6+ support
- ModelViewer requires browsers that support Web Components
- iOS AR Quick Look requires iOS 12+ and Safari
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Credits
Built with:
- EditorJS
- Google Model Viewer (optional)
- CodeX Icons
