'use strict'; var $ = function(id){ return document.getElementById(id); }; var sourceImage = null; var currentMode = 'crop'; var currentFmt = 'jpeg'; var renderedCards = []; $('imgInput').addEventListener('change', function(e){ var f = e.target.files[0]; if (!f) return; var objUrl = URL.createObjectURL(f); var img = new Image(); img.onload = function(){ sourceImage = img; $('srcPreview').src = objUrl; $('srcPreviewWrap').style.display = 'block'; $('dropLabel').textContent = '✓ ' + f.name; $('renderBtn').disabled = false; }; img.src = objUrl; }); ['dragover','dragleave','drop'].forEach(function(ev){ $('dropzone').addEventListener(ev, function(e){ e.preventDefault(); }); }); $('dropzone').addEventListener('drop', function(e){ var f = e.dataTransfer.files[0]; if (!f || !f.type.startsWith('image/')) return; var dt = new DataTransfer(); dt.items.add(f); $('imgInput').files = dt.files; $('imgInput').dispatchEvent(new Event('change')); }); $('removeImg').addEventListener('click', function(){ sourceImage = null; $('imgInput').value = ''; $('srcPreviewWrap').style.display = 'none'; $('dropLabel').textContent = 'Click or drag your image here'; $('renderBtn').disabled = true; $('downloadAllBtn').disabled = true; clearGrid(); }); /* Platform master checkboxes */ document.querySelectorAll('.plat-master').forEach(function(master){ master.addEventListener('change', function(){ var plat = master.dataset.platform; document.querySelectorAll('.size-checks[data-platform="'+plat+'"] input[type="checkbox"]').forEach(function(c){ c.checked = master.checked; }); }); }); /* Custom size */ $('addCustom').addEventListener('click', function(){ var w = parseInt($('customW').value); var h = parseInt($('customH').value); if (!w || !h || w < 10 || h < 10 || w > 5000 || h > 5000) { $('customW').style.borderColor='#c00'; $('customH').style.borderColor='#c00'; setTimeout(function(){ $('customW').style.borderColor=''; $('customH').style.borderColor=''; }, 1500); return; } var id = 'cust-' + w + 'x' + h; var item = document.createElement('div'); item.className = 'custom-item'; item.id = id; item.innerHTML = ''+w+' × '+h+''; item.querySelector('.custom-remove').addEventListener('click', function(){ item.remove(); }); $('customList').appendChild(item); $('customW').value=''; $('customH').value=''; $('customMaster').checked = true; }); /* Fit mode */ document.querySelectorAll('.mode-opt').forEach(function(opt){ opt.addEventListener('click', function(){ document.querySelectorAll('.mode-opt').forEach(function(o){ o.classList.remove('active'); }); opt.classList.add('active'); currentMode = opt.dataset.mode; }); }); /* Format */ document.querySelectorAll('.format-opt').forEach(function(opt){ opt.addEventListener('click', function(){ document.querySelectorAll('.format-opt').forEach(function(o){ o.classList.remove('active'); }); opt.classList.add('active'); currentFmt = opt.dataset.fmt; $('qualityRow').style.display = currentFmt === 'jpeg' ? '' : 'none'; }); }); /* Sliders */ function wireSlider(id,outId,suffix){ $(id).addEventListener('input',function(){ $(outId).textContent=$(id).value+suffix; }); } wireSlider('ovAlpha','ovAlphaVal','%'); wireSlider('ovFontSize','ovFontSizeVal','px'); wireSlider('jpgQuality','jpgQualityVal','%'); /* Overlay toggle */ $('overlayToggle').addEventListener('change', function(){ $('overlayFields').style.display = this.checked ? '' : 'none'; }); /* Accordion */ document.querySelectorAll('.ctrl-head').forEach(function(head){ head.addEventListener('click', function(){ head.closest('.ctrl-section').classList.toggle('collapsed'); }); }); /* Get selected sizes */ function getSelectedSizes(){ var sizes=[], seen={}; document.querySelectorAll('.size-checks input[type="checkbox"]:checked').forEach(function(cb){ var w=parseInt(cb.dataset.w), h=parseInt(cb.dataset.h); if(!w||!h) return; var key=w+'x'+h; if(seen[key]) return; seen[key]=true; var plat = cb.closest('.size-checks').dataset.platform||''; sizes.push({w:w,h:h,key:key,platform:plat,label:cb.dataset.label||''}); }); return sizes; } /* Render to canvas */ function renderToCanvas(canvas, W, H, mode){ canvas.width=W; canvas.height=H; var ctx=canvas.getContext('2d'), img=sourceImage; var iW=img.naturalWidth, iH=img.naturalHeight; ctx.clearRect(0,0,W,H); if(mode==='crop'){ var s=Math.max(W/iW,H/iH); ctx.drawImage(img,(W-iW*s)/2,(H-iH*s)/2,iW*s,iH*s); } else if(mode==='contain-white'||mode==='contain-black'){ ctx.fillStyle=mode==='contain-white'?'#fff':'#000'; ctx.fillRect(0,0,W,H); var s2=Math.min(W/iW,H/iH); ctx.drawImage(img,(W-iW*s2)/2,(H-iH*s2)/2,iW*s2,iH*s2); } else if(mode==='blur'){ var off=document.createElement('canvas'); off.width=Math.min(W,320); off.height=Math.min(H,320); var oc=off.getContext('2d'); var bs=Math.max(off.width/iW,off.height/iH); oc.drawImage(img,(off.width-iW*bs)/2,(off.height-iH*bs)/2,iW*bs,iH*bs); ctx.filter='blur(22px) brightness(0.65)'; ctx.drawImage(off,-40,-40,W+80,H+80); ctx.filter='none'; var s3=Math.min(W/iW,H/iH); ctx.drawImage(img,(W-iW*s3)/2,(H-iH*s3)/2,iW*s3,iH*s3); } } /* Text overlay */ function drawOverlay(canvas,W,H){ if(!$('overlayToggle').checked) return; var headline=$('ovHeadline').value.trim(), subtext=$('ovSubtext').value.trim(), cta=$('ovCta').value.trim(); var textColor=$('ovTextColor').value, ctaBg=$('ovCtaBg').value; var alpha=parseInt($('ovAlpha').value)/100, baseFont=parseInt($('ovFontSize').value)*(W/1080); var ctx=canvas.getContext('2d'), pad=W*0.055, curY=H-pad; var grad=ctx.createLinearGradient(0,H-H*0.4,0,H); grad.addColorStop(0,'rgba(0,0,0,0)'); grad.addColorStop(1,'rgba(0,0,0,'+alpha+')'); ctx.fillStyle=grad; ctx.fillRect(0,H-H*0.4,W,H*0.4); if(cta){ var cfs=baseFont*0.52, cpx=W*0.028, cpy=W*0.014; ctx.font='bold '+cfs+'px sans-serif'; var cw=ctx.measureText(cta).width+cpx*2, ch=cfs+cpy*2; ctx.fillStyle=ctaBg; roundRect(ctx,pad,curY-ch,cw,ch,ch*0.2); ctx.fillStyle='#fff'; ctx.textBaseline='middle'; ctx.fillText(cta,pad+cpx,curY-ch/2); curY-=ch+pad*0.55; } if(subtext){ var sfs=baseFont*0.58; ctx.font=sfs+'px sans-serif'; ctx.fillStyle='rgba(255,255,255,0.85)'; ctx.textBaseline='alphabetic'; wrapText(ctx,subtext,W-pad*2,sfs*1.4).reverse().forEach(function(l){ctx.fillText(l,pad,curY);curY-=sfs*1.4;}); curY-=pad*0.3; } if(headline){ ctx.font='bold '+baseFont+'px sans-serif'; ctx.fillStyle=textColor; ctx.textBaseline='alphabetic'; wrapText(ctx,headline,W-pad*2,baseFont*1.25).reverse().forEach(function(l){ctx.fillText(l,pad,curY);curY-=baseFont*1.25;}); } } function wrapText(ctx,text,maxW,lh){ var words=text.split(' '),lines=[],line=''; words.forEach(function(w){var t=line?line+' '+w:w;if(ctx.measureText(t).width>maxW&&line){lines.push(line);line=w;}else line=t;}); if(line)lines.push(line);return lines; } function roundRect(ctx,x,y,w,h,r){ ctx.beginPath();ctx.moveTo(x+r,y);ctx.lineTo(x+w-r,y);ctx.quadraticCurveTo(x+w,y,x+w,y+r);ctx.lineTo(x+w,y+h-r);ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h);ctx.lineTo(x+r,y+h);ctx.quadraticCurveTo(x,y+h,x,y+h-r);ctx.lineTo(x,y+r);ctx.quadraticCurveTo(x,y,x+r,y);ctx.closePath();ctx.fill(); } /* Clear grid */ function clearGrid(){ var grid=$('canvasGrid'); grid.innerHTML=''; renderedCards=[]; var es=document.createElement('div'); es.className='empty-state'; es.id='emptyState'; es.innerHTML='
📐

Your resized creatives will appear here

Upload an image → select sizes → click Render'; grid.appendChild(es); } /* Build filename */ function buildFilename(size){ var ext=currentFmt==='jpeg'?'jpg':'png'; return (size.platform?size.platform+'-':'')+(size.label?size.label.toLowerCase().replace(/\s+/g,'-')+'-':'')+size.w+'x'+size.h+'.'+ext; } /* Render button */ $('renderBtn').addEventListener('click', function(){ if(!sourceImage) return; var sizes=getSelectedSizes(); if(!sizes.length){ alert('Please select at least one size.'); return; } clearGrid(); var grid=$('canvasGrid'); renderedCards=[]; $('renderHint').textContent='Rendering '+sizes.length+' size'+(sizes.length>1?'s':'')+'…'; $('renderBtn').disabled=true; $('downloadAllBtn').disabled=true; var i=0; function next(){ if(i>=sizes.length){ $('renderBtn').disabled=false; $('downloadAllBtn').disabled=false; $('renderHint').textContent=sizes.length+' size'+(sizes.length>1?'s':'')+' ready'; return; } var size=sizes[i++]; var card=document.createElement('div'); card.className='size-card'; var platLabel=size.platform.charAt(0).toUpperCase()+size.platform.slice(1); var fname=buildFilename(size); card.innerHTML='
'+(size.label||size.key)+''+size.w+' × '+size.h+''+platLabel+'
'; grid.appendChild(card); var canvas=document.createElement('canvas'); card.querySelector('.canvas-outer').appendChild(canvas); renderToCanvas(canvas,size.w,size.h,currentMode); drawOverlay(canvas,size.w,size.h); renderedCards.push({key:size.key,canvas:canvas,filename:fname}); /* Individual download — canvas.toDataURL avoids blob/createObjectURL pattern */ card.querySelector('.dl-btn').addEventListener('click', function(){ var quality=parseInt($('jpgQuality').value)/100; var mime=currentFmt==='jpeg'?'image/jpeg':'image/png'; var dataUrl=canvas.toDataURL(mime, quality); var a=document.createElement('a'); a.href=dataUrl; a.download=fname; document.body.appendChild(a); a.click(); document.body.removeChild(a); }); setTimeout(next,30); } next(); }); /* Download All — hidden form POST, PHP packages and streams download */ $('downloadAllBtn').addEventListener('click', function(){ if(!renderedCards.length) return; var btn=$('downloadAllBtn'); btn.textContent='⏳ Packaging…'; btn.disabled=true; var quality=parseInt($('jpgQuality').value)/100; var mime=currentFmt==='jpeg'?'image/jpeg':'image/png'; var fmt=currentFmt==='jpeg'?'jpg':'png'; /* Build form with all images as hidden fields */ var form=document.createElement('form'); form.method='POST'; form.action='../resize-export.php'; form.style.display='none'; var fFmt=document.createElement('input');fFmt.type='hidden';fFmt.name='format';fFmt.value=fmt; form.appendChild(fFmt); renderedCards.forEach(function(card, idx){ var dataUrl=card.canvas.toDataURL(mime, quality); var b64=dataUrl.split(',')[1]; var fn=document.createElement('input');fn.type='hidden'; fn.name='images['+idx+'][filename]'; fn.value=card.filename.replace(/\.[^.]+$/,''); form.appendChild(fn); var fd=document.createElement('input');fd.type='hidden'; fd.name='images['+idx+'][data]'; fd.value=b64; form.appendChild(fd); }); document.body.appendChild(form); form.submit(); document.body.removeChild(form); setTimeout(function(){ btn.textContent='⬇ Download All'; btn.disabled=false; },2000); });