let characters=[]; // Tab switching document.querySelectorAll(".tab-btn").forEach(btn=>{ btn.addEventListener("click",()=>{ document.querySelectorAll(".tab-btn").forEach(b=>b.classList.remove("active")); document.querySelectorAll(".tab-content").forEach(c=>c.classList.add("hidden")); btn.classList.add("active"); document.getElementById(btn.dataset.tab).classList.remove("hidden"); }); }); // Add character document.getElementById("add-character").addEventListener("click",()=>{ const container=document.createElement("div"); container.className="border p-4 rounded"; container.innerHTML=` `; document.getElementById("character-list").appendChild(container); characters.push({name:"",desc:"",img:null}); }); // Convert file to Base64 function imageFileToBase64(file){ return new Promise((resolve,reject)=>{ const reader=new FileReader(); reader.onload=()=>resolve(reader.result); reader.onerror=err=>reject(err); reader.readAsDataURL(file); }); } // Make speech bubbles draggable function makeDraggable(el){ let offsetX,offsetY; el.onmousedown=e=>{ offsetX=e.clientX-el.offsetLeft; offsetY=e.clientY-el.offsetTop; document.onmousemove=e=>{el.style.left=(e.clientX-offsetX)+"px"; el.style.top=(e.clientY-offsetY)+"px";} document.onmouseup=()=>document.onmousemove=null; }; } // Comic sound effects const comicEffects=["BAM!","KAPOW!","KA-BOOM!","WHAM!","ZAP!","BOOM!"]; // Generate panels document.getElementById("generate-btn").addEventListener("click", async()=>{ const story=document.getElementById("story-input").value.trim(); const panels=parseInt(document.getElementById("panel-count").value); const apiKey=document.getElementById("api-key").value.trim(); const artStyle=document.getElementById("art-style").value; const explicit=document.getElementById("explicit-toggle").checked; const model=document.getElementById("custom-model").value.trim() || "stabilityai/stable-diffusion-2"; const bgDesc=document.getElementById("bg-desc").value.trim(); const preview=document.getElementById("comic-preview"); preview.innerHTML=""; // Collect characters const charPrompts=[]; const charImages=[]; const charDivs=document.querySelectorAll("#character-list .border"); for(const div of charDivs){ const name=div.querySelector(".char-name").value; const desc=div.querySelector(".char-desc").value; const file=div.querySelector(".char-img").files[0]; if(name && desc) charPrompts.push(`${name}: ${desc}`); if(file) charImages.push(await imageFileToBase64(file)); } for(let i=0;i`; // Generate short dialogue for speech bubble const textPrompt=`Generate short comic dialogue for panel ${i+1} with characters: ${charPrompts.join(", ")} including sound effects like BAM, POW, KAPOW.`; const textResp=await fetch(`https://api-inference.huggingface.co/models/gpt2`,{ method:"POST", headers:{Authorization:`Bearer ${apiKey}`, "Content-Type":"application/json"}, body:JSON.stringify({inputs:textPrompt,max_new_tokens:40}) }).then(r=>r.json()); // Add draggable speech bubble const bubble=document.createElement("div"); bubble.className="speech-bubble"; bubble.contentEditable=true; bubble.innerText=textResp[0]?.generated_text?.split(".")[0] || comicEffects[Math.floor(Math.random()*comicEffects.length)]; makeDraggable(bubble); panelDiv.appendChild(bubble); // Add editable caption const caption=document.createElement("div"); caption.className="caption"; caption.contentEditable=true; caption.innerText=textResp[0]?.generated_text || ""; panelDiv.appendChild(caption); }catch(err){ console.error(err); panelDiv.innerText="❌ Error generating panel"; } } }); // Export PDF document.getElementById("download-btn").addEventListener("click",()=>{ const {jsPDF}=window.jspdf; const pdf=new jsPDF(); const panels=document.querySelectorAll(".comic-panel img"); panels.forEach((img,i)=>{ if(i>0) pdf.addPage(); pdf.addImage(img.src,"JPEG",10,10,180,160); }); pdf.save("comic-book.pdf"); });