NzService's picture
Add 3 files
3cbe03e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PixelConvert Pro - Advanced Image Converter</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #f59e0b;
--dark: #1e293b;
--light: #f8fafc;
}
body {
font-family: 'Poppins', sans-serif;
background: #f1f5f9;
}
.dropzone {
border: 2px dashed #94a3b8;
transition: all 0.3s ease;
}
.dropzone.active {
border-color: var(--primary);
background-color: rgba(99, 102, 241, 0.05);
}
.file-card {
transition: all 0.3s ease;
}
.file-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.progress-bar {
transition: width 0.5s ease;
}
#previewModal {
transition: opacity 0.3s ease, transform 0.3s ease;
opacity: 0;
transform: scale(0.9);
pointer-events: none;
}
#previewModal.active {
opacity: 1;
transform: scale(1);
pointer-events: auto;
}
.format-option {
transition: all 0.2s ease;
}
.format-option:hover {
background-color: #e2e8f0;
}
.tooltip {
position: relative;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 200px;
background-color: #1e293b;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style>
</head>
<body class="min-h-screen">
<div class="bg-indigo-600 text-white">
<div class="container mx-auto px-4 py-4 flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fas fa-image fa-lg"></i>
<h1 class="text-xl font-bold">PixelConvert Pro</h1>
</div>
<div class="flex space-x-4">
<button class="px-4 py-2 bg-white text-indigo-600 rounded-md font-medium hover:bg-gray-100 transition">Sign In</button>
<button class="px-4 py-2 bg-indigo-700 rounded-md font-medium hover:bg-indigo-800 transition">Upgrade</button>
</div>
</div>
</div>
<div class="container mx-auto px-4 py-8">
<div class="text-center mb-10">
<h2 class="text-3xl font-bold text-gray-800 mb-2">Convert Any Image Format</h2>
<p class="text-gray-600 max-w-2xl mx-auto">Supporting 50+ formats including JPEG, PNG, TIFF, GIF, WEBP, SVG, PSD, AI and more. Secure, fast and easy to use.</p>
</div>
<div class="bg-white rounded-xl shadow-lg overflow-hidden mb-8">
<div class="p-6">
<div class="flex items-center mb-6 space-x-4">
<button id="uploadTab" class="px-4 py-2 bg-indigo-600 text-white rounded-md font-medium transition">Upload Files</button>
<button id="cloudTab" class="px-4 py-2 text-gray-600 rounded-md font-medium hover:bg-gray-100 transition">Cloud Services</button>
<button id="urlTab" class="px-4 py-2 text-gray-600 rounded-md font-medium hover:bg-gray-100 transition">From URL</button>
</div>
<!-- Upload Tab Content -->
<div id="uploadContent" class="block">
<div id="dropzone" class="dropzone rounded-lg p-12 text-center cursor-pointer">
<i class="fas fa-cloud-upload-alt text-4xl text-indigo-500 mb-4"></i>
<h3 class="text-lg font-medium text-gray-800 mb-2">Drag & drop your files here</h3>
<p class="text-gray-500 mb-4">or click to browse files</p>
<input type="file" id="fileInput" class="hidden" multiple>
<button id="browseBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md font-medium hover:bg-indigo-700 transition">Browse Files</button>
<p class="text-sm text-gray-500 mt-4">Supports: JPG, PNG, GIF, SVG, PSD, AI, TIFF, WEBP, HEIC, RAW and more</p>
<p class="text-xs text-gray-400 mt-2">Max file size: 1GB (Upgrade for larger files)</p>
</div>
</div>
<!-- Cloud Tab Content -->
<div id="cloudContent" class="hidden">
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 p-4">
<div class="p-4 border rounded-lg text-center cursor-pointer hover:bg-gray-50 transition">
<i class="fab fa-dropbox text-3xl text-blue-600 mb-2"></i>
<p class="font-medium">Dropbox</p>
</div>
<div class="p-4 border rounded-lg text-center cursor-pointer hover:bg-gray-50 transition">
<i class="fab fa-google-drive text-3xl text-blue-400 mb-2"></i>
<p class="font-medium">Google Drive</p>
</div>
<div class="p-4 border rounded-lg text-center cursor-pointer hover:bg-gray-50 transition">
<i class="fas fa-cloud text-3xl text-indigo-500 mb-2"></i>
<p class="font-medium">OneDrive</p>
</div>
<div class="p-4 border rounded-lg text-center cursor-pointer hover:bg-gray-50 transition">
<i class="fab fa-apple text-3xl text-gray-800 mb-2"></i>
<p class="font-medium">iCloud</p>
</div>
</div>
</div>
<!-- URL Tab Content -->
<div id="urlContent" class="hidden">
<div class="p-4">
<div class="flex">
<input type="text" placeholder="Enter image URL (https://example.com/image.jpg)" class="flex-1 px-4 py-2 border rounded-l-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
<button class="px-4 py-2 bg-indigo-600 text-white rounded-r-md font-medium hover:bg-indigo-700 transition">Add</button>
</div>
<p class="text-sm text-gray-500 mt-2">Supports direct links to images</p>
</div>
</div>
</div>
<div id="fileList" class="border-t px-6 py-4 hidden">
<div class="flex justify-between items-center mb-4">
<h3 class="font-medium text-gray-800">Selected Files</h3>
<div class="flex space-x-2">
<button id="clearAllBtn" class="px-3 py-1 text-sm text-red-500 hover:bg-red-50 rounded-md transition">Clear All</button>
<button id="convertAllBtn" class="px-3 py-1 text-sm bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition">Convert All</button>
</div>
</div>
<div id="filesContainer" class="space-y-3">
<!-- Files will be added here dynamically -->
</div>
</div>
</div>
<!-- Conversion Options -->
<div id="conversionOptions" class="bg-white rounded-xl shadow-lg p-6 mb-8 hidden">
<h3 class="font-bold text-lg text-gray-800 mb-4">Conversion Settings</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Format Selection -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Output Format</label>
<div class="relative">
<button id="formatDropdownBtn" class="w-full px-4 py-2 border rounded-md text-left flex justify-between items-center hover:bg-gray-50 transition">
<span>Select format</span>
<i class="fas fa-chevron-down"></i>
</button>
<div id="formatDropdown" class="absolute z-10 w-full mt-1 bg-white border rounded-md shadow-lg hidden max-h-96 overflow-y-auto">
<!-- Format groups -->
<div class="p-2">
<h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Raster Formats</h4>
<div class="space-y-1">
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="jpg">
<div>
<span class="font-medium">JPG</span>
<span class="text-xs text-gray-500 ml-2">Joint Photographic Experts Group</span>
</div>
<span class="text-xs bg-gray-100 px-2 py-1 rounded">Lossy</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="png">
<div>
<span class="font-medium">PNG</span>
<span class="text-xs text-gray-500 ml-2">Portable Network Graphics</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="gif">
<div>
<span class="font-medium">GIF</span>
<span class="text-xs text-gray-500 ml-2">Graphics Interchange Format</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="webp">
<div>
<span class="font-medium">WEBP</span>
<span class="text-xs text-gray-500 ml-2">Web Picture Format</span>
</div>
<span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded">Both</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="tiff">
<div>
<span class="font-medium">TIFF</span>
<span class="text-xs text-gray-500 ml-2">Tagged Image File Format</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="bmp">
<div>
<span class="font-medium">BMP</span>
<span class="text-xs text-gray-500 ml-2">Bitmap Image File</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="heic">
<div>
<span class="font-medium">HEIC</span>
<span class="text-xs text-gray-500 ml-2">High Efficiency Image Format</span>
</div>
<span class="text-xs bg-gray-100 px-2 py-1 rounded">Lossy</span>
</div>
</div>
</div>
<div class="border-t p-2">
<h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Vector Formats</h4>
<div class="space-y-1">
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="svg">
<div>
<span class="font-medium">SVG</span>
<span class="text-xs text-gray-500 ml-2">Scalable Vector Graphics</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="eps">
<div>
<span class="font-medium">EPS</span>
<span class="text-xs text-gray-500 ml-2">Encapsulated PostScript</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Lossless</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="pdf">
<div>
<span class="font-medium">PDF</span>
<span class="text-xs text-gray-500 ml-2">Portable Document Format</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Vector/Raster</span>
</div>
</div>
</div>
<div class="border-t p-2">
<h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Project Files</h4>
<div class="space-y-1">
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="psd">
<div>
<span class="font-medium">PSD</span>
<span class="text-xs text-gray-500 ml-2">Photoshop Document</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Project</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="ai">
<div>
<span class="font-medium">AI</span>
<span class="text-xs text-gray-500 ml-2">Adobe Illustrator Artwork</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Project</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="xcf">
<div>
<span class="font-medium">XCF</span>
<span class="text-xs text-gray-500 ml-2">GIMP Image File</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">Project</span>
</div>
</div>
</div>
<div class="border-t p-2">
<h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Raw Formats</h4>
<div class="space-y-1">
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="cr2">
<div>
<span class="font-medium">CR2</span>
<span class="text-xs text-gray-500 ml-2">Canon Raw Image File</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">RAW</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="nef">
<div>
<span class="font-medium">NEF</span>
<span class="text-xs text-gray-500 ml-2">Nikon Electronic Format</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">RAW</span>
</div>
<div class="format-option px-4 py-2 cursor-pointer flex justify-between items-center" data-format="arw">
<div>
<span class="font-medium">ARW</span>
<span class="text-xs text-gray-500 ml-2">Sony Alpha Raw File</span>
</div>
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">RAW</span>
</div>
</div>
</div>
</div>
</div>
<div id="selectedFormat" class="mt-2 text-sm font-medium text-indigo-600 hidden">
Selected: <span id="formatName"></span>
</div>
</div>
<!-- Quality Settings -->
<div class="format-dependent" data-dependent="jpg,webp,heic">
<label class="block text-sm font-medium text-gray-700 mb-1">Quality</label>
<div class="flex items-center space-x-4">
<input type="range" id="qualitySlider" min="1" max="100" value="90" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
<span id="qualityValue" class="text-sm text-gray-600 w-10 text-center">90%</span>
</div>
<div class="flex justify-between text-xs text-gray-500 mt-1">
<span>Smaller file</span>
<span>Better quality</span>
</div>
</div>
<!-- Resize Options -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Resize</label>
<div class="flex space-x-4">
<div class="flex-1">
<div class="relative">
<input type="number" id="widthInput" placeholder="Width" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500">
<div class="absolute right-3 top-2.5 text-gray-400">
px
</div>
</div>
</div>
<div class="flex-1">
<div class="relative">
<input type="number" id="heightInput" placeholder="Height" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500">
<div class="absolute right-3 top-2.5 text-gray-400">
px
</div>
</div>
</div>
</div>
<div class="mt-2 text-xs text-gray-500">Leave blank to maintain aspect ratio</div>
</div>
</div>
<!-- Advanced Options -->
<div class="mt-6">
<div class="flex items-center justify-between cursor-pointer" id="advancedToggle">
<h4 class="text-sm font-medium text-gray-700">Advanced Options</h4>
<i class="fas fa-chevron-down text-gray-500 transition-transform transform" id="advancedIcon"></i>
</div>
<div id="advancedOptions" class="hidden mt-4 space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Preserve Metadata -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Metadata</label>
<select class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500">
<option value="keep">Keep all metadata</option>
<option value="copyright">Keep only copyright</option>
<option value="remove">Remove all metadata</option>
</select>
</div>
<!-- Color Profile -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Color Profile</label>
<select class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500">
<option value="srgb">sRGB (web default)</option>
<option value="adobe-rgb">Adobe RGB</option>
<option value="cmyk">CMYK (for print)</option>
<option value="keep">Keep original</option>
</select>
</div>
</div>
<!-- DPI Setting -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">DPI (Resolution)</label>
<select class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500">
<option value="72">72 (web/email)</option>
<option value="150">150 (medium quality print)</option>
<option value="300">300 (high quality print)</option>
<option value="keep">Keep original</option>
</select>
</div>
</div>
</div>
<div class="mt-8 text-center">
<button id="applySettingsBtn" class="px-6 py-3 bg-indigo-600 text-white rounded-md font-medium hover:bg-indigo-700 transition">Apply Settings & Convert</button>
</div>
</div>
<!-- Results Section -->
<div id="resultsSection" class="bg-white rounded-xl shadow-lg p-6 mb-8 hidden">
<div class="flex justify-between items-center mb-6">
<h3 class="font-bold text-lg text-gray-800">Conversion Results</h3>
<button id="downloadAllBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md font-medium hover:bg-indigo-700 transition flex items-center space-x-2">
<i class="fas fa-download"></i>
<span>Download All</span>
</button>
</div>
<div id="resultsContainer" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Results will be added here dynamically -->
</div>
</div>
<!-- Security & Features Section -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="text-center mb-4">
<i class="fas fa-shield-alt text-3xl text-indigo-600 mb-3"></i>
<h3 class="font-bold text-lg text-gray-800 mb-2">Bank-Level Security</h3>
<p class="text-gray-600">256-bit SSL encryption protects your data during transfer. Files are automatically deleted after 1 hour.</p>
</div>
</div>
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="text-center mb-4">
<i class="fas fa-tachometer-alt text-3xl text-indigo-600 mb-3"></i>
<h3 class="font-bold text-lg text-gray-800 mb-2">Super Fast Conversion</h3>
<p class="text-gray-600">Our cloud-powered servers process files in seconds, even for large batches.</p>
</div>
</div>
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="text-center mb-4">
<i class="fas fa-star text-3xl text-indigo-600 mb-3"></i>
<h3 class="font-bold text-lg text-gray-800 mb-2">Quality Preservation</h3>
<p class="text-gray-600">Advanced algorithms maintain the highest possible quality during conversions.</p>
</div>
</div>
</div>
</div>
<!-- Preview Modal -->
<div id="previewModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
<div class="bg-white rounded-xl max-w-4xl w-full max-h-[90vh] flex flex-col">
<div class="flex justify-between items-center p-4 border-b">
<h3 class="font-bold text-lg">Image Preview</h3>
<button id="closePreviewBtn" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="flex-1 overflow-auto p-4 flex justify-center items-center">
<img id="previewImage" src="" alt="Preview" class="max-w-full max-h-[70vh]">
</div>
<div class="p-4 border-t">
<div class="flex justify-end space-x-3">
<button id="downloadPreviewBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition flex items-center space-x-2">
<i class="fas fa-download"></i>
<span>Download</span>
</button>
</div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-8">
<div class="container mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h4 class="font-bold text-lg mb-4">PixelConvert Pro</h4>
<p class="text-gray-400">The most advanced online image converter supporting 50+ formats with professional quality.</p>
</div>
<div>
<h4 class="font-bold text-lg mb-4">Formats</h4>
<ul class="space-y-2 text-gray-400">
<li><a href="#" class="hover:text-white transition">Raster Formats</a></li>
<li><a href="#" class="hover:text-white transition">Vector Formats</a></li>
<li><a href="#" class="hover:text-white transition">Project Files</a></li>
<li><a href="#" class="hover:text-white transition">Raw Camera Files</a></li>
</ul>
</div>
<div>
<h4 class="font-bold text-lg mb-4">Help</h4>
<ul class="space-y-2 text-gray-400">
<li><a href="#" class="hover:text-white transition">How to Convert</a></li>
<li><a href="#" class="hover:text-white transition">Supported Formats</a></li>
<li><a href="#" class="hover:text-white transition">Quality Settings</a></li>
<li><a href="#" class="hover:text-white transition">FAQ</a></li>
</ul>
</div>
<div>
<h4 class="font-bold text-lg mb-4">Legal</h4>
<ul class="space-y-2 text-gray-400">
<li><a href="#" class="hover:text-white transition">Privacy Policy</a></li>
<li><a href="#" class="hover:text-white transition">Terms of Service</a></li>
<li><a href="#" class="hover:text-white transition">Data Security</a></li>
<li><a href="#" class="hover:text-white transition">DMCA</a></li>
</ul>
</div>
</div>
<div class="border-t border-gray-700 mt-8 pt-6 text-center text-gray-400">
<p>© 2023 PixelConvert Pro. All rights reserved.</p>
</div>
</div>
</footer>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Variables
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
const browseBtn = document.getElementById('browseBtn');
const fileList = document.getElementById('fileList');
const filesContainer = document.getElementById('filesContainer');
const clearAllBtn = document.getElementById('clearAllBtn');
const convertAllBtn = document.getElementById('convertAllBtn');
const uploadTab = document.getElementById('uploadTab');
const cloudTab = document.getElementById('cloudTab');
const urlTab = document.getElementById('urlTab');
const uploadContent = document.getElementById('uploadContent');
const cloudContent = document.getElementById('cloudContent');
const urlContent = document.getElementById('urlContent');
const formatDropdownBtn = document.getElementById('formatDropdownBtn');
const formatDropdown = document.getElementById('formatDropdown');
const formatOptions = document.querySelectorAll('.format-option');
const selectedFormat = document.getElementById('selectedFormat');
const formatName = document.getElementById('formatName');
const conversionOptions = document.getElementById('conversionOptions');
const applySettingsBtn = document.getElementById('applySettingsBtn');
const resultsSection = document.getElementById('resultsSection');
const resultsContainer = document.getElementById('resultsContainer');
const downloadAllBtn = document.getElementById('downloadAllBtn');
const qualitySlider = document.getElementById('qualitySlider');
const qualityValue = document.getElementById('qualityValue');
const previewModal = document.getElementById('previewModal');
const closePreviewBtn = document.getElementById('closePreviewBtn');
const previewImage = document.getElementById('previewImage');
const downloadPreviewBtn = document.getElementById('downloadPreviewBtn');
const advancedToggle = document.getElementById('advancedToggle');
const advancedOptions = document.getElementById('advancedOptions');
const advancedIcon = document.getElementById('advancedIcon');
let files = [];
let selectedFiles = [];
let currentFormat = null;
let currentConversionOptions = {};
// Event Listeners
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.classList.add('active');
});
dropzone.addEventListener('dragleave', () => {
dropzone.classList.remove('active');
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.classList.remove('active');
handleFiles(e.dataTransfer.files);
});
browseBtn.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', () => {
if (fileInput.files.length > 0) {
handleFiles(fileInput.files);
}
});
clearAllBtn.addEventListener('click', clearAllFiles);
uploadTab.addEventListener('click', () => {
showTab(uploadContent, uploadTab, [cloudContent, urlContent], [cloudTab, urlTab]);
});
cloudTab.addEventListener('click', () => {
showTab(cloudContent, cloudTab, [uploadContent, urlContent], [uploadTab, urlTab]);
});
urlTab.addEventListener('click', () => {
showTab(urlContent, urlTab, [uploadContent, cloudContent], [uploadTab, cloudTab]);
});
formatDropdownBtn.addEventListener('click', toggleFormatDropdown);
formatOptions.forEach(option => {
option.addEventListener('click', () => {
selectFormat(option);
});
});
document.addEventListener('click', (e) => {
if (!formatDropdownBtn.contains(e.target) && !formatDropdown.contains(e.target)) {
formatDropdown.classList.add('hidden');
}
});
applySettingsBtn.addEventListener('click', convertFiles);
qualitySlider.addEventListener('input', updateQualityValue);
closePreviewBtn.addEventListener('click', closePreview);
downloadAllBtn.addEventListener('click', simulateDownloadAll);
advancedToggle.addEventListener('click', toggleAdvancedOptions);
// Functions
function handleFiles(newFiles) {
for (let i = 0; i < newFiles.length; i++) {
const file = newFiles[i];
// Check if file is already added
if (!files.some(f => f.name === file.name && f.size === file.size)) {
files.push(file);
}
}
if (files.length > 0) {
updateFileList();
fileList.classList.remove('hidden');
}
}
function updateFileList() {
filesContainer.innerHTML = '';
const sortable = new Sortable(filesContainer, {
animation: 150,
handle: '.handle',
ghostClass: 'opacity-50'
});
files.forEach((file, index) => {
const fileName = file.name.length > 30 ?
file.name.substring(0, 15) + '...' + file.name.substring(file.name.lastIndexOf('.')) :
file.name;
const fileSize = formatFileSize(file.size);
const fileExtension = file.name.split('.').pop().toUpperCase();
const fileCard = document.createElement('div');
fileCard.className = 'file-card bg-white border rounded-md p-3 flex items-center space-x-3 hover:shadow-md transition cursor-pointer';
fileCard.innerHTML = `
<div class="handle p-2 text-gray-400 hover:text-gray-600 cursor-move">
<i class="fas fa-arrows-alt"></i>
</div>
<div class="flex-shrink-0 w-10 h-10 rounded-md bg-indigo-50 flex items-center justify-center">
<span class="text-xs font-medium text-indigo-600">${fileExtension}</span>
</div>
<div class="flex-1 min-w-0">
<div class="flex justify-between">
<p class="text-sm font-medium text-gray-900 truncate">${fileName}</p>
<button class="file-remove text-gray-400 hover:text-red-500" data-index="${index}">
<i class="fas fa-times"></i>
</button>
</div>
<p class="text-xs text-gray-500">${fileSize}</p>
<div class="w-full bg-gray-200 rounded-full h-1.5 mt-1 hidden">
<div class="progress-bar bg-indigo-600 h-1.5 rounded-full" style="width: 0%"></div>
</div>
</div>
`;
filesContainer.appendChild(fileCard);
// Add click event to preview image
fileCard.addEventListener('click', (e) => {
if (!e.target.closest('.file-remove') && !e.target.closest('.handle')) {
previewFile(file);
}
});
// Add remove file event
const removeBtn = fileCard.querySelector('.file-remove');
removeBtn.addEventListener('click', (e) => {
e.stopPropagation();
removeFile(index);
});
});
// Update conversion options if there are files
updateConversionOptions();
}
function formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' bytes';
else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
else if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB';
else return (bytes / 1073741824).toFixed(1) + ' GB';
}
function removeFile(index) {
files.splice(index, 1);
if (files.length === 0) {
fileList.classList.add('hidden');
conversionOptions.classList.add('hidden');
} else {
updateFileList();
}
}
function clearAllFiles() {
files = [];
fileList.classList.add('hidden');
conversionOptions.classList.add('hidden');
}
function showTab(activeContent, activeTab, inactiveContents, inactiveTabs) {
activeContent.classList.remove('hidden');
activeTab.classList.remove('text-gray-600', 'hover:bg-gray-100');
activeTab.classList.add('bg-indigo-600', 'text-white');
inactiveContents.forEach(content => content.classList.add('hidden'));
inactiveTabs.forEach(tab => {
tab.classList.remove('bg-indigo-600', 'text-white');
tab.classList.add('text-gray-600', 'hover:bg-gray-100');
});
}
function toggleFormatDropdown() {
formatDropdown.classList.toggle('hidden');
}
function selectFormat(option) {
currentFormat = option.getAttribute('data-format');
const displayName = option.querySelector('.font-medium').textContent;
formatName.textContent = displayName.toUpperCase();
selectedFormat.classList.remove('hidden');
formatDropdownBtn.querySelector('span').textContent = displayName.toUpperCase();
formatDropdown.classList.add('hidden');
// Show/hide format-dependent options
document.querySelectorAll('.format-dependent').forEach(el => {
const formats = el.getAttribute('data-dependent').split(',');
if (formats.includes(currentFormat)) {
el.classList.remove('hidden');
} else {
el.classList.add('hidden');
}
});
}
function updateConversionOptions() {
if (files.length > 0) {
conversionOptions.classList.remove('hidden');
// Initialize options
currentConversionOptions = {
format: null,
quality: 90,
width: null,
height: null,
metadata: 'keep',
colorProfile: 'srgb',
dpi: '72'
};
}
}
function updateQualityValue() {
qualityValue.textContent = `${qualitySlider.value}%`;
}
function toggleAdvancedOptions() {
advancedOptions.classList.toggle('hidden');
advancedIcon.classList.toggle('rotate-180');
}
function convertFiles() {
if (!currentFormat) {
alert('Please select an output format');
return;
}
// Simulate conversion - in a real app this would be an API call
convertAllBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Converting...';
convertAllBtn.disabled = true;
selectedFiles = [...files];
// Simulate conversion progress
let convertedCount = 0;
const progressBars = document.querySelectorAll('.progress-bar');
const progressContainers = document.querySelectorAll('.bg-gray-200');
progressContainers.forEach(container => container.classList.remove('hidden'));
const conversionInterval = setInterval(() => {
convertedCount++;
progressBars.forEach((bar, index) => {
const percentage = (index < convertedCount) ? 100 : 0;
bar.style.width = `${percentage}%`;
});
if (convertedCount >= files.length) {
clearInterval(conversionInterval);
setTimeout(showResults, 500);
}
}, 300);
}
function showResults() {
resultsContainer.innerHTML = '';
selectedFiles.forEach((file, index) => {
// Simulate converted file
const resultItem = document.createElement('div');
resultItem.className = 'bg-white border rounded-md overflow-hidden hover:shadow-md transition';
// Generate a fake converted file name
const originalName = file.name;
const extensionIndex = originalName.lastIndexOf('.');
const nameWithoutExtension = extensionIndex !== -1 ?
originalName.substring(0, extensionIndex) :
originalName;
const convertedName = `${nameWithoutExtension}_converted.${currentFormat.toLowerCase()}`;
resultItem.innerHTML = `
<div class="p-4">
<div class="flex items-center space-x-3">
<div class="flex-shrink-0 w-10 h-10 rounded-md bg-green-50 flex items-center justify-center">
<span class="text-xs font-medium text-green-600">${currentFormat.toUpperCase()}</span>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-900 truncate">${convertedName}</p>
<p class="text-xs text-gray-500">${formatFileSize(file.size * 0.7)}</p>
</div>
</div>
</div>
<div class="border-t px-4 py-3 bg-gray-50">
<div class="flex space-x-2 justify-between">
<button class="preview-btn px-3 py-1 text-sm bg-white border rounded-md hover:bg-gray-50 transition flex items-center space-x-1" data-index="${index}">
<i class="fas fa-eye text-indigo-600"></i>
<span>Preview</span>
</button>
<button class="download-btn px-3 py-1 text-sm bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition flex items-center space-x-1" data-index="${index}">
<i class="fas fa-download"></i>
<span>Download</span>
</button>
</div>
</div>
`;
resultsContainer.appendChild(resultItem);
// Add preview and download events
const previewBtn = resultItem.querySelector('.preview-btn');
previewBtn.addEventListener('click', () => previewFile(file, true));
const downloadBtn = resultItem.querySelector('.download-btn');
downloadBtn.addEventListener('click', simulateDownload);
});
// Show results section
resultsSection.classList.remove('hidden');
// Reset convert button
convertAllBtn.innerHTML = 'Convert All';
convertAllBtn.disabled = false;
// Scroll to results
resultsSection.scrollIntoView({ behavior: 'smooth' });
}
function previewFile(file, isConverted = false) {
if (!file.type.startsWith('image/')) {
alert('Preview is only available for image files');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
previewImage.src = e.target.result;
previewModal.classList.add('active');
// Set download button for original or converted file
if (isConverted) {
downloadPreviewBtn.onclick = simulateDownload;
} else {
downloadPreviewBtn.onclick = () => {
downloadFile(file);
};
}
};
reader.readAsDataURL(file);
}
function closePreview() {
previewModal.classList.remove('active');
}
function simulateDownload() {
// In a real app, this would download the converted file
showToast('Download started - this is a simulation');
}
function simulateDownloadAll() {
showToast('Starting download of all files - this is a simulation');
}
function downloadFile(file) {
const a = document.createElement('a');
a.href = URL.createObjectURL(file);
a.download = file.name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
function showToast(message) {
const toast = document.createElement('div');
toast.className = 'fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-4 py-2 rounded-md shadow-lg flex items-center space-x-2 z-50';
toast.innerHTML = `
<span>${message}</span>
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.add('opacity-0', 'transition-opacity', 'duration-300');
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// Close modal when clicking outside
previewModal.addEventListener('click', (e) => {
if (e.target === previewModal) {
closePreview();
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=gabrielnexby/nitripan" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p><p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=NzService/convert-any-image-format" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>