Online Virtual Reality Classroom Tool

Online Virtual Reality Classroom Tool

Session Details

Select a Virtual Classroom Layout

Layout Preview:

Layout Preview

Build Your Lesson Plan

Add New Activity

Session Agenda

No activities added yet.

VR Session Plan Summary

No activities added yet. Use the form above to build your agenda.

'; return; } activitiesList.innerHTML = sessionPlan.activities.map((activity, index) => `
${index + 1}

${activity.type}

${activity.description || 'No description'}

${activity.duration} min
`).join(''); updateSummary(); } /** * Adds a new activity to the session plan. */ function handleAddActivity() { const type = activityTypeInput.value; const description = activityDescriptionInput.value; const duration = parseInt(activityDurationInput.value); if (!duration || duration < 1) { alert('Please enter a valid duration in minutes.'); return; } sessionPlan.activities.push({ type, description, duration }); renderActivities(); // Clear input fields activityDescriptionInput.value = ''; activityDurationInput.value = ''; activityTypeInput.selectedIndex = 0; } /** * Removes an activity from the plan. Made globally accessible via window object. * @param {number} index - The index of the activity to remove. */ window.removeActivity = function(index) { sessionPlan.activities.splice(index, 1); renderActivities(); } /** * Updates the layout preview image based on selection. */ function updateLayoutPreview() { const layoutName = layoutSelect.value.replace(/\s+/g, '+'); layoutPreview.src = `https://placehold.co/600x400/E2E8F0/4A5568?text=${layoutName}`; layoutPreview.alt = `${layoutSelect.value} Layout Preview`; updateState(); } /** * Populates the summary tab with the current session plan data. */ function updateSummary() { const totalDuration = sessionPlan.activities.reduce((sum, act) => sum + act.duration, 0); summaryContent.innerHTML = `

Lesson: ${sessionPlan.title || 'Not Set'}

Total Duration: ${totalDuration} minutes

Learning Objectives:

${sessionPlan.objectives || 'Not specified.'}

Classroom Layout:

${sessionPlan.layout}

Agenda:

${sessionPlan.activities.length > 0 ? `
    ${sessionPlan.activities.map(act => `
  1. ${act.type} (${act.duration} min): ${act.description || 'No description'}
  2. `).join('')}
` : '

No activities planned.

'}
`; } /** * Handles tab switching logic. * @param {Event | null} evt - The click event, or null if called programmatically. * @param {string} tabName - The ID of the tab to switch to. */ window.changeTab = function(evt, tabName) { document.querySelectorAll(".tab-content").forEach(tc => tc.classList.remove('active')); document.querySelectorAll(".tab-button").forEach(tb => tb.classList.remove('active')); document.getElementById(tabName).classList.add('active'); const button = evt ? evt.currentTarget : document.querySelector(`.tab-button[onclick*="'${tabName}'"]`); if(button) button.classList.add('active'); currentTab = tabName; updateNavButtons(); if(tabName === 'summary-export') { updateSummary(); } } /** * Updates the visibility and state of the Next/Previous buttons. */ function updateNavButtons() { const currentIndex = tabs.indexOf(currentTab); prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex === tabs.length - 1; prevBtn.classList.toggle('opacity-50', prevBtn.disabled); prevBtn.classList.toggle('cursor-not-allowed', prevBtn.disabled); nextBtn.classList.toggle('opacity-50', nextBtn.disabled); nextBtn.classList.toggle('cursor-not-allowed', nextBtn.disabled); } /** * Navigates between tabs using Next/Previous buttons. * @param {string} direction - 'next' or 'prev'. */ window.navigateTabs = function(direction) { const currentIndex = tabs.indexOf(currentTab); let newIndex; if (direction === 'next' && currentIndex < tabs.length - 1) { newIndex = currentIndex + 1; } else if (direction === 'prev' && currentIndex > 0) { newIndex = currentIndex - 1; } if (newIndex !== undefined) { changeTab(null, tabs[newIndex]); } } /** * Handles the PDF download functionality. */ function downloadPDF() { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); html2canvas(pdfContent, { scale: 2, useCORS: true }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: '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 width = pdfWidth - 40; const height = width / ratio; // Check if content exceeds one page if (height > pdfHeight - 40) { alert("The content is too long for a single PDF page. Please shorten the plan."); return; } pdf.addImage(imgData, 'PNG', 20, 20, width, height); pdf.save('VR_Classroom_Plan.pdf'); }).catch(err => { console.error("Error generating PDF:", err); alert("Could not generate PDF. Please see the browser console for details."); }); } // --- EVENT LISTENERS --- lessonTitleInput.addEventListener('input', updateState); learningObjectivesInput.addEventListener('input', updateState); layoutSelect.addEventListener('change', updateLayoutPreview); addActivityBtn.addEventListener('click', handleAddActivity); downloadPdfBtn.addEventListener('click', downloadPDF); // --- INITIALIZATION --- renderActivities(); updateSummary(); updateNavButtons(); });
Scroll to Top