Current
Current
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vidyadarshan Electricity 10</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.
min.css" rel="stylesheet">
<style>
.canvas-container {
border: 1px solid #000;
touch-action: none;
background-color: white;
margin-bottom: 15px;
}
.concept-card {
cursor: pointer;
transition: all 0.3s;
}
.concept-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
#recognizedText {
white-space: pre-wrap;
font-family: monospace;
}
.tool-btn {
margin-bottom: 5px;
width: 100%;
}
.tool-btn.active {
background-color: #0d6efd;
color: white;
}
.color-option {
width: 25px;
height: 25px;
display: inline-block;
margin-right: 5px;
cursor: pointer;
border: 1px solid #ddd;
}
.selected-color {
border: 2px solid #000;
}
.section-title {
margin-top: 20px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #eee;
}
#questionBank {
max-height: 100px;
overflow-y: auto;
}
.question-item {
cursor: pointer;
padding: 5px;
border-bottom: 1px solid #eee;
}
.question-item:hover {
background-color: #f8f9fa;
}
.selected-question {
background-color: #e9ecef;
}
.custom-question-container {
margin-top: 15px;
}
.tab-button {
padding: 8px 15px;
border: 1px solid #dee2e6;
background-color: #f8f9fa;
cursor: pointer;
}
.tab-button.active {
background-color: #0d6efd;
color: white;
border-color: #0d6efd;
}
</style>
</head>
<body>
<div class="container-fluid mt-3">
<h1 class="text-center">VIDYADARSHAN PHYSICS AI TEACHER</h1>
<div class="row">
<!-- Left Column - Problem Input -->
<div class="col-md-6">
<h3 class="section-title">Problem Input</h3>
<div class="mb-3">
<label for="problemText" class="form-label">Selected Problem:</la
bel>
<textarea class="form-control" id="problemText" rows="6" readonly
></textarea>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="mb-3">
<h5>Tools</h5>
<button id="penTool" class="btn btn-outline-primary tool-btn ac
tive">Pen</button>
<button id="eraserTool" class="btn btn-outline-danger tool-btn"
>Eraser</button>
</div>
<div class="mb-3">
<h5>Pen Size</h5>
<input type="range" id="penSize" min="1" max="20" value="2" cl
ass="form-range">
</div>
<div class="mb-3">
<h5>Eraser Size</h5>
<input type="range" id="eraserSize" min="5" max="50" value="1
0" class="form-range">
</div>
<div class="mb-3">
<h5>Color</h5>
<div class="color-option selected-color" style="background-col
or: #000000;" data-color="#000000"></div>
<div class="color-option" style="background-color: #ff0000;" da
ta-color="#ff0000"></div>
<div class="color-option" style="background-color: #0000ff;" da
ta-color="#0000ff"></div>
<div class="color-option" style="background-color: #008000;" d
ata-color="#008000"></div>
</div>
</div>
<div class="col-md-4">
<button id="clearCanvas" class="btn btn-warning mb-3">Clear Ca
nvas</button>
<button id="recognizeBtn" class="btn btn-success mb-3">Analyze
Solution</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.b
undle.min.js"></script>
<script>
// Configuration - Replace with your actual Gemini API key
const GEMINI_API_KEY = 'AIzaSyDgBhaI9zWmolWSI0gIYh2Zrep4vAx62rw';
// Replace with your actual key
];
questionBank.forEach(question => {
const questionElement = document.createElement('div');
questionElement.className = 'question-item';
questionElement.textContent = `Question ${question.id}`;
questionElement.dataset.id = question.id;
questionElement.addEventListener('click', () => selectQuestion(questi
on.id));
questionBankElement.appendChild(questionElement);
});
}
bankTab.addEventListener('click', () => {
bankTab.classList.add('active');
customTab.classList.remove('active');
bankSection.style.display = 'block';
customSection.style.display = 'none';
});
customTab.addEventListener('click', () => {
customTab.classList.add('active');
bankTab.classList.remove('active');
customSection.style.display = 'block';
bankSection.style.display = 'none';
});
}
// Tool selection
document.getElementById('penTool').addEventListener('click', () => {
currentTool = 'pen';
document.getElementById('penTool').classList.add('active');
document.getElementById('eraserTool').classList.remove('active');
});
document.getElementById('eraserTool').addEventListener('click', () => {
currentTool = 'eraser';
document.getElementById('eraserTool').classList.add('active');
document.getElementById('penTool').classList.remove('active');
});
// Color selection
const colorOptions = document.querySelectorAll('.color-option');
colorOptions.forEach(option => {
option.addEventListener('click', () => {
currentColor = option.dataset.color;
ctx.strokeStyle = currentColor;
colorOptions.forEach(opt => opt.classList.remove('selected-color')
);
option.classList.add('selected-color');
});
});
function draw(e) {
if (!isDrawing) return;
lastX = pos.x;
lastY = pos.y;
}
function stopDrawing() {
isDrawing = false;
ctx.beginPath(); // Start a new path for the next stroke
}
function getPosition(e) {
let x, y;
if (e.type.includes('touch')) {
const touch = e.touches[0] || e.changedTouches[0];
const rect = canvas.getBoundingClientRect();
x = touch.clientX - rect.left;
y = touch.clientY - rect.top;
} else {
const rect = canvas.getBoundingClientRect();
x = e.clientX - rect.left;
y = e.clientY - rect.top;
}
return { x, y };
}
try {
// Convert canvas to image data
const imageData = canvas.toDataURL('image/png');
} catch (error) {
document.getElementById('errorAnalysis').textContent = `Error: ${er
ror.message}`;
document.getElementById('errorAnalysis').style.display = 'block';
} finally {
document.getElementById('loadingAnalysis').style.display = 'none';
}
});
try {
const response = await analyzeProblemWithGemini(problemText);
document.getElementById('problemAnalysis').innerHTML = `
<div class="card">
<div class="card-header">
Problem Analysis
</div>
<div class="card-body">
<h5 class="card-title">Key Concepts</h5>
<p class="card-text">${formatAsBullets(response.concepts)
}</p>
<h5 class="card-title">Expected Approach</h5>
<p class="card-text">${formatAsParagraphs(response.appro
ach)}</p>
<h5 class="card-title">Common Mistakes</h5>
<p class="card-text">${formatAsBullets(response.common_
mistakes)}</p>
</div>
</div>
`;
} catch (error) {
document.getElementById('problemAnalysis').innerHTML = `
<div class="alert alert-danger">Error analyzing problem: ${error.m
essage}</div>
`;
}
});
}
// Analyze solution using Gemini API (both image recognition and analysis
)
async function analyzeSolutionWithGemini(problemText, imageData) {
const prompt = `you are a physics teacher.Student ask problem from yo
u with:
1. A kinematics problem statement
2. An image of a student's handwritten solution to this problem
Please:
1. Extract and transcribe the handwritten solution text
2. Analyze the solution for mistakes
3. Provide the correct solution approach
4. Identify weak concepts
5. Suggest 2 that covers all weak concept for practice practice problems
Problem: ${problemText}`;
try {
return JSON.parse(response);
} catch {
// Fallback if JSON parsing fails
return {
recognized_text: "Could not recognize text",
mistakes: ["Analysis failed"],
correct_solution: "Could not analyze solution",
weak_concepts: [],
practice_problems: []
};
}
}
if (!response.ok) {
throw new Error(data.error?.message || 'Failed to call Gemini API');
}
return data.candidates?.[0]?.content?.parts?.[0]?.text || '';
}
// Concept explanations
if (analysis.weak_concepts && analysis.weak_concepts.length > 0) {
conceptDiv.innerHTML = '<h4>Concept Explanations</h4><div class=
"row" id="conceptCards"></div>';
const cardsContainer = document.getElementById('conceptCards');
analysis.weak_concepts.forEach(concept => {
const card = document.createElement('div');
card.className = 'col-md-6 mb-3';
card.innerHTML = `
<div class="card concept-card h-100">
<div class="card-header">
${concept}
</div>
<div class="card-body">
<p class="card-text">Loading explanation...</p>
</div>
</div>
`;
cardsContainer.appendChild(card);
// Practice problems
if (analysis.practice_problems && analysis.practice_problems.length > 0
){
practiceDiv.innerHTML = `
<div class="card">
<div class="card-header bg-success text-white">
Recommended Practice Problems
</div>
<div class="card-body">
${formatAsNumberedList(analysis.practice_problems)}
</div>
</div>
`;
} else {
practiceDiv.innerHTML = '';
}
}
cardElement.querySelector('.card-text').innerHTML = `
<p>${result.explanation || 'No explanation available'}</p>
${result.example ? `<div class="mt-2"><strong>Example:</strong> $
{result.example}</div>` : ''}
`;
} catch (error) {
cardElement.querySelector('.card-text').textContent = `Failed to load e
xplanation: ${error.message}`;
}
}
// Helper functions
function formatAsBullets(text) {
if (Array.isArray(text)) {
return `<ul>${text.map(item => `<li>${item}</li>`).join('')}</ul>`;
}
return `<ul><li>${text}</li></ul>`;
}
function formatAsNumberedList(items) {
if (Array.isArray(items)) {
return `<ol>${items.map(item => `<li>${item}</li>`).join('')}</ol>`;
}
return items;
}
function formatAsParagraphs(text) {
if (Array.isArray(text)) {
return text.map(para => `<p>${para}</p>`).join('');
}
return `<p>${text}</p>`;
}