Ayeeee45's picture
Fix preview page not generating face swaps
7281673 verified
// Shared functions
function openImageEditor(imageSrc) {
const editor = document.querySelector('custom-image-editor');
if (editor) {
editor.style.display = 'flex';
// In a real app, this would load the image into the canvas
}
}
function generateFaceSwap() {
const resultsContainer = document.getElementById('results-container');
const selectedImages = document.querySelectorAll('#image-preview img');
const faceSelection = document.querySelectorAll('#face-selection .ring-purple-600');
if (selectedImages.length < 2) {
alert('Please upload at least 2 images for face swapping');
return;
}
if (faceSelection.length < 2) {
alert('Please select at least 2 faces to swap');
return;
}
// Show loading state
resultsContainer.innerHTML = `
<div class="col-span-4 text-center py-12">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-600 mx-auto mb-4"></div>
<p>Generating face swaps...</p>
</div>
`;
// Get the source images for reference
const sourceImages = Array.from(selectedImages).map(img => img.src);
// Simulate API call delay
setTimeout(() => {
// Generate mock results using the selected faces
resultsContainer.innerHTML = '';
// Get the selected face IDs
const selectedFaceIds = Array.from(faceSelection).map(face => face.dataset.faceId);
// Create 4 different combinations
for (let i = 0; i < 4; i++) {
const resultItem = document.createElement('div');
resultItem.className = 'bg-white rounded-xl shadow-md overflow-hidden group';
// Use the selected face IDs in the image URL for consistency
const faceId1 = selectedFaceIds[0];
const faceId2 = selectedFaceIds[i % selectedFaceIds.length] || selectedFaceIds[1];
// Calculate a seed based on the source images and face IDs
const seed = (sourceImages.join('').length + parseInt(faceId1) + parseInt(faceId2)) % 1000;
resultItem.innerHTML = `
<img src="http://static.photos/people/640x360/${seed}"
class="w-full h-full object-cover transition group-hover:scale-105 cursor-pointer"
alt="Face swap result ${i+1}"
onclick="openImageEditor(this.src)">
<div class="p-3">
<h3 class="font-semibold">Result #${i+1}</h3>
<div class="flex justify-between items-center mt-2">
<button class="text-purple-600 hover:text-purple-800 text-sm flex items-center" onclick="downloadImage(this)">
<i data-feather="download" class="w-4 h-4 mr-1"></i>
Download
</button>
<button class="text-purple-600 hover:text-purple-800 text-sm flex items-center" onclick="openImageEditor(this.parentElement.parentElement.querySelector('img').src)">
<i data-feather="edit" class="w-4 h-4 mr-1"></i>
Edit
</button>
</div>
</div>
`;
resultsContainer.appendChild(resultItem);
}
if (typeof feather !== 'undefined') {
feather.replace();
}
}, 2000);
}
function downloadImage(button) {
const img = button.closest('div').querySelector('img');
const link = document.createElement('a');
link.href = img.src;
link.download = `face-swap-${Date.now()}.jpg`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
document.addEventListener('DOMContentLoaded', function() {
// Initialize feather icons
if (typeof feather !== 'undefined') {
feather.replace();
}
// Add event listener to generate button
const generateBtn = document.querySelector('main button:has(i[data-feather="refresh-cw"])');
if (generateBtn) {
generateBtn.addEventListener('click', function(e) {
e.preventDefault();
generateFaceSwap();
});
}
// Enable face selection on image click
document.addEventListener('click', function(e) {
if (e.target.closest('#image-preview img')) {
const imgSrc = e.target.src;
// In a real app, this would trigger face detection on the clicked image
console.log('Image clicked for face detection:', imgSrc);
}
});
// Initialize face detection and selection
const faceSelection = document.getElementById('face-selection');
// This would be replaced with actual face detection logic
// For demo purposes, we'll create mock faces when images are uploaded
const fileInput = document.getElementById('file-input');
if (fileInput) {
fileInput.addEventListener('change', function() {
const mockFaces = [];
const numFaces = Math.floor(Math.random() * 4) + 1; // 1-4 faces per image
for (let i = 1; i <= numFaces; i++) {
const colors = ['bg-red-400', 'bg-blue-400', 'bg-green-400', 'bg-yellow-400'];
mockFaces.push({
id: i,
name: `Face ${i}`,
color: colors[i % colors.length]
});
}
// Clear existing faces
faceSelection.innerHTML = '';
mockFaces.forEach(face => {
const faceElement = document.createElement('div');
faceElement.className = `flex items-center justify-center w-16 h-16 rounded-full ${face.color} text-white cursor-pointer hover:opacity-80 transition`;
faceElement.textContent = face.name;
faceElement.dataset.faceId = face.id;
faceElement.addEventListener('click', function() {
this.classList.toggle('ring-2');
this.classList.toggle('ring-purple-600');
});
faceSelection.appendChild(faceElement);
});
});
}
// Clear existing faces
faceSelection.innerHTML = '';
mockFaces.forEach(face => {
const faceElement = document.createElement('div');
faceElement.className = `flex items-center justify-center w-16 h-16 rounded-full ${face.color} text-white cursor-pointer hover:opacity-80 transition`;
faceElement.textContent = face.name;
faceElement.dataset.faceId = face.id;
faceElement.addEventListener('click', function() {
this.classList.toggle('ring-2');
this.classList.toggle('ring-purple-600');
});
faceSelection.appendChild(faceElement);
});
// Clear results when new images are uploaded
const fileInput = document.getElementById('file-input');
if (fileInput) {
fileInput.addEventListener('change', function() {
const resultsContainer = document.getElementById('results-container');
if (resultsContainer) {
resultsContainer.innerHTML = `
<div class="text-center text-gray-500 py-12 col-span-4">
<i data-feather="image" class="w-12 h-12 mx-auto mb-2"></i>
<p>Your face swaps will appear here</p>
</div>
`;
if (typeof feather !== 'undefined') {
feather.replace();
}
}
});
}
// Image upload functionality
const uploadArea = document.getElementById('upload-area');
const fileInput = document.getElementById('file-input');
const imagePreview = document.getElementById('image-preview');
// Handle file selection
fileInput.addEventListener('change', function(e) {
handleFiles(e.target.files);
});
// Handle drag and drop
uploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
uploadArea.classList.add('border-purple-500', 'bg-purple-50');
});
uploadArea.addEventListener('dragleave', function() {
uploadArea.classList.remove('border-purple-500', 'bg-purple-50');
});
uploadArea.addEventListener('drop', function(e) {
e.preventDefault();
uploadArea.classList.remove('border-purple-500', 'bg-purple-50');
if (e.dataTransfer.files.length) {
handleFiles(e.dataTransfer.files);
}
});
function handleFiles(files) {
// Process each file
Array.from(files).forEach(file => {
if (!file.type.match('image.*')) return;
const reader = new FileReader();
reader.onload = function(e) {
// Create container for the image and remove button
const container = document.createElement('div');
container.className = 'relative group';
// Create image element
const img = document.createElement('img');
img.src = e.target.result;
img.alt = file.name;
img.className = 'w-full h-full object-cover rounded-lg';
// Create remove button
const removeBtn = document.createElement('button');
removeBtn.className = 'absolute top-2 right-2 bg-red-500 text-white rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity';
removeBtn.innerHTML = '<i data-feather="x"></i>';
removeBtn.addEventListener('click', () => {
container.remove();
if (typeof feather !== 'undefined') {
feather.replace();
}
});
container.appendChild(img);
container.appendChild(removeBtn);
imagePreview.appendChild(container);
if (typeof feather !== 'undefined') {
feather.replace();
}
};
reader.readAsDataURL(file);
});
}
// Drag and drop functionality would go here
});