0% found this document useful (0 votes)
12 views26 pages

Untitled Document

The EcoPackGEN API Integration Guide provides detailed instructions for integrating the EcoPackGEN Packaging Preview API into a frontend application, including setup prerequisites, file structure, and necessary dependencies. It outlines the HTML structure for the user interface, JavaScript implementation for API interaction, and optional CSS styling. Additionally, the guide includes testing and troubleshooting tips to ensure successful integration and functionality of the application.

Uploaded by

shivangi4441
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views26 pages

Untitled Document

The EcoPackGEN API Integration Guide provides detailed instructions for integrating the EcoPackGEN Packaging Preview API into a frontend application, including setup prerequisites, file structure, and necessary dependencies. It outlines the HTML structure for the user interface, JavaScript implementation for API interaction, and optional CSS styling. Additionally, the guide includes testing and troubleshooting tips to ensure successful integration and functionality of the application.

Uploaded by

shivangi4441
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

EcoPackGEN API Integration Guide

This guide explains how to integrate the EcoPackGEN Packaging Preview API into your
frontend application step-by-step.

Setup Instructions
1. Prerequisites

Before you begin, make sure you have:

●​ Basic knowledge of HTML, CSS, and JavaScript


●​ A web server or development environment to serve your files
●​ Access to the EcoPackGEN API (credentials if needed)

2. File Structure Setup

Create the following files in your project directory:

your-project/
├── index.html # Main HTML file with form and UI components
├── ecopackgen.js # JavaScript file with API integration
└── styles.css # Optional: Additional styling if needed

3. Adding Dependencies

The implementation needs these external libraries:

●​ Three.js - For 3D rendering


●​ GLTFLoader - For loading 3D models
●​ OrbitControls - For interacting with 3D models
●​ Tailwind CSS - For styling UI components

4. HTML Structure

In your index.html file, set up the basic structure including the form elements and 3D viewer
container:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EcoPackGEN Integration</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-6 text-center">EcoPackGEN Packaging Preview</h1>

<div class="grid grid-cols-1 md:grid-cols-3 gap-6">


<!-- Configuration Panel -->
<div class="col-span-1 bg-white p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Package Configuration</h2>

<form id="packageForm" class="space-y-4">


<!-- Dimensions -->
<div>
<h3 class="font-medium mb-2">Dimensions (cm)</h3>
<div class="grid grid-cols-3 gap-2">
<div>
<label class="block text-sm">Width</label>
<input type="number" id="width" class="w-full border rounded px-3 py-2"
value="10" min="1">
</div>
<div>
<label class="block text-sm">Height</label>
<input type="number" id="height" class="w-full border rounded px-3 py-2"
value="15" min="1">
</div>
<div>
<label class="block text-sm">Depth</label>
<input type="number" id="depth" class="w-full border rounded px-3 py-2"
value="5" min="1">
</div>
</div>
</div>

<!-- Material Selection -->


<div>
<label class="block font-medium mb-2">Material</label>
<select id="material" class="w-full border rounded px-3 py-2">
<option value="recycled-cardboard">Recycled Cardboard</option>
<option value="corrugated-kraft">Corrugated Kraft</option>
<option value="biodegradable-plastic">Biodegradable Plastic</option>
<option value="mushroom-packaging">Mushroom Packaging</option>
</select>
</div>

<!-- Color Picker -->


<div>
<label class="block font-medium mb-2">Color</label>
<input type="color" id="color" class="w-full h-10 border rounded"
value="#8B5A2B">
</div>

<!-- Logo Upload -->


<div>
<label class="block font-medium mb-2">Logo (optional)</label>
<input type="file" id="logo" class="w-full border rounded px-3 py-2"
accept="image/*">
</div>

<!-- Submit Button -->


<button type="submit" class="w-full bg-green-600 text-white font-medium py-2 px-4
rounded hover:bg-green-700 transition-colors">
Generate Preview
</button>
</form>
</div>

<!-- 3D Preview Panel -->


<div class="col-span-2">
<div class="bg-white p-6 rounded-lg shadow h-full">
<h2 class="text-xl font-semibold mb-4">3D Preview</h2>
<div id="preview-container" class="w-full h-96 bg-gray-200 rounded-lg"></div>

<!-- Preview Controls -->


<div class="flex justify-between mt-4">
<div>
<button id="rotate-left" class="bg-gray-200 px-4 py-2 rounded
hover:bg-gray-300">
Rotate Left
</button>
<button id="rotate-right" class="bg-gray-200 px-4 py-2 rounded
hover:bg-gray-300">
Rotate Right
</button>
</div>
<div>
<button id="download-model" class="bg-blue-600 text-white px-4 py-2
rounded hover:bg-blue-700">
Download Model
</button>
</div>
</div>
</div>
</div>
</div>

<!-- Sustainability Metrics -->


<div class="mt-6 bg-white p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Sustainability Metrics</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-center">
<div class="border rounded-lg p-4">
<h3 class="font-medium">Carbon Footprint</h3>
<p id="carbon-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">kg CO₂ equivalent</p>
</div>
<div class="border rounded-lg p-4">
<h3 class="font-medium">Recyclability Score</h3>
<p id="recyclability-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">out of 100</p>
</div>
<div class="border rounded-lg p-4">
<h3 class="font-medium">Water Usage</h3>
<p id="water-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">liters</p>
</div>
</div>
</div>
</div>

<script src="ecopackgen.js"></script>
</body>
</html>
5. JavaScript Implementation

Create the ecopackgen.js file with the following code for API integration:

// EcoPackGEN API Integration

// API Configuration
const API_ENDPOINT = 'https://api.ecopackgen.com/v1/generate';
const API_KEY = 'YOUR_API_KEY_HERE'; // Replace with your actual API key

// Global variables
let scene, camera, renderer, controls, currentModel;
const previewContainer = document.getElementById('preview-container');

// Initialize 3D scene
function initScene() {
// Create scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);

// Set up camera
camera = new THREE.PerspectiveCamera(
45,
previewContainer.clientWidth / previewContainer.clientHeight,
0.1,
1000
);
camera.position.set(0, 0, 50);

// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);


directionalLight.position.set(0, 10, 10);
scene.add(directionalLight);

// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(previewContainer.clientWidth, previewContainer.clientHeight);
previewContainer.appendChild(renderer.domElement);

// Controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;

// Handle window resize


window.addEventListener('resize', onWindowResize);

// Start animation loop


animate();
}

// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}

// Handle window resize


function onWindowResize() {
camera.aspect = previewContainer.clientWidth / previewContainer.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(previewContainer.clientWidth, previewContainer.clientHeight);
}

// Load 3D model from API response


function loadModel(modelData) {
// Remove existing model if any
if (currentModel) {
scene.remove(currentModel);
}

const loader = new THREE.GLTFLoader();

// Convert base64 to blob URL if needed


let modelUrl;
if (modelData.startsWith('data:')) {
const byteString = atob(modelData.split(',')[1]);
const mimeString = modelData.split(',')[0].split(':')[1].split(';')[0];
const arrayBuffer = new ArrayBuffer(byteString.length);
const intArray = new Uint8Array(arrayBuffer);

for (let i = 0; i < byteString.length; i++) {


intArray[i] = byteString.charCodeAt(i);
}
const blob = new Blob([arrayBuffer], { type: mimeString });
modelUrl = URL.createObjectURL(blob);
} else {
modelUrl = modelData;
}

// Load the model


loader.load(
modelUrl,
(gltf) => {
currentModel = gltf.scene;

// Center model
const box = new THREE.Box3().setFromObject(currentModel);
const center = box.getCenter(new THREE.Vector3());
currentModel.position.sub(center);

// Add to scene
scene.add(currentModel);

// Adjust camera position


const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
camera.position.set(0, 0, maxDim * 2.5);
controls.target.set(0, 0, 0);
controls.update();
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
(error) => {
console.error('Error loading model:', error);
alert('Failed to load 3D model. Please try again.');
}
);
}

// Generate package preview via API


async function generatePackagePreview(formData) {
try {
// Show loading state
previewContainer.innerHTML = '<div class="flex justify-center items-center
h-full"><p>Generating preview...</p></div>';
// Prepare form data for API
const apiData = {
dimensions: {
width: parseFloat(formData.width),
height: parseFloat(formData.height),
depth: parseFloat(formData.depth)
},
material: formData.material,
color: formData.color,
logo: formData.logo // Base64 encoded image data
};

// Make API request


const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify(apiData)
});

if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}

const data = await response.json();

// Reinitialize the 3D scene


previewContainer.innerHTML = '';
initScene();

// Load the generated model


loadModel(data.modelUrl);

// Update sustainability metrics


updateSustainabilityMetrics(data.sustainabilityMetrics);

// Store download URL


document.getElementById('download-model').dataset.downloadUrl = data.downloadUrl;

} catch (error) {
console.error('Error generating preview:', error);
previewContainer.innerHTML = `<div class="flex justify-center items-center h-full">
<p class="text-red-600">Error: ${error.message}</p>
</div>`;
}
}

// Update sustainability metrics


function updateSustainabilityMetrics(metrics) {
if (metrics) {
document.getElementById('carbon-metric').textContent =
metrics.carbonFootprint.toFixed(2);
document.getElementById('recyclability-metric').textContent = metrics.recyclabilityScore;
document.getElementById('water-metric').textContent = metrics.waterUsage.toFixed(1);
}
}

// Convert file to base64


function fileToBase64(file) {
return new Promise((resolve, reject) => {
if (!file) {
resolve(null);
return;
}

const reader = new FileReader();


reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}

// Event Listeners
document.addEventListener('DOMContentLoaded', function() {
// Initialize preview with default cube
initScene();

// Create a default cube


const geometry = new THREE.BoxGeometry(10, 15, 5);
const material = new THREE.MeshStandardMaterial({ color: 0x8B5A2B });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
currentModel = cube;

// Form submission
document.getElementById('packageForm').addEventListener('submit', async function(e) {
e.preventDefault();

const formData = {
width: document.getElementById('width').value,
height: document.getElementById('height').value,
depth: document.getElementById('depth').value,
material: document.getElementById('material').value,
color: document.getElementById('color').value,
logo: await fileToBase64(document.getElementById('logo').files[0])
};

generatePackagePreview(formData);
});

// Rotation controls
document.getElementById('rotate-left').addEventListener('click', function() {
if (currentModel) {
currentModel.rotation.y -= Math.PI / 4;
}
});

document.getElementById('rotate-right').addEventListener('click', function() {
if (currentModel) {
currentModel.rotation.y += Math.PI / 4;
}
});

// Download model button


document.getElementById('download-model').addEventListener('click', function() {
const downloadUrl = this.dataset.downloadUrl;
if (downloadUrl) {
window.open(downloadUrl, '_blank');
} else {
alert('No model available for download yet. Generate a preview first.');
}
});
});

6. Additional CSS Styling (Optional)

If you need additional styling beyond Tailwind, add it to your styles.css file:
/* Additional custom styles */
#preview-container canvas {
border-radius: 0.5rem;
}

.loading-spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
width: 36px;
height: 36px;
border-radius: 50%;
border-left-color: #09f;
animation: spin 1s linear infinite;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

7. Testing Your Integration

1.​ Replace 'YOUR_API_KEY_HERE' with your actual EcoPackGEN API key


2.​ Host your files on a web server or use a local development server
3.​ Open the application in your browser and test the form functionality

8. Troubleshooting

●​ CORS Issues: If you encounter CORS errors, make sure your API key has proper
permissions
●​ Loading Errors: Check browser console for specific error messages
●​ Model Rendering Issues: Ensure Three.js and GLTFLoader are properly loaded

9. Advanced Features (Optional)

Add Package Template Selection

Enhance the form with predefined templates:

<!-- Add this to your form -->


<div>
<label class="block font-medium mb-2">Template Style</label>
<select id="template" class="w-full border rounded px-3 py-2">
<option value="standard-box">Standard Box</option>
<option value="pillow-box">Pillow Box</option>
<option value="tuck-top">Tuck Top Box</option>
<option value="mailer">Eco Mailer</option>
</select>
</div>

Then update your JavaScript to include the template in the API request:

const apiData = {
// ... existing data
template: formData.template
};

Environmental Impact Report

Add a button to generate a detailed environmental impact report:

<!-- Add below the sustainability metrics -->


<div class="mt-4 text-center">
<button id="generate-report" class="bg-green-600 text-white px-6 py-2 rounded
hover:bg-green-700">
Generate Environmental Impact Report
</button>
</div>

Add the corresponding JavaScript:

document.getElementById('generate-report').addEventListener('click', async function() {


try {
const response = await fetch(`${API_ENDPOINT}/report`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({
packageId: currentPackageId // You'll need to store this from the original response
})
});

if (!response.ok) throw new Error('Failed to generate report');


const reportData = await response.json();
// Open report in new window or display in modal
window.open(reportData.reportUrl, '_blank');
} catch (error) {
console.error('Error generating report:', error);
alert('Failed to generate environmental impact report');
}
});

10. Production Considerations

Before deploying to production:

1.​ Security: Never expose your API key in client-side code. Use a backend proxy to make
API calls.
2.​ Error Handling: Implement comprehensive error handling and user feedback.
3.​ Loading States: Add loading indicators for all asynchronous operations.
4.​ Optimization: Optimize 3D models and textures for web performance.
5.​ Accessibility: Ensure your UI is accessible to all users.

This completes the basic integration guide for the EcoPackGEN Packaging Preview API. For
more advanced features or customization options, refer to the official API documentation.

EcoPackGEN API Integration Guide


This guide explains how to integrate the EcoPackGEN Packaging Preview API into your
frontend application step-by-step.

Setup Instructions
1. Prerequisites

Before you begin, make sure you have:

●​ Basic knowledge of HTML, CSS, and JavaScript


●​ A web server or development environment to serve your files
●​ Access to the EcoPackGEN API (credentials if needed)

2. File Structure Setup

Create the following files in your project directory:


your-project/
├── index.html # Main HTML file with form and UI components
├── ecopackgen.js # JavaScript file with API integration
└── styles.css # Optional: Additional styling if needed

3. Adding Dependencies

The implementation needs these external libraries:

●​ Three.js - For 3D rendering


●​ GLTFLoader - For loading 3D models
●​ OrbitControls - For interacting with 3D models
●​ Tailwind CSS - For styling UI components

4. HTML Structure

In your index.html file, set up the basic structure including the form elements and 3D viewer
container:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EcoPackGEN Integration</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-6 text-center">EcoPackGEN Packaging Preview</h1>

<div class="grid grid-cols-1 md:grid-cols-3 gap-6">


<!-- Configuration Panel -->
<div class="col-span-1 bg-white p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Package Configuration</h2>

<form id="packageForm" class="space-y-4">


<!-- Dimensions -->
<div>
<h3 class="font-medium mb-2">Dimensions (cm)</h3>
<div class="grid grid-cols-3 gap-2">
<div>
<label class="block text-sm">Width</label>
<input type="number" id="width" class="w-full border rounded px-3 py-2"
value="10" min="1">
</div>
<div>
<label class="block text-sm">Height</label>
<input type="number" id="height" class="w-full border rounded px-3 py-2"
value="15" min="1">
</div>
<div>
<label class="block text-sm">Depth</label>
<input type="number" id="depth" class="w-full border rounded px-3 py-2"
value="5" min="1">
</div>
</div>
</div>

<!-- Material Selection -->


<div>
<label class="block font-medium mb-2">Material</label>
<select id="material" class="w-full border rounded px-3 py-2">
<option value="recycled-cardboard">Recycled Cardboard</option>
<option value="corrugated-kraft">Corrugated Kraft</option>
<option value="biodegradable-plastic">Biodegradable Plastic</option>
<option value="mushroom-packaging">Mushroom Packaging</option>
</select>
</div>

<!-- Color Picker -->


<div>
<label class="block font-medium mb-2">Color</label>
<input type="color" id="color" class="w-full h-10 border rounded"
value="#8B5A2B">
</div>

<!-- Logo Upload -->


<div>
<label class="block font-medium mb-2">Logo (optional)</label>
<input type="file" id="logo" class="w-full border rounded px-3 py-2"
accept="image/*">
</div>

<!-- Submit Button -->


<button type="submit" class="w-full bg-green-600 text-white font-medium py-2 px-4
rounded hover:bg-green-700 transition-colors">
Generate Preview
</button>
</form>
</div>

<!-- 3D Preview Panel -->


<div class="col-span-2">
<div class="bg-white p-6 rounded-lg shadow h-full">
<h2 class="text-xl font-semibold mb-4">3D Preview</h2>
<div id="preview-container" class="w-full h-96 bg-gray-200 rounded-lg"></div>

<!-- Preview Controls -->


<div class="flex justify-between mt-4">
<div>
<button id="rotate-left" class="bg-gray-200 px-4 py-2 rounded
hover:bg-gray-300">
Rotate Left
</button>
<button id="rotate-right" class="bg-gray-200 px-4 py-2 rounded
hover:bg-gray-300">
Rotate Right
</button>
</div>
<div>
<button id="download-model" class="bg-blue-600 text-white px-4 py-2
rounded hover:bg-blue-700">
Download Model
</button>
</div>
</div>
</div>
</div>
</div>

<!-- Sustainability Metrics -->


<div class="mt-6 bg-white p-6 rounded-lg shadow">
<h2 class="text-xl font-semibold mb-4">Sustainability Metrics</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-center">
<div class="border rounded-lg p-4">
<h3 class="font-medium">Carbon Footprint</h3>
<p id="carbon-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">kg CO₂ equivalent</p>
</div>
<div class="border rounded-lg p-4">
<h3 class="font-medium">Recyclability Score</h3>
<p id="recyclability-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">out of 100</p>
</div>
<div class="border rounded-lg p-4">
<h3 class="font-medium">Water Usage</h3>
<p id="water-metric" class="text-2xl font-bold text-green-600">--</p>
<p class="text-sm text-gray-500">liters</p>
</div>
</div>
</div>
</div>

<script src="ecopackgen.js"></script>
</body>
</html>

5. JavaScript Implementation

Create the ecopackgen.js file with the following code for API integration:

// EcoPackGEN API Integration

// API Configuration
const API_ENDPOINT = 'https://api.ecopackgen.com/v1/generate';
const API_KEY = 'YOUR_API_KEY_HERE'; // Replace with your actual API key

// Global variables
let scene, camera, renderer, controls, currentModel;
const previewContainer = document.getElementById('preview-container');

// Initialize 3D scene
function initScene() {
// Create scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// Set up camera
camera = new THREE.PerspectiveCamera(
45,
previewContainer.clientWidth / previewContainer.clientHeight,
0.1,
1000
);
camera.position.set(0, 0, 50);

// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);


directionalLight.position.set(0, 10, 10);
scene.add(directionalLight);

// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(previewContainer.clientWidth, previewContainer.clientHeight);
previewContainer.appendChild(renderer.domElement);

// Controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;

// Handle window resize


window.addEventListener('resize', onWindowResize);

// Start animation loop


animate();
}

// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}

// Handle window resize


function onWindowResize() {
camera.aspect = previewContainer.clientWidth / previewContainer.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(previewContainer.clientWidth, previewContainer.clientHeight);
}

// Load 3D model from API response


function loadModel(modelData) {
// Remove existing model if any
if (currentModel) {
scene.remove(currentModel);
}

const loader = new THREE.GLTFLoader();

// Convert base64 to blob URL if needed


let modelUrl;
if (modelData.startsWith('data:')) {
const byteString = atob(modelData.split(',')[1]);
const mimeString = modelData.split(',')[0].split(':')[1].split(';')[0];
const arrayBuffer = new ArrayBuffer(byteString.length);
const intArray = new Uint8Array(arrayBuffer);

for (let i = 0; i < byteString.length; i++) {


intArray[i] = byteString.charCodeAt(i);
}

const blob = new Blob([arrayBuffer], { type: mimeString });


modelUrl = URL.createObjectURL(blob);
} else {
modelUrl = modelData;
}

// Load the model


loader.load(
modelUrl,
(gltf) => {
currentModel = gltf.scene;

// Center model
const box = new THREE.Box3().setFromObject(currentModel);
const center = box.getCenter(new THREE.Vector3());
currentModel.position.sub(center);

// Add to scene
scene.add(currentModel);

// Adjust camera position


const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
camera.position.set(0, 0, maxDim * 2.5);
controls.target.set(0, 0, 0);
controls.update();
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
(error) => {
console.error('Error loading model:', error);
alert('Failed to load 3D model. Please try again.');
}
);
}

// Generate package preview via API


async function generatePackagePreview(formData) {
try {
// Show loading state
previewContainer.innerHTML = '<div class="flex justify-center items-center
h-full"><p>Generating preview...</p></div>';

// Prepare form data for API


const apiData = {
dimensions: {
width: parseFloat(formData.width),
height: parseFloat(formData.height),
depth: parseFloat(formData.depth)
},
material: formData.material,
color: formData.color,
logo: formData.logo // Base64 encoded image data
};

// Make API request


const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify(apiData)
});

if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}

const data = await response.json();

// Reinitialize the 3D scene


previewContainer.innerHTML = '';
initScene();

// Load the generated model


loadModel(data.modelUrl);

// Update sustainability metrics


updateSustainabilityMetrics(data.sustainabilityMetrics);

// Store download URL


document.getElementById('download-model').dataset.downloadUrl = data.downloadUrl;

} catch (error) {
console.error('Error generating preview:', error);
previewContainer.innerHTML = `<div class="flex justify-center items-center h-full">
<p class="text-red-600">Error: ${error.message}</p>
</div>`;
}
}

// Update sustainability metrics


function updateSustainabilityMetrics(metrics) {
if (metrics) {
document.getElementById('carbon-metric').textContent =
metrics.carbonFootprint.toFixed(2);
document.getElementById('recyclability-metric').textContent = metrics.recyclabilityScore;
document.getElementById('water-metric').textContent = metrics.waterUsage.toFixed(1);
}
}

// Convert file to base64


function fileToBase64(file) {
return new Promise((resolve, reject) => {
if (!file) {
resolve(null);
return;
}

const reader = new FileReader();


reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}

// Event Listeners
document.addEventListener('DOMContentLoaded', function() {
// Initialize preview with default cube
initScene();

// Create a default cube


const geometry = new THREE.BoxGeometry(10, 15, 5);
const material = new THREE.MeshStandardMaterial({ color: 0x8B5A2B });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
currentModel = cube;

// Form submission
document.getElementById('packageForm').addEventListener('submit', async function(e) {
e.preventDefault();

const formData = {
width: document.getElementById('width').value,
height: document.getElementById('height').value,
depth: document.getElementById('depth').value,
material: document.getElementById('material').value,
color: document.getElementById('color').value,
logo: await fileToBase64(document.getElementById('logo').files[0])
};

generatePackagePreview(formData);
});

// Rotation controls
document.getElementById('rotate-left').addEventListener('click', function() {
if (currentModel) {
currentModel.rotation.y -= Math.PI / 4;
}
});

document.getElementById('rotate-right').addEventListener('click', function() {
if (currentModel) {
currentModel.rotation.y += Math.PI / 4;
}
});

// Download model button


document.getElementById('download-model').addEventListener('click', function() {
const downloadUrl = this.dataset.downloadUrl;
if (downloadUrl) {
window.open(downloadUrl, '_blank');
} else {
alert('No model available for download yet. Generate a preview first.');
}
});
});

6. Additional CSS Styling (Optional)

If you need additional styling beyond Tailwind, add it to your styles.css file:

/* Additional custom styles */


#preview-container canvas {
border-radius: 0.5rem;
}

.loading-spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
width: 36px;
height: 36px;
border-radius: 50%;
border-left-color: #09f;
animation: spin 1s linear infinite;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
7. Testing Your Integration

1.​ Replace 'YOUR_API_KEY_HERE' with your actual EcoPackGEN API key


2.​ Host your files on a web server or use a local development server
3.​ Open the application in your browser and test the form functionality

8. Troubleshooting

●​ CORS Issues: If you encounter CORS errors, make sure your API key has proper
permissions
●​ Loading Errors: Check browser console for specific error messages
●​ Model Rendering Issues: Ensure Three.js and GLTFLoader are properly loaded

9. Advanced Features (Optional)

Add Package Template Selection

Enhance the form with predefined templates:

<!-- Add this to your form -->


<div>
<label class="block font-medium mb-2">Template Style</label>
<select id="template" class="w-full border rounded px-3 py-2">
<option value="standard-box">Standard Box</option>
<option value="pillow-box">Pillow Box</option>
<option value="tuck-top">Tuck Top Box</option>
<option value="mailer">Eco Mailer</option>
</select>
</div>

Then update your JavaScript to include the template in the API request:

const apiData = {
// ... existing data
template: formData.template
};

Environmental Impact Report

Add a button to generate a detailed environmental impact report:

<!-- Add below the sustainability metrics -->


<div class="mt-4 text-center">
<button id="generate-report" class="bg-green-600 text-white px-6 py-2 rounded
hover:bg-green-700">
Generate Environmental Impact Report
</button>
</div>

Add the corresponding JavaScript:

document.getElementById('generate-report').addEventListener('click', async function() {


try {
const response = await fetch(`${API_ENDPOINT}/report`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({
packageId: currentPackageId // You'll need to store this from the original response
})
});

if (!response.ok) throw new Error('Failed to generate report');

const reportData = await response.json();


// Open report in new window or display in modal
window.open(reportData.reportUrl, '_blank');
} catch (error) {
console.error('Error generating report:', error);
alert('Failed to generate environmental impact report');
}
});

10. Production Considerations

Before deploying to production:

1.​ Security: Never expose your API key in client-side code. Use a backend proxy to make
API calls.
2.​ Error Handling: Implement comprehensive error handling and user feedback.
3.​ Loading States: Add loading indicators for all asynchronous operations.
4.​ Optimization: Optimize 3D models and textures for web performance.
5.​ Accessibility: Ensure your UI is accessible to all users.
This completes the basic integration guide for the EcoPackGEN Packaging Preview API. For
more advanced features or customization options, refer to the official API documentation.

You might also like