Virtual Alien Species Creator

Customize Your Species

Notable Quirk: ${quirk}

`; alienDescription.innerHTML = descriptionHTML; alienShape.style.cssText = bodyForm.shape || ''; alienShape.style.backgroundColor = environment.color || '#e9c46a'; alienShape.style.animation = 'none'; alienShape.offsetHeight; if (formKey === 'Amorphous') alienShape.style.animation = 'alienBlobAnim 10s infinite alternate'; else if (formKey === 'EnergyBased') { alienShape.style.boxShadow = '0 0 15px 5px currentColor'; alienShape.style.borderWidth = '3px'; alienShape.style.animation = 'alienPulseAnim 3s infinite alternate'; } else if (formKey === 'ExoticForm') { alienShape.style.animation = 'alienShiftAnim 8s infinite linear'; } else { alienShape.style.boxShadow = 'none'; alienShape.style.borderWidth = '1px'; } outputContainer.style.display = 'block'; if (downloadBtn) { downloadBtn.style.display = 'block'; downloadBtn.disabled = !jsPDFLoaded || !html2canvasLoaded; } // Depends on both now console.log("Alien generated and displayed."); } catch (error) { console.error("Error during alien generation:", error); errorMsgDiv.textContent = "An error occurred while generating the alien species."; } } // --- PDF Download Logic --- function downloadPDF() { const uniqueId = Date.now(); // Unique ID for this attempt console.log(`/* DEBUG ${uniqueId}: */ PDF Download button clicked.`); errorMsgDiv.textContent = ''; // Clear previous errors if(downloadBtn) { downloadBtn.disabled = true; // Disable button downloadBtn.textContent = 'Processing...'; // Add indicator downloadBtn.style.opacity = '0.7'; } // Use setTimeout to allow the UI update (Processing text) before potentially heavy work setTimeout(() => { console.log(`/* DEBUG ${uniqueId}: */ Starting PDF processing inside setTimeout.`); // Final check for required libraries (jsPDF is always needed, html2canvas is needed for Method 2) if (!jsPDFLoaded) { console.error(`/* DEBUG ${uniqueId}: */ jsPDF library check failed.`); errorMsgDiv.textContent = "Error: jsPDF library not available."; if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } return; } // Check for html2canvas only if Method 2 is active (which it is by default now) if (!html2canvasLoaded) { console.error(`/* DEBUG ${uniqueId}: */ html2canvas library check failed (Method 2 active).`); errorMsgDiv.textContent = "Error: html2canvas library not available for image capture."; if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } return; } // Check for content existence const outputAreaElement = document.getElementById('alienOutputArea'); // Target for html2canvas if (!outputAreaElement || !document.getElementById('alienDescription').innerHTML.trim()) { // Check description part specifically console.error(`/* DEBUG ${uniqueId}: */ No content found in #alienDescription.`); errorMsgDiv.textContent = "Error: Please generate an alien species first."; if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } return; } // ***** TEST C: SIMPLIFY CONTENT (Can still be useful for html2canvas if needed) ***** // To test if complexity causes html2canvas issues, simplify BOTH #alienVisual and #alienDescription // console.log(`/* DEBUG ${uniqueId}: */ Replacing content with SIMPLE test HTML for html2canvas.`); // document.getElementById('alienVisual').innerHTML = '
'; // document.getElementById('alienDescription').innerHTML = '

Test Alien

Simple test.

'; // ***** END OF TEST C ***** /* --- METHOD 1: jsPDF.html() (COMMENTED OUT - Was causing freezes) --- */ /* console.log(`/ * DEBUG ${uniqueId}: * / Attempting PDF generation using METHOD 1: jsPDF.html()...`); try { // ... (Code for Method 1 - jsPDF.html() is commented out) ... } catch (error) { // ... (Error handling for Method 1) ... } */ // --- METHOD 2: html2canvas (DEFAULT ACTIVE METHOD) --- // This method captures the output area (#alienOutputArea) as an image. // It's generally more robust for complex layouts and less prone to freezing. console.log(`/* DEBUG ${uniqueId}: */ Attempting PDF generation using METHOD 2: html2canvas...`); try { const { jsPDF } = window.jspdf; // Still need jsPDF to put the image in a PDF const targetElement = document.getElementById('alienOutputArea'); // Capture the whole area const speciesName = document.getElementById('alienDescription')?.querySelector('h4')?.innerText || 'Alien-Species'; const pdfFilename = `${speciesName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_visual.pdf`; console.log(`/* DEBUG ${uniqueId}: */ PDF Filename (html2canvas): ${pdfFilename}`); html2canvas(targetElement, { scale: 2, // Higher scale for better quality image useCORS: true, // Important if using external resources like web fonts backgroundColor: '#ffffff', // Force white background for capture consistency logging: false // Disable excessive logging from html2canvas unless debugging it specifically }) .then(canvas => { console.log(`/* DEBUG ${uniqueId}: */ html2canvas capture successful.`); const imgData = canvas.toDataURL('image/png'); const imgProps = { width: canvas.width, height: canvas.height }; // Determine PDF orientation based on captured image aspect ratio const orientation = imgProps.width >= imgProps.height ? 'l' : 'p'; // Landscape if wider/square const doc = new jsPDF(orientation, 'pt', 'a4'); console.log(`/* DEBUG ${uniqueId}: */ jsPDF object created. Orientation: ${orientation}`); const page = doc.internal.pageSize; const margin = 40; // PDF margin in points const pageWidth = page.getWidth() - (margin * 2); const pageHeight = page.getHeight() - (margin * 2); // Calculate scaling to fit image within margins const scale = Math.min(pageWidth / imgProps.width, pageHeight / imgProps.height); const scaledWidth = imgProps.width * scale; const scaledHeight = imgProps.height * scale; // Center the image const marginLeft = (page.getWidth() - scaledWidth) / 2; const marginTop = (page.getHeight() - scaledHeight) / 2; console.log(`/* DEBUG ${uniqueId}: */ Adding image from html2canvas to PDF. Scaled W: ${scaledWidth}, H: ${scaledHeight}`); doc.addImage(imgData, 'PNG', marginLeft, marginTop, scaledWidth, scaledHeight); console.log(`/* DEBUG ${uniqueId}: */ Attempting doc.save() for html2canvas PDF...`); try { doc.save(pdfFilename); console.log(`/* DEBUG ${uniqueId}: */ doc.save() issued.`); } catch (saveError) { console.error(`/* DEBUG ${uniqueId}: */ Error during doc.save() [html2canvas]:`, saveError); errorMsgDiv.textContent = "Error saving the PDF (html2canvas). See console."; } // Re-enable button and restore text if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } console.log(`/* DEBUG ${uniqueId}: */ html2canvas PDF process finished.`); }) .catch(err => { // Catch errors from html2canvas promise itself console.error(`/* DEBUG ${uniqueId}: */ Error during html2canvas capture:`, err); errorMsgDiv.textContent = "Error capturing alien details image for PDF. See console."; // Re-enable button if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } }); } catch (error) { // Catch errors in the setup *before* html2canvas runs console.error(`/* DEBUG ${uniqueId}: */ Error setting up html2canvas generation:`, error); errorMsgDiv.textContent = "Setup error for PDF generation (html2canvas). See console."; // Re-enable button if(downloadBtn) { downloadBtn.disabled = false; downloadBtn.textContent = 'Download as PDF'; downloadBtn.style.opacity = '1'; } } }, 10); // Small delay (10ms) allows UI to update with "Processing..." } // End of downloadPDF // --- Attach Event Listeners --- if(customGenBtn) customGenBtn.addEventListener('click', () => generateAlien(false)); else console.error("Custom Gen Button not found"); if(randomGenBtn) randomGenBtn.addEventListener('click', () => generateAlien(true)); else console.error("Random Gen Button not found"); if(downloadBtn) downloadBtn.addEventListener('click', downloadPDF); else console.error("Download Button not found"); // Initialize first tab const firstTabButton = document.querySelector('.alien-tab-button'); if (firstTabButton) { const onclickAttr = firstTabButton.getAttribute('onclick'); const match = onclickAttr ? onclickAttr.match(/openAlienTab\(.*?,\s*'([^']+)'\s*\)/) : null; if (match && match[1]) { const firstTabName = match[1]; openAlienTab(null, firstTabName); } else { console.error("Could not extract first tab name from onclick attribute:", onclickAttr); openAlienTab(null, 'CustomizeTab'); } } else { console.error("Could not find the first tab button to initialize."); openAlienTab(null, 'CustomizeTab'); } // Add CSS Keyframes for animations const styleSheet = document.createElement("style"); styleSheet.type = "text/css"; styleSheet.innerText = `@keyframes alienBlobAnim { 0% { border-radius: 60% 40% 30% 70% / 50% 60% 40% 50%; } 50% { border-radius: 30% 70% 70% 30% / 60% 40% 60% 40%; } 100% { border-radius: 60% 40% 30% 70% / 50% 60% 40% 50%; } } @keyframes alienPulseAnim { 0% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.05); } 100% { opacity: 0.7; transform: scale(1); } } @keyframes alienShiftAnim { 0% { transform: rotate(15deg) scale(1); border-radius: 10% 90% 30% 70% / 70% 20% 80% 30%;} 50% { transform: rotate(-10deg) scale(1.02); border-radius: 70% 30% 90% 10% / 20% 80% 30% 70%;} 100% { transform: rotate(15deg) scale(1); border-radius: 10% 90% 30% 70% / 70% 20% 80% 30%;} }`; document.head.appendChild(styleSheet); console.log("Alien Creator Tool Initialized."); } // End of initializeAlienCreator // --- Run Initialization --- if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeAlienCreator); } else { initializeAlienCreator(); // DOM already loaded }
Scroll to Top