'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='