// Export the complete diagram in world coordinates, independent of viewport/zoom. (() => { const NS='http://www.w3.org/2000/svg'; function init(){ const root=document.getElementById('uc-editor');if(!root||root.dataset.exportReady)return;root.dataset.exportReady='1'; const $=id=>root.querySelector('#uc-'+id),dialog=$('export-dialog');let busy=false; const paint=['fill','fill-opacity','stroke','stroke-width','stroke-opacity','stroke-dasharray','stroke-linecap','stroke-linejoin','opacity','font-family','font-size','font-weight','font-style','letter-spacing','word-spacing','text-anchor','dominant-baseline','paint-order','white-space']; function snapshot(){ const svg=$('svg'),content=svg.querySelector('.uc-graph');if(!content||!content.children.length)throw new Error('เพิ่ม shape ก่อนส่งออก PNG'); const box=content.getBBox(),padding=32,width=Math.max(1,Math.ceil(box.width+padding*2)),height=Math.max(1,Math.ceil(box.height+padding*2)); const copy=svg.cloneNode(true),sourceNodes=[svg,...svg.querySelectorAll('*')],targetNodes=[copy,...copy.querySelectorAll('*')]; for(let i=0;iel.remove()); copy.querySelectorAll('.is-selected').forEach(el=>el.classList.remove('is-selected')); copy.setAttribute('xmlns',NS);copy.setAttribute('width',width);copy.setAttribute('height',height);copy.setAttribute('viewBox',`${box.x-padding} ${box.y-padding} ${width} ${height}`); return {xml:new XMLSerializer().serializeToString(copy),width,height}; } $('export-png').addEventListener('click',()=>{ $('export-png').closest('details').open=false;$('export-status').dataset.error='false';$('export-status').textContent='PNG · Full diagram · ไม่รวมกริดและจุดลาก';dialog.showModal(); }); const close=()=>{if(!busy)dialog.close()};$('export-close').onclick=close;$('export-cancel').onclick=close;dialog.addEventListener('cancel',e=>{if(busy)e.preventDefault()}); $('export-form').addEventListener('submit',async e=>{ e.preventDefault();if(busy)return;busy=true;$('export-download').disabled=true;$('export-close').disabled=true;$('export-cancel').disabled=true;$('export-status').dataset.error='false';$('export-status').textContent='กำลังสร้าง PNG…';let imageURL; try{ await document.fonts.ready;const {xml,width,height}=snapshot(); // Keep a full diagram export within browser canvas memory/dimension limits. const scale=Math.min(2,16384/width,16384/height,Math.sqrt(16000000/(width*height))); const canvas=document.createElement('canvas');canvas.width=Math.max(1,Math.floor(width*scale));canvas.height=Math.max(1,Math.floor(height*scale)); const ctx=canvas.getContext('2d');if(!ctx)throw new Error('ไม่สามารถสร้างภาพ PNG ได้'); if($('export-form').elements.background.value==='white'){ctx.fillStyle='#ffffff';ctx.fillRect(0,0,canvas.width,canvas.height);} imageURL=URL.createObjectURL(new Blob([xml],{type:'image/svg+xml;charset=utf-8'})); const img=new Image();await new Promise((resolve,reject)=>{img.onload=resolve;img.onerror=()=>reject(new Error('ไม่สามารถอ่านภาพ diagram ได้'));img.src=imageURL});ctx.drawImage(img,0,0,canvas.width,canvas.height); const blob=await new Promise(resolve=>canvas.toBlob(resolve,'image/png'));if(!blob)throw new Error('ไม่สามารถสร้างไฟล์ PNG ได้'); const href=URL.createObjectURL(blob),link=document.createElement('a');link.href=href;link.download=root.dataset.uid+'-workflow-'+$('export-form').elements.background.value+'.png';document.body.append(link);link.click();link.remove();setTimeout(()=>URL.revokeObjectURL(href),60000); $('export-status').textContent='ส่งออก PNG แล้ว · '+canvas.width+' × '+canvas.height+' px'; }catch(err){$('export-status').dataset.error='true';$('export-status').textContent=err.message||'ส่งออกไม่สำเร็จ กรุณาลองใหม่';} finally{if(imageURL)URL.revokeObjectURL(imageURL);busy=false;$('export-download').disabled=false;$('export-close').disabled=false;$('export-cancel').disabled=false;} }); } init();document.addEventListener('tracker:updated',init); })();