Virtual Mystery Story Generator

Click the button below to generate the core elements for your next mystery story!

${generatedData.detective}

`; resultsDiv.style.display = 'block'; pdfBtn.disabled = false; // Enable PDF button } function downloadPDF() { if (!generatedData || Object.keys(generatedData).length === 0) { console.error("No data generated to create PDF."); alert("Please generate story elements first."); return; } // Ensure jsPDF is loaded if (typeof jspdf === 'undefined') { console.error("jsPDF library is not loaded."); alert("Error: PDF generation library failed to load. Please check your internet connection or try again later."); return; } const { jsPDF } = jspdf; const doc = new jsPDF(); // --- PDF Styling --- const primaryColor = '#4a69bd'; // Match CSS --mystery-primary const textColor = '#333333'; // Match CSS --mystery-text const secondaryColor = '#7f8c8d'; // Match CSS --mystery-secondary const pageMargin = 15; const lineSpacing = 7; const sectionSpacing = 10; let currentY = pageMargin; // Start position // Helper function to add text and move down function addText(text, size, color, isBold = false) { if (currentY > 280) { // Basic check for page break (adjust as needed) doc.addPage(); currentY = pageMargin; } doc.setFontSize(size); doc.setTextColor(color); doc.setFont(undefined, isBold ? 'bold' : 'normal'); // Set font style // Use splitTextToSize for basic word wrapping const splitText = doc.splitTextToSize(text, doc.internal.pageSize.width - pageMargin * 2); doc.text(splitText, pageMargin, currentY); currentY += (splitText.length * lineSpacing) - (lineSpacing/2); // Adjust Y position based on number of lines } function addHeading(text) { addText(text, 14, primaryColor, true); // Add a small gap after heading currentY += lineSpacing * 0.5; } function addSubHeading(text) { addText(text, 12, secondaryColor, true); } function addParagraph(text) { addText(text, 11, textColor); currentY += lineSpacing * 0.5; // Extra space after paragraph/list item } // --- PDF Content --- addText("Virtual Mystery Story Outline", 18, primaryColor, true); currentY += sectionSpacing; addHeading("Setting:"); addParagraph(generatedData.setting); addHeading("The Victim:"); addParagraph(generatedData.victim); addHeading("Potential Motive:"); addParagraph(generatedData.motive); addHeading("The Suspects:"); generatedData.suspects.forEach(suspect => { addParagraph(`- ${suspect}`); }); // Add a little extra space after the list currentY += lineSpacing * 0.5; addHeading("Key Clues:"); generatedData.clues.forEach(clue => { addParagraph(`- ${clue}`); }); // Add a little extra space after the list currentY += lineSpacing * 0.5; addHeading("The Detective:"); addParagraph(generatedData.detective); // --- Save PDF --- doc.save('mystery_story_outline.pdf'); } // --- Event Listeners --- generateBtn.addEventListener('click', generateMystery); pdfBtn.addEventListener('click', downloadPDF); })(); // Immediately invoke the function to encapsulate scope
Scroll to Top