Skip to main content

Using Mimeeq as a 3D/2D Visualizer

Add stunning product visualization to your existing website without changing your UI. This guide shows you how to use Mimeeq purely as a visualization engine that responds to your existing product selectors.

When to Use Visualizer Mode

Perfect for:

  • Ecommerce platforms with existing product pages (Shopify, WooCommerce, Magento)
  • Custom websites where you want to keep your UI
  • B2B portals adding visualization to quote builders
  • Mobile apps needing 3D through WebView

Setup

Step 1: Create a Canvas-Only Template

In your Mimeeq admin panel:

  1. Create a new embed template
  2. Enable "Custom UI" mode to hide all Mimeeq controls
  3. Configure any 3D settings you need
  4. Save the template

Step 2: Add the Visualizer

<!-- Your existing product page -->
<div class="product-page">
<div class="product-visualization">
<!-- Mimeeq canvas only -->
<mmq-embed
id="visualizer"
short-code="YOUR_PRODUCT_CODE"
template="canvas_only_template">
</mmq-embed>
</div>

<div class="product-options">
<!-- Your existing option selectors -->
<select id="color-select">
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>

<select id="size-select">
<option value="small">Small</option>
<option value="large">Large</option>
</select>
</div>
</div>

<script src="https://cdn.mimeeq.com/read_models/embed/app-embed.js" async></script>

Step 3: Connect Your UI to Mimeeq

document.addEventListener('mimeeq-app-loaded', () => {
// Connect your selectors to Mimeeq
document.getElementById('color-select').addEventListener('change', (e) => {
window.mimeeqApp.actions.markOptionByBlockNameAndOptionCode(
'Color', // Block name in Mimeeq
e.target.value // Option code
);
});

document.getElementById('size-select').addEventListener('change', (e) => {
window.mimeeqApp.actions.markOptionByBlockNameAndOptionCode(
'Size',
e.target.value
);
});
});

Complete Working Example

Here's a simple product page with Mimeeq visualization:

<!DOCTYPE html>
<html>
<head>
<style>
.product-page {
display: grid;
grid-template-columns: 1fr 400px;
gap: 40px;
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
}

.visualization-container {
background: #f5f5f5;
border-radius: 12px;
overflow: hidden;
height: 600px;
}

#product-canvas {
width: 100%;
height: 100%;
}

.product-details h1 {
margin-top: 0;
}

.option-group {
margin: 30px 0;
}

.option-group label {
display: block;
font-weight: 600;
margin-bottom: 10px;
}

.option-selector {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
}

.price-display {
font-size: 32px;
font-weight: bold;
margin: 30px 0;
color: #333;
}

.add-to-cart {
width: 100%;
padding: 16px;
background: #000;
color: white;
border: none;
border-radius: 6px;
font-size: 18px;
cursor: pointer;
}

.add-to-cart:hover {
background: #333;
}

.sync-indicator {
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 10px 20px;
border-radius: 4px;
opacity: 0;
transition: opacity 0.3s;
}

.sync-indicator.show {
opacity: 1;
}
</style>
</head>
<body>
<div class="product-page">
<div class="visualization-container">
<mmq-embed
id="product-canvas"
short-code="YOUR_PRODUCT"
template="canvas_only">
</mmq-embed>
</div>

<div class="product-details">
<h1>Custom Product</h1>
<p>Configure your perfect product with our easy-to-use options.</p>

<div class="option-group">
<label for="material">Material</label>
<select class="option-selector" id="material" data-mimeeq-block="Material">
<option value="wood_oak">Oak Wood</option>
<option value="wood_walnut">Walnut Wood</option>
<option value="metal_steel">Steel</option>
<option value="metal_aluminum">Aluminum</option>
</select>
</div>

<div class="option-group">
<label for="color">Color</label>
<select class="option-selector" id="color" data-mimeeq-block="Color">
<option value="natural">Natural</option>
<option value="white">White</option>
<option value="black">Black</option>
<option value="custom_red">Red</option>
</select>
</div>

<div class="option-group">
<label for="size">Size</label>
<select class="option-selector" id="size" data-mimeeq-block="Size">
<option value="small">Small (120cm)</option>
<option value="medium">Medium (160cm)</option>
<option value="large">Large (200cm)</option>
</select>
</div>

<div class="price-display" id="price">
$999.00
</div>

<button class="add-to-cart" onclick="addToCart()">
Add to Cart
</button>
</div>
</div>

<div class="sync-indicator" id="sync-indicator">
Updating visualization...
</div>

<script src="https://cdn.mimeeq.com/read_models/embed/app-embed.js" async></script>

<script>
let currentConfig = {};
let syncTimeout;

document.addEventListener('mimeeq-app-loaded', () => {
console.log('Visualizer ready');

// Connect all selectors
document.querySelectorAll('.option-selector').forEach(selector => {
selector.addEventListener('change', handleOptionChange);
});

// Subscribe to price updates
window.mimeeqApp.observers.pricing.prices.subscribe(({ newValue }) => {
if (newValue && newValue.price) {
document.getElementById('price').textContent =
`$${newValue.price.toFixed(2)}`;
}
});

// Track configuration for cart
window.mimeeqApp.observers.product.configurationCode.subscribe(({ newValue }) => {
currentConfig.code = newValue;
});

window.mimeeqApp.observers.product.sku.subscribe(({ newValue }) => {
currentConfig.sku = newValue;
});
});

function handleOptionChange(event) {
const selector = event.target;
const blockName = selector.dataset.mimeeqBlock;
const optionCode = selector.value;

// Update Mimeeq
window.mimeeqApp.actions.markOptionByBlockNameAndOptionCode(
blockName,
optionCode
);

// Show sync indicator
showSyncIndicator();
}

function showSyncIndicator() {
const indicator = document.getElementById('sync-indicator');
indicator.classList.add('show');

clearTimeout(syncTimeout);
syncTimeout = setTimeout(() => {
indicator.classList.remove('show');
}, 1500);
}

function addToCart() {
// Use Mimeeq's add to cart
window.mimeeqApp.utils.addToCart();

// Or use your own cart system with the current config
console.log('Adding to cart:', currentConfig);
}
</script>
</body>
</html>

Platform Integration Examples

Shopify Integration

For Shopify, connect variant selectors to Mimeeq:

// Listen for Shopify variant changes
document.addEventListener('variant:changed', (event) => {
const variant = event.detail.variant;

// Map Shopify options to Mimeeq
if (variant.option1) {
window.mimeeqApp.actions.markOptionByBlockNameAndOptionCode(
'Color',
mapShopifyToMimeeq(variant.option1)
);
}

if (variant.option2) {
window.mimeeqApp.actions.markOptionByBlockNameAndOptionCode(
'Size',
mapShopifyToMimeeq(variant.option2)
);
}
});

function mapShopifyToMimeeq(shopifyValue) {
// Map your Shopify values to Mimeeq codes
const mapping = {
'Red': 'color_red',
'Blue': 'color_blue',
'Small': 'size_s',
'Large': 'size_l'
};
return mapping[shopifyValue] || shopifyValue;
}

Setting Initial Configuration

Load a saved configuration or URL parameters:

document.addEventListener('mimeeq-app-loaded', () => {
// From URL parameter
const urlParams = new URLSearchParams(window.location.search);
const configCode = urlParams.get('config');

if (configCode) {
window.mimeeqApp.actions.setConfigurationCode(configCode);
} else {
// From saved configuration
const savedConfig = localStorage.getItem('lastConfiguration');
if (savedConfig) {
window.mimeeqApp.actions.setConfigurationCode(savedConfig);
}
}

// Save configuration changes
window.mimeeqApp.observers.product.configurationCode.subscribe(({ newValue }) => {
if (newValue) {
localStorage.setItem('lastConfiguration', newValue);
}
});
});

Screenshot Feature

Add a screenshot button for customers:

async function takeProductScreenshot() {
const button = document.getElementById('screenshot-btn');
button.disabled = true;
button.textContent = 'Generating...';

try {
const imageData = await window.mimeeqApp.utils.takeScreenshot(
'png', // Format
1200, // Width
'#FFFFFF', // Background
null, // Default height
true, // Auto-zoom
true // Reset camera
);

// Create download link
const link = document.createElement('a');
link.download = 'my-custom-product.png';
link.href = imageData;
link.click();

button.textContent = 'Screenshot saved!';
} catch (error) {
console.error('Screenshot failed:', error);
button.textContent = 'Try again';
} finally {
button.disabled = false;
}
}

Performance Considerations

Initial Load Optimization

For ecommerce sites where page speed is critical:

  1. Start with 2D images: Display product images initially, then load 3D on demand
  2. Load on interaction: Place the configurator in a modal that opens when users click "Customize" or "View in 3D"
  3. Consider your users: Not everyone needs 3D visualization - loading Babylon.js, models, and textures can add several MB to your page

Example modal approach:

// Only load configurator when needed
document.getElementById('customize-btn').addEventListener('click', () => {
const modal = document.getElementById('configurator-modal');
modal.style.display = 'block';

// Show the configurator (if using render-at-page-load="false")
document.getElementById('visualizer').show();
});

User Experience

  • Show loading states while the 3D model loads
  • Provide visual feedback when options change
  • Consider adding zoom/rotate instructions

Integration Tips

  • Map your existing option values to Mimeeq codes
  • Keep configuration state synchronized
  • Handle edge cases (invalid combinations, etc.)

Shopify Integration

Mimeeq offers a dedicated Shopify app available in the Shopify App Store that includes:

  • Ready-to-use block for your product pages
  • Built-in integration with Shopify cart
  • Automatic variant synchronization
  • No custom code required for basic setups

For most Shopify stores, installing our app is easier than custom integration. The app handles the visualizer setup and cart integration automatically.

Common Issues

Canvas Not Showing

  • Ensure the container has explicit height
  • Check that the template has Custom UI enabled
  • Verify the short-code is correct

Options Not Syncing

  • Confirm block names match exactly (case-sensitive)
  • Check option codes are correct
  • Ensure mimeeq-app-loaded fires before binding events

Performance Issues

  • Use appropriate texture sizes
  • Consider 2D views for complex products
  • Test on target devices

Next Steps

For Shopify-specific setup, our Shopify app handles most of the integration automatically. Check your Shopify admin panel for configuration options.