Image Tools.

Trend World Free Image Tools

`; toolGrid.appendChild(card); }); // 2. MODAL HANDLING let currentToolCleanup = null; // To handle cleanup for tools like the cropper toolGrid.addEventListener('click', (e) => { if (e.target.classList.contains('btn')) { openModal(e.target.getAttribute('data-tool-id')); } }); const closeModal = () => { if (currentToolCleanup) { currentToolCleanup(); currentToolCleanup = null; } modal.classList.remove('show'); }; closeBtn.onclick = closeModal; modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); }); function openModal(toolId) { const tool = tools.find(t => t.id === toolId); modalHost.innerHTML = getToolHTML(toolId, tool.title); modal.classList.add('show'); attachToolListener(toolId); } // 3. GENERATE HTML FOR EACH TOOL function getToolHTML(toolId, title) { let controls = ''; let workspace = `

Click or drag image here

`; switch(toolId) { case 'compressor': controls = ``; break; case 'resizer': controls = ``; break; case 'cropper': controls = ``; workspace = `

Click to upload

`; break; case 'pngToJpg': case 'jpgToPng': case 'webpToPng': controls = ``; break; case 'favicon': controls = ``; break; case 'logoMaker': controls = ``; workspace = `Download Logo`; break; case 'mbToKb': controls = ``; workspace = ''; break; case 'reverseSearch': case 'jpgToWord': case 'svgConverter': controls = ``; break; } return `

${title}

${controls}${workspace}
`; } // 4. ATTACH LISTENERS AND DEFINE TOOL LOGIC function attachToolListener(toolId) { const toolData = tools.find(t => t.id === toolId); const actionBtn = modal.querySelector('#action-btn'); const outputDiv = modal.querySelector('#output'); // Reusable image loading logic let originalImage = null; let originalFileName = ''; const workspace = modal.querySelector('#workspace'); const uploadInput = modal.querySelector('#image-upload'); if (workspace && uploadInput) { const prompt = workspace.querySelector('.upload-prompt'); const openFileDialog = () => uploadInput.click(); workspace.addEventListener('click', openFileDialog); workspace.addEventListener('dragover', (e) => e.preventDefault()); workspace.addEventListener('drop', (e) => { e.preventDefault(); if (e.dataTransfer.files.length) { handleFile(e.dataTransfer.files[0]); } }); uploadInput.onchange = (e) => handleFile(e.target.files[0]); function handleFile(file) { if (!file.type.startsWith('image/')) return; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { originalImage = img; originalFileName = file.name.split('.').slice(0, -1).join('.'); const canvas = document.createElement('canvas'); canvas.id = 'main-canvas'; canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); if (prompt) workspace.innerHTML = ''; else workspace.querySelector('#main-canvas')?.remove(); workspace.appendChild(canvas); if (actionBtn) actionBtn.disabled = false; // Specific setup for cropper after image load if(toolId === 'cropper') setupCropper(canvas); }; img.src = e.target.result; }; reader.readAsDataURL(file); } } // Logic for each tool if (toolData.type === 'demo') { if(!actionBtn) return; actionBtn.onclick = () => { outputDiv.innerHTML = 'Processing...'; setTimeout(() => { let resultText; if(toolId === 'reverseSearch') { resultText = `For a real Reverse Image Search, please use Google Images. This is a UI demonstration.`; } else { resultText = `This is a functional UI demonstration. A real ${toolData.title} requires complex server-side processing to provide accurate results.`; } outputDiv.innerHTML = resultText; }, 1500); }; return; } switch(toolId) { case 'compressor': actionBtn.onclick = async () => { const canvas = workspace.querySelector('canvas'); const targetSizeKB = parseFloat(modal.querySelector('#target-size').value); let quality = parseFloat(modal.querySelector('#quality').value); let mimeType = originalImage.src.includes('png') ? 'image/png' : 'image/jpeg'; outputDiv.innerHTML = "Compressing..."; if (!isNaN(targetSizeKB)) { // Iterative compression to meet target size const targetBytes = targetSizeKB * 1024; let low = 0, high = 1, mid, currentBlob; for(let i=0; i < 10; i++) { // 10 iterations for precision mid = (low + high) / 2; currentBlob = await getCanvasBlob(canvas, 'image/jpeg', mid); if (currentBlob.size > targetBytes) high = mid; else low = mid; } quality = low; mimeType = 'image/jpeg'; // Target size only works well for JPEG } const blob = await getCanvasBlob(canvas, mimeType, quality); const url = URL.createObjectURL(blob); outputDiv.innerHTML = `Compressed Size: ${(blob.size / 1024).toFixed(2)} KB Download`; }; break; case 'resizer': actionBtn.onclick = () => { const width = parseInt(modal.querySelector('#width-input').value); const height = parseInt(modal.querySelector('#height-input').value); if(isNaN(width) || isNaN(height)) return; const newCanvas = document.createElement('canvas'); newCanvas.width = width; newCanvas.height = height; newCanvas.getContext('2d').drawImage(originalImage, 0, 0, width, height); const url = newCanvas.toDataURL(); outputDiv.innerHTML = `Resized to ${width}x${height} Download`; }; break; case 'cropper': // Setup logic is handled in the image loader break; case 'pngToJpg': case 'jpgToPng': case 'webpToPng': actionBtn.onclick = () => { const canvas = workspace.querySelector('canvas'); let targetMime, ext; switch(toolId) { case 'pngToJpg': targetMime = 'image/jpeg'; ext = 'jpg'; break; case 'jpgToPng': targetMime = 'image/png'; ext = 'png'; break; case 'webpToPng': targetMime = 'image/png'; ext = 'png'; break; } const url = canvas.toDataURL(targetMime, 1.0); outputDiv.innerHTML = `Converted! Download`; }; break; case 'favicon': actionBtn.onclick = () => { const size = parseInt(modal.querySelector('#favicon-size').value); const newCanvas = document.createElement('canvas'); newCanvas.width = size; newCanvas.height = size; newCanvas.getContext('2d').drawImage(originalImage, 0, 0, size, size); const url = newCanvas.toDataURL('image/png'); outputDiv.innerHTML = `Generated ${size}x${size} Favicon Download`; }; break; case 'logoMaker': const logoCanvas = modal.querySelector('#logo-canvas'); const ctx = logoCanvas.getContext('2d'); const textInput = modal.querySelector('#logo-text'); const shapeSelect = modal.querySelector('#logo-shape'); const bgInput = modal.querySelector('#logo-bg'); const fgInput = modal.querySelector('#logo-fg'); function drawLogo() { const w = logoCanvas.width, h = logoCanvas.height; const bgColor = bgInput.value; const fgColor = fgInput.value; const text = textInput.value; const shape = shapeSelect.value; // Background ctx.fillStyle = bgColor; if(shape === 'circle') { ctx.clearRect(0,0,w,h); ctx.beginPath(); ctx.arc(w/2, h/2, w/2, 0, 2 * Math.PI); ctx.fill(); } else { ctx.fillRect(0,0,w,h); } // Text ctx.fillStyle = fgColor; ctx.font = 'bold 40px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(text, w/2, h/2); } drawLogo(); [textInput, shapeSelect, bgInput, fgInput].forEach(el => el.oninput = drawLogo); modal.querySelector('#download-btn').onclick = (e) => { e.target.href = logoCanvas.toDataURL('image/png'); e.target.download = `${textInput.value}_logo.png`; }; break; case 'mbToKb': const mbInput = modal.querySelector('#mb-input'); const kbInput = modal.querySelector('#kb-input'); mbInput.oninput = () => kbInput.value = parseFloat(mbInput.value) * 1024; kbInput.oninput = () => mbInput.value = parseFloat(kbInput.value) / 1024; break; } } // Helper to get blob from canvas function getCanvasBlob(canvas, mimeType, quality) { return new Promise(resolve => canvas.toBlob(resolve, mimeType, quality)); } // Specific and complex logic for cropper tool function setupCropper(canvas) { const workspace = canvas.parentElement; let cropRect = { x: 0, y: 0, w: 100, h: 100 }; let isDragging = false, dragStart = {}; const selectionDiv = document.createElement('div'); selectionDiv.style.position = 'absolute'; selectionDiv.style.border = '2px dashed blue'; selectionDiv.style.pointerEvents = 'none'; workspace.appendChild(selectionDiv); const updateSelection = () => { selectionDiv.style.left = `${cropRect.x}px`; selectionDiv.style.top = `${cropRect.y}px`; selectionDiv.style.width = `${cropRect.w}px`; selectionDiv.style.height = `${cropRect.h}px`; }; updateSelection(); const onMouseDown = (e) => { isDragging = true; dragStart.x = e.clientX - workspace.getBoundingClientRect().left; dragStart.y = e.clientY - workspace.getBoundingClientRect().top; }; const onMouseMove = (e) => { if (!isDragging) return; const mouseX = e.clientX - workspace.getBoundingClientRect().left; const mouseY = e.clientY - workspace.getBoundingClientRect().top; cropRect.x = Math.min(mouseX, dragStart.x); cropRect.y = Math.min(mouseY, dragStart.y); cropRect.w = Math.abs(mouseX - dragStart.x); cropRect.h = Math.abs(mouseY - dragStart.y); updateSelection(); }; const onMouseUp = () => { isDragging = false; }; workspace.addEventListener('mousedown', onMouseDown); window.addEventListener('mousemove', onMouseMove); window.addEventListener('mouseup', onMouseUp); currentToolCleanup = () => { window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); }; modal.querySelector('#action-btn').onclick = () => { const sourceImage = workspace.querySelector('canvas'); const scaleX = sourceImage.naturalWidth / sourceImage.width; const scaleY = sourceImage.naturalHeight / sourceImage.height; const croppedCanvas = document.createElement('canvas'); croppedCanvas.width = cropRect.w; croppedCanvas.height = cropRect.h; croppedCanvas.getContext('2d').drawImage( sourceImage, cropRect.x, cropRect.y, cropRect.w, cropRect.h, // Source rect 0, 0, cropRect.w, cropRect.h // Destination rect ); const url = croppedCanvas.toDataURL(); modal.querySelector('#output').innerHTML = `Cropped! Download`; }; } })();

This website uses cookies.