Interactive Historical Architecture Explorer

×

Style Name

Period:

Geographical Origin:

Key Characteristics:

    Famous Examples:

      ${style.period}

      ${style.origin}

      `; card.addEventListener('click', () => openArchModal(style)); gridContainer.appendChild(card); }); } function populateFilterDropdown() { const uniquePeriods = new Set(); architecturalStylesData.forEach(style => { uniquePeriods.add(getBroadPeriod(style.period, style.name)); }); uniquePeriods.forEach(period => { const option = document.createElement('option'); option.value = period; option.textContent = period; periodFilterEl.appendChild(option); }); } function filterAndRenderStyles() { const selectedPeriod = periodFilterEl.value; const searchTerm = searchTermEl.value.toLowerCase(); const filtered = architecturalStylesData.filter(style => { const matchesPeriod = selectedPeriod === 'all' || getBroadPeriod(style.period, style.name) === selectedPeriod; const matchesSearch = !searchTerm || style.name.toLowerCase().includes(searchTerm) || style.characteristics.some(char => char.toLowerCase().includes(searchTerm)) || style.examples.some(ex => ex.toLowerCase().includes(searchTerm)); return matchesPeriod && matchesSearch; }); renderStyleCards(filtered); } window.openArchModal = (style) => { currentStyleForPdf = style; // Store for PDF generation modalStyleNameEl.textContent = style.name; modalStylePeriodEl.textContent = style.period; modalStyleOriginEl.textContent = style.origin; modalStyleCharacteristicsEl.innerHTML = style.characteristics.map(char => `
    • ${char}
    • `).join(''); modalStyleExamplesEl.innerHTML = style.examples.map(ex => `
    • ${ex}
    • `).join(''); if (style.keyArchitects && style.keyArchitects.length > 0) { modalStyleKeyArchitectsEl.innerHTML = style.keyArchitects.map(arch => `
    • ${arch}
    • `).join(''); modalKeyArchitectsContainerEl.style.display = 'block'; } else { modalKeyArchitectsContainerEl.style.display = 'none'; } modalEl.style.display = "block"; }; window.closeArchModal = () => { modalEl.style.animation = "fadeOut 0.3s"; setTimeout(() => { modalEl.style.display = "none"; modalEl.style.animation = "fadeIn 0.3s"; // Reset for next open }, 280); }; // Close modal if clicked outside content window.onclick = function(event) { if (event.target == modalEl) { closeArchModal(); } } if (downloadStylePdfButtonEl) { downloadStylePdfButtonEl.addEventListener('click', () => { if (!currentStyleForPdf) { alert("No style data to download."); return; } if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: The jsPDF library (window.jspdf.jsPDF) could not be found.'); return; } const jsPDFConstructor = window.jspdf.jsPDF; // No complex table needed here, so autoTable check is less critical but good practice if features evolve. // const tempDoc = new jsPDFConstructor(); if (typeof tempDoc.autoTable !== 'function') { alert('jsPDF-AutoTable not found.');} const doc = new jsPDFConstructor('p', 'pt', 'a4'); const pageWidth = doc.internal.pageSize.getWidth(); const margin = 40; const usableWidth = pageWidth - 2 * margin; let yPos = margin; const style = currentStyleForPdf; doc.setFont('helvetica', 'bold'); doc.setFontSize(18); doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim()); const titleLines = doc.splitTextToSize(style.name, usableWidth); doc.text(titleLines, pageWidth / 2, yPos, { align: 'center' }); yPos += titleLines.length * 18 + 20; doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim()); function addDetail(label, value) { if (yPos > doc.internal.pageSize.getHeight() - margin - 20) { doc.addPage(); yPos = margin; } doc.setFont('helvetica', 'bold'); doc.text(label, margin, yPos); doc.setFont('helvetica', 'normal'); const valueLines = doc.splitTextToSize(value, usableWidth - 60); // Indent value slightly doc.text(valueLines, margin + 70, yPos); // Value starts after label yPos += Math.max(12, valueLines.length * 10 + 5); // Adjust for single line or multi-line } function addList(label, items) { if (!items || items.length === 0) return; if (yPos > doc.internal.pageSize.getHeight() - margin - 30) { doc.addPage(); yPos = margin; } doc.setFont('helvetica', 'bold'); doc.text(label, margin, yPos); yPos += 15; doc.setFont('helvetica', 'normal'); items.forEach(item => { if (yPos > doc.internal.pageSize.getHeight() - margin - 15) { doc.addPage(); yPos = margin; } const itemLines = doc.splitTextToSize(`• ${item}`, usableWidth - 10); doc.text(itemLines, margin + 10, yPos); yPos += itemLines.length * 10 + 3; }); yPos += 10; } addDetail("Period:", style.period); addDetail("Origin:", style.origin); addList("Key Characteristics:", style.characteristics); addList("Famous Examples:", style.examples); if (style.keyArchitects && style.keyArchitects.length > 0) { addList("Key Architects:", style.keyArchitects); } doc.setFontSize(8); doc.setTextColor(150); if (yPos > doc.internal.pageSize.getHeight() - 25) { doc.addPage(); yPos = margin; } doc.text(`Generated: ${new Date().toLocaleDateString()}`, margin, doc.internal.pageSize.getHeight() - (margin/2)); doc.save(`${style.name.replace(/\s+/g, '_')}_Architecture_Info.pdf`); }); } // Initialization populateFilterDropdown(); // Populate filter based on categorized data renderStyleCards(); // Initial render of all cards periodFilterEl.addEventListener('change', filterAndRenderStyles); searchTermEl.addEventListener('input', filterAndRenderStyles); });
      Scroll to Top