Hero’s Journey Story Generator

Hero’s Journey Story Generator

Craft a timeless narrative using the 12-stage monomyth framework.

Part I: The Beginning

Part II: The Call to Adventure

Part III: Entering the New World

Part IV: The Ordeal & Reward

Part V: The Journey Home

Your Completed Story Outline

Your story outline will appear here once you fill out the previous steps and click "Generate Story".

An error occurred. A form field is missing from the page.

'; showTab(tabs.length - 1); return; } if (!storyData['hero-name']) { resultsContainer.innerHTML = '

Please provide a name for your hero before generating the story.

'; showTab(tabs.length - 1); return; } let htmlOutput = '
'; for(const id in stageTitles) { if(storyData[id]){ htmlOutput += `

${stageTitles[id]}

${storyData[id]}

`; } } htmlOutput += '
'; resultsContainer.innerHTML = htmlOutput; pdfButtonContainer.style.display = 'block'; showTab(tabs.length - 1); }; const downloadPDF = () => { try { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const storyData = {}; stageIds.forEach(id => storyData[id] = document.getElementById(id)?.value || 'N/A'); const heroName = storyData['hero-name'] || 'Untitled Story'; const pageHeight = doc.internal.pageSize.getHeight(); const pageWidth = doc.internal.pageSize.getWidth(); const margin = 18; let cursorY = margin; // --- PDF Header --- doc.setFont('times', 'bold'); doc.setFontSize(26); doc.setTextColor(45, 22, 82); doc.text("The Hero's Journey", pageWidth / 2, cursorY, { align: 'center' }); cursorY += 10; doc.setFont('times', 'italic'); doc.setFontSize(16); doc.setTextColor(100, 100, 100); doc.text(`A Story Outline for ${heroName}`, pageWidth / 2, cursorY, { align: 'center' }); cursorY += 15; doc.setDrawColor(200, 200, 200); doc.line(margin, cursorY, pageWidth - margin, cursorY); cursorY += 12; // --- Helper function for story sections --- const addStorySection = (title, content) => { const contentLines = doc.splitTextToSize(content, pageWidth - margin * 2); const sectionHeight = 8 + (contentLines.length * 5); // Title height + text height if (cursorY + sectionHeight > pageHeight - margin) { doc.addPage(); cursorY = margin; } doc.setFontSize(14); doc.setFont('times', 'bold'); doc.setTextColor(0, 0, 0); doc.text(title, margin, cursorY); cursorY += 7; doc.setFont('times', 'normal'); doc.setFontSize(11); doc.setTextColor(55, 65, 81); doc.text(contentLines, margin, cursorY); cursorY += (contentLines.length * 5) + 10; }; // --- Build PDF Sections --- for(const id in stageTitles) { if(id !== 'hero-name' && storyData[id] && storyData[id] !== 'N/A') { addStorySection(stageTitles[id], storyData[id]); } } // --- Footer --- const pageCount = doc.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { doc.setPage(i); doc.setFontSize(9); doc.setTextColor(150); const footerText = `Page ${i} of ${pageCount} | ${heroName}`; doc.text(footerText, pageWidth / 2, pageHeight - 10, { align: 'center' }); } doc.save(`${heroName.replace(/\s+/g, '_')}_Heros_Journey.pdf`); } catch (error) { console.error("Failed to generate PDF:", error); const pdfButtonContainer = document.getElementById('pdf-button-container'); if (pdfButtonContainer && !pdfButtonContainer.querySelector('.error-msg')) { const errorMsg = document.createElement('p'); errorMsg.textContent = 'Sorry, an error occurred while creating the PDF.'; errorMsg.className = 'text-red-500 text-sm mt-2 error-msg'; pdfButtonContainer.appendChild(errorMsg); } } }; // Event Listeners prevButton.addEventListener('click', () => navigate(-1)); nextButton.addEventListener('click', () => navigate(1)); generateButton.addEventListener('click', generateStory); downloadPdfButton.addEventListener('click', downloadPDF); // Initial setup showTab(0); });
Scroll to Top