Natkat1's picture
Error: backgroundRemoval is not defined
e8333f6 verified
import { removeBackground } from "https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.0.0/dist/index.mjs";
document.addEventListener('DOMContentLoaded', () => {
const dropArea = document.getElementById('drop-area');
const fileInput = document.getElementById('file-input');
const browseBtn = document.getElementById('browse-btn');
const uploadUI = document.getElementById('upload-ui');
const processingUI = document.getElementById('processing-ui');
const originalImage = document.getElementById('original-image');
const resultImage = document.getElementById('result-image');
const downloadBtn = document.getElementById('download-btn');
const downloadSection = document.getElementById('download-section');
const progressText = document.getElementById('progress-text');
const progressBar = document.getElementById('progress-bar');
const firstRunNotice = document.getElementById('first-run-notice');
let isFirstRun = true;
let processing = false;
let currentFile = null;
// Prevent default drag behaviors
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// Highlight drop area when item is dragged over it
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dropArea.classList.add('highlight');
}
function unhighlight() {
dropArea.classList.remove('highlight');
}
// Handle dropped files
dropArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length && !processing) {
handleFiles(files);
}
}
// Handle file input
fileInput.addEventListener('change', function() {
if (this.files.length && !processing) {
handleFiles(this.files);
}
});
// Browse button click
browseBtn.addEventListener('click', () => {
fileInput.click();
});
// Handle file processing
async function handleFiles(files) {
const file = files[0];
if (!file.type.match('image.*')) {
alert('Please select an image file');
return;
}
currentFile = file;
processing = true;
// Show original image
const reader = new FileReader();
reader.onload = function(e) {
originalImage.src = e.target.result;
originalImage.classList.remove('hidden');
};
reader.readAsDataURL(file);
// Show processing UI
uploadUI.classList.add('hidden');
processingUI.classList.remove('hidden');
if (isFirstRun) {
progressText.textContent = 'Loading models for the first time (20-40MB)...';
progressBar.style.width = '10%';
} else {
progressText.textContent = 'Processing image...';
progressBar.style.width = '30%';
}
try {
// Initialize the background removal
const blobURL = URL.createObjectURL(file);
// Revoke the blob URL after use to prevent memory leaks
setTimeout(() => URL.revokeObjectURL(blobURL), 1000);
const progressCallback = (progress) => {
const percent = Math.floor(progress * 100);
progressBar.style.width = `${percent}%`;
if (isFirstRun) {
if (progress < 0.9) {
progressText.textContent = `Downloading models... ${percent}%`;
} else {
progressText.textContent = 'Processing image...';
}
} else {
progressText.textContent = `Processing... ${percent}%`;
}
};
// Convert file to Blob URL
const blob = await fetch(blobURL).then(r => r.blob());
// Use the imported removeBackground function
const result = await removeBackground(blob, {
progress: progressCallback,
publicPath: 'https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.0.0/dist/', // Required for loading models
debug: true
});
// Convert Blob to URL for display
// Convert result to PNG if it's not already
const pngBlob = await result.convertToBlob('image/png');
const resultURL = URL.createObjectURL(pngBlob);
// Display result
resultImage.src = resultURL;
resultImage.classList.remove('hidden');
// Enable download button
downloadBtn.onclick = function() {
const a = document.createElement('a');
a.href = resultURL;
a.download = `background-removed-${file.name}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(() => URL.revokeObjectURL(resultURL), 100);
};
downloadSection.classList.remove('hidden');
// Reset UI
processing = false;
uploadUI.classList.remove('hidden');
processingUI.classList.add('hidden');
if (isFirstRun) {
isFirstRun = false;
firstRunNotice.classList.add('hidden');
}
} catch (error) {
console.error('Error during background removal:', error);
// Show error message
progressText.textContent = `Error: ${error.message || 'Failed to process image'}`;
progressBar.style.width = '0%';
progressBar.classList.add('bg-red-500');
// Show retry button
const retryBtn = document.createElement('button');
retryBtn.className = 'bg-primary-500 hover:bg-primary-600 text-white font-medium py-2 px-6 rounded-lg transition-colors duration-200 mt-4';
retryBtn.textContent = 'Try Again';
retryBtn.onclick = () => {
if (currentFile) {
handleFiles([currentFile]);
}
};
processingUI.querySelector('.flex').appendChild(retryBtn);
setTimeout(() => {
// Reset UI if user doesn't retry
processing = false;
uploadUI.classList.remove('hidden');
processingUI.classList.add('hidden');
progressBar.classList.remove('bg-red-500');
if (processingUI.contains(retryBtn)) {
processingUI.querySelector('.flex').removeChild(retryBtn);
}
}, 8000);
}
}
});