Science Vocabulary Builder Generator

Science Vocabulary Builder Generator

${item.definition || 'No definition provided.'}

Example Use:

"${item.exampleSentence || 'No example sentence provided.'}"

`; termsOutput.appendChild(card); }); resultsContainer.classList.remove('hidden'); downloadPdfBtn.classList.remove('hidden'); } // --- API UTILITY WITH BACKOFF --- async function fetchWithBackoff(url, options, delay = 1000, maxRetries = 5) { for (let i = 0; i < maxRetries; i++) { try { const response = await fetch(url, options); if (response.status === 429 && i < maxRetries - 1) { await new Promise(resolve => setTimeout(resolve, delay)); delay *= 2; continue; } if (!response.ok) { const errorData = await response.json(); throw new Error(`API Error ${response.status}: ${errorData.error?.message || response.statusText}`); } return response.json(); } catch (error) { if (i === maxRetries - 1) throw error; } } } // --- PDF GENERATION (Ensured to be robust) --- function generatePDF() { const { jsPDF } = window.jspdf; const container = document.getElementById('svbg-container'); const pdfWrapper = document.getElementById('svbg-pdf-wrapper'); // 1. Prepare for PDF capture by applying export styles container.classList.add('svbg-pdf-export-mode'); html2canvas(pdfWrapper, { scale: 2 }).then(canvas => { // 2. Restore original view container.classList.remove('svbg-pdf-export-mode'); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF('p', 'mm', 'a4'); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const imgWidth = pdfWidth - 20; // 10mm margin on each side const imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; // Top margin // Add image of the generated content, handling multiple pages pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= pdfHeight; while (heightLeft > -pdfHeight) { // Calculate position for the start of the next page to continue the image position = imgHeight - (pdfHeight * Math.floor(imgHeight / pdfHeight)); if (position > 0) position -= (pdfHeight * Math.floor(imgHeight / pdfHeight)); pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= pdfHeight; } const topic = topicInput.value.substring(0, 30).replace(/[^a-z0-9]/gi, '_').toLowerCase() || 'vocabulary'; pdf.save(`${topic}_vocabulary_sheet.pdf`); }).catch(err => { container.classList.remove('svbg-pdf-export-mode'); console.error("PDF generation failed:", err); alert("Could not generate PDF. See console for details."); }); } // --- TAB NAVIGATION --- window.svbg_changeTab = function(tabIndex) { if (tabIndex < 0 || tabIndex >= tabButtons.length) return; tabButtons.forEach((b, i) => { b.classList.toggle('active', i === tabIndex); b.classList.toggle('text-gray-500', i !== tabIndex); }); tabContents.forEach((c, i) => { c.classList.toggle('active', i === tabIndex); c.classList.toggle('hidden', i !== tabIndex); }); currentTab = tabIndex; prevBtn.style.visibility = currentTab === 0 ? 'hidden' : 'visible'; nextBtn.style.visibility = currentTab === tabButtons.length - 1 ? 'hidden' : 'visible'; } // --- ATTACH EVENT LISTENERS --- generateBtn.addEventListener('click', generateVocabulary); downloadPdfBtn.addEventListener('click', generatePDF); prevBtn.addEventListener('click', () => svbg_changeTab(currentTab - 1)); nextBtn.addEventListener('click', () => svbg_changeTab(currentTab + 1)); // Initial call to set up tab styling svbg_changeTab(0); }); })();
Scroll to Top