'use strict'; var $ = function(id){ return document.getElementById(id); }; var uploadedDataURL = ''; var currentAnim = 'fade'; var adW = 600, adH = 600; function hexRgba(hex,pct){var r=parseInt(hex.slice(1,3),16),g=parseInt(hex.slice(3,5),16),bb=parseInt(hex.slice(5,7),16);return 'rgba('+r+','+g+','+bb+','+(pct/100).toFixed(2)+')';} function kfCSS(anim,name){ var kf={fade:'from{opacity:0}to{opacity:1}','slide-up':'from{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}','slide-left':'from{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}',zoom:'from{opacity:0;transform:scale(0.4)}to{opacity:1;transform:scale(1)}',bounce:'0%{opacity:0;transform:scale(0.3)}55%{opacity:1;transform:scale(1.12)}75%{transform:scale(0.94)}100%{opacity:1;transform:scale(1)}',typewriter:'from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0% 0 0)}'}; return '@keyframes '+name+'{' +(kf[anim]||kf.fade)+'}'; } function esc(s){return String(s).replace(/&/g,'&').replace(//g,'>');} function buildAdHTML(opts){ var ovBg=hexRgba(opts.overlayColor,opts.overlayAlpha); var dur=parseFloat(opts.dur),delay=parseFloat(opts.delay); var d0=delay.toFixed(2),d1=(delay+0.25).toFixed(2),d2=(delay+0.5).toFixed(2); var font=opts.font,ease=opts.ease; var imgTag=opts.imgSrc?'':'
'; var animBlock=opts.animate?kfCSS(opts.anim,'kf')+'.hl{animation:kf '+dur+'s '+ease+' '+d0+'s both}.sub{animation:kf '+dur+'s '+ease+' '+d1+'s both}.btn{animation:kf '+dur+'s '+ease+' '+d2+'s both}':''; var safeUrl=(opts.clickUrl||'').replace(/'/g,'%27')||'https://example.com'; return ''+imgTag+'
'+esc(opts.headline)+'
'+esc(opts.subtext)+'
'; } function getOpts(animate){ return {w:adW,h:adH,imgSrc:uploadedDataURL||'',headline:$('headline').value,subtext:$('subtext').value,cta:$('cta').value,overlayColor:$('overlayColor').value,overlayAlpha:+$('overlayAlpha').value,headlineColor:$('headlineColor').value,ctaColor:$('ctaColor').value,ctaText:$('ctaText').value,hlSize:$('headlineSize').value,subSize:$('subSize').value,font:$('fontSelect').value,anim:currentAnim,dur:$('duration').value,delay:$('delay').value,ease:$('easing').value,clickUrl:$('clickUrl').value.trim(),animate:animate||false}; } function refreshPreview(animate){ var opts=getOpts(animate),html=buildAdHTML(opts),frame=$('adPreviewFrame'),shell=$('iframeShell'); frame.width=adW;frame.height=adH; var stageW=$('previewStage').offsetWidth-48,stageH=$('previewStage').offsetHeight-48; var scale=Math.min(1,stageW/adW,stageH/adH); shell.style.width=Math.round(adW*scale)+'px';shell.style.height=Math.round(adH*scale)+'px'; frame.style.transform='scale('+scale+')';frame.style.transformOrigin='top left'; try{frame.srcdoc=html;}catch(e){var doc=frame.contentDocument||frame.contentWindow.document;doc.open();doc.write(html);doc.close();} } /* Export via hidden form POST — no fetch/blob needed, browser handles download directly */ function doExport(){ var btn=$('exportBtn'),btn2=$('exportBtn2'); btn.textContent='⏳…';btn.disabled=true; btn2.textContent='⏳…';btn2.disabled=true; $('exportStatus').style.display='none'; $('exportError').style.display='none'; var exportOpts=getOpts(true); if(uploadedDataURL) exportOpts.imgSrc='bg.jpg'; var adHTML=buildAdHTML(exportOpts); /* Use hidden form POST so PHP streams the file directly to browser download No JS blob handling needed — avoids AV-triggering patterns */ var form=document.createElement('form'); form.method='POST'; form.action='export.php'; form.style.display='none'; var f1=document.createElement('input');f1.type='hidden';f1.name='adHtml';f1.value=adHTML; var f2=document.createElement('input');f2.type='hidden';f2.name='w';f2.value=adW; var f3=document.createElement('input');f3.type='hidden';f3.name='h';f3.value=adH; form.appendChild(f1);form.appendChild(f2);form.appendChild(f3); if(uploadedDataURL){ var f4=document.createElement('input');f4.type='hidden';f4.name='bgImage';f4.value=uploadedDataURL.split(',')[1]; form.appendChild(f4); } document.body.appendChild(form); form.submit(); document.body.removeChild(form); setTimeout(function(){ btn.textContent='⬇ Export ZIP';btn.disabled=false; btn2.textContent='⬇ Export ZIP';btn2.disabled=false; $('exportStatus').style.display='block'; setTimeout(function(){$('exportStatus').style.display='none';},4000); },1500); } /* Accordion */ document.querySelectorAll('.ctrl-head').forEach(function(h){h.addEventListener('click',function(){h.closest('.ctrl-section').classList.toggle('collapsed');});}); $('imgInput').addEventListener('change',function(e){ var f=e.target.files[0];if(!f)return; /* Store as objectURL for preview, read as base64 only for export payload */ var objUrl=URL.createObjectURL(f); $('imgThumb').src=objUrl; $('imgThumbWrap').style.display='flex'; $('dropLabel').textContent='✓ '+f.name; /* Read base64 for iframe preview using canvas */ var img=new Image(); img.onload=function(){ var c=document.createElement('canvas'); c.width=img.naturalWidth;c.height=img.naturalHeight; c.getContext('2d').drawImage(img,0,0); uploadedDataURL=c.toDataURL('image/jpeg',0.92); URL.revokeObjectURL(objUrl); refreshPreview(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(){uploadedDataURL='';$('imgInput').value='';$('dropLabel').textContent='Click or drag image here';$('imgThumbWrap').style.display='none';refreshPreview(false);}); $('clickUrl').addEventListener('input',function(){var v=$('clickUrl').value.trim(),badge=$('urlBadge');if(!v){badge.textContent='—';badge.className='url-badge';return;}try{new URL(v);badge.textContent='✓ Valid';badge.className='url-badge valid';}catch(e){badge.textContent='Invalid';badge.className='url-badge';}}); document.querySelectorAll('.chip').forEach(function(t){t.addEventListener('click',function(){document.querySelectorAll('.chip').forEach(function(x){x.classList.remove('active');});t.classList.add('active');adW=+t.dataset.w;adH=+t.dataset.h;$('sizeLabel').textContent=adW+' × '+adH+' px';refreshPreview(false);});}); document.querySelectorAll('.anim-chip').forEach(function(o){o.addEventListener('click',function(){document.querySelectorAll('.anim-chip').forEach(function(x){x.classList.remove('active');});o.classList.add('active');currentAnim=o.dataset.anim;});}); function wire(id,outId,suffix){$(id).addEventListener('input',function(){$(outId).textContent=$(id).value+suffix;refreshPreview(false);});} wire('overlayAlpha','alphaVal','%');wire('headlineSize','hlVal','px');wire('subSize','subVal','px');wire('duration','durVal','s');wire('delay','delayVal','s'); ['headline','subtext','cta'].forEach(function(id){$(id).addEventListener('input',function(){refreshPreview(false);});}); ['overlayColor','headlineColor','ctaColor','ctaText','fontSelect','easing'].forEach(function(id){$(id).addEventListener('change',function(){refreshPreview(false);});}); $('previewBtn').addEventListener('click',function(){refreshPreview(true);}); $('previewBtn2').addEventListener('click',function(){refreshPreview(true);}); $('exportBtn').addEventListener('click',doExport); $('exportBtn2').addEventListener('click',doExport); document.querySelectorAll('.sb-item').forEach(function(item){item.addEventListener('click',function(e){if(item.getAttribute('href')&&item.getAttribute('href')!=='#')return;e.preventDefault();document.querySelectorAll('.sb-item').forEach(function(x){x.classList.remove('active');});item.classList.add('active');});}); window.addEventListener('DOMContentLoaded',function(){refreshPreview(false);}); window.addEventListener('resize',function(){refreshPreview(false);});