neural-network-playground / js /animation-fixes.js
ameerazam08's picture
Upload 22 files
a895648 verified
// Animation Fixes Script - Patches common animation issues
(function() {
console.log('Animation Fixes Script Loaded');
// Wait for DOM content to be loaded
document.addEventListener('DOMContentLoaded', function() {
console.log('Applying animation fixes');
// 1. Fix for missing canvas elements
const expectedCanvases = [
{ id: 'backprop-canvas', container: '.animation-container', tab: 'backpropagation-tab' },
{ id: 'forward-canvas', container: '.forward-visualization', tab: 'forward-propagation-tab' },
{ id: 'background-canvas', container: '.background-visualization', tab: 'background-animation-tab' }
];
expectedCanvases.forEach(canvasInfo => {
const canvas = document.getElementById(canvasInfo.id);
const container = document.querySelector(`#${canvasInfo.tab} ${canvasInfo.container}`);
if (!canvas && container) {
console.log(`Creating missing canvas: ${canvasInfo.id}`);
const newCanvas = document.createElement('canvas');
newCanvas.id = canvasInfo.id;
newCanvas.className = 'animation-canvas';
newCanvas.width = container.clientWidth || 800;
newCanvas.height = container.clientHeight || 400;
container.prepend(newCanvas);
// Try drawing something to show the canvas is working
const ctx = newCanvas.getContext('2d');
if (ctx) {
ctx.fillStyle = 'rgba(200, 200, 255, 0.3)';
ctx.fillRect(0, 0, newCanvas.width, newCanvas.height);
ctx.fillStyle = '#333';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.fillText(`Canvas ${canvasInfo.id} initialized`, newCanvas.width/2, newCanvas.height/2);
}
}
});
// 2. Fix for animation scripts not running
// Capture tab change events and force canvas initialization
document.addEventListener('tabSwitch', function(e) {
const tabId = e.detail.tab;
console.log(`Tab switch detected to: ${tabId}`);
setTimeout(() => {
// Force canvas initialization after tab switch
switch(tabId) {
case 'backpropagation':
initBackpropCanvas();
break;
case 'forward-propagation':
initForwardCanvas();
break;
case 'background-animation':
initBackgroundCanvas();
break;
}
}, 100);
});
// Helper functions to initialize canvases if the main scripts fail
function initBackpropCanvas() {
const canvas = document.getElementById('backprop-canvas');
if (!canvas) return;
if (typeof window.initBackpropCanvas === 'function') {
window.initBackpropCanvas();
} else {
const ctx = canvas.getContext('2d');
if (ctx) {
drawPlaceholderNetwork(ctx, canvas.width, canvas.height, 'Backpropagation');
}
}
}
function initForwardCanvas() {
const canvas = document.getElementById('forward-canvas');
if (!canvas) return;
if (typeof window.initForwardPropCanvas === 'function') {
window.initForwardPropCanvas();
} else {
const ctx = canvas.getContext('2d');
if (ctx) {
drawPlaceholderNetwork(ctx, canvas.width, canvas.height, 'Forward Propagation');
}
}
}
function initBackgroundCanvas() {
const canvas = document.getElementById('background-canvas');
if (!canvas) return;
if (typeof window.initBackgroundCanvas === 'function') {
window.initBackgroundCanvas();
} else {
const ctx = canvas.getContext('2d');
if (ctx) {
drawPlaceholderNeurons(ctx, canvas.width, canvas.height);
}
}
}
// Helper drawing functions
function drawPlaceholderNetwork(ctx, width, height, title) {
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Draw background
ctx.fillStyle = '#f8f9fa';
ctx.fillRect(0, 0, width, height);
// Define network layout
const layers = [3, 4, 2]; // Input, hidden, output layers
const neuronRadius = 20;
const layerSpacing = width / (layers.length + 1);
// Function to calculate neuron positions
function getNeuronPosition(layerIndex, neuronIndex, totalNeurons) {
const x = layerSpacing * (layerIndex + 1);
const layerHeight = totalNeurons * (neuronRadius * 2 + 10);
const startY = (height - layerHeight) / 2 + neuronRadius;
const y = startY + neuronIndex * (neuronRadius * 2 + 10);
return { x, y };
}
// Draw connections first (so they appear behind neurons)
ctx.strokeStyle = '#aaa';
ctx.lineWidth = 1;
// For each layer except the last
for (let layerIndex = 0; layerIndex < layers.length - 1; layerIndex++) {
const sourceLayer = layers[layerIndex];
const targetLayer = layers[layerIndex + 1];
// Connect each neuron in source layer to each neuron in target layer
for (let sourceNeuron = 0; sourceNeuron < sourceLayer; sourceNeuron++) {
const source = getNeuronPosition(layerIndex, sourceNeuron, sourceLayer);
for (let targetNeuron = 0; targetNeuron < targetLayer; targetNeuron++) {
const target = getNeuronPosition(layerIndex + 1, targetNeuron, targetLayer);
// Draw connection
ctx.beginPath();
ctx.moveTo(source.x, source.y);
ctx.lineTo(target.x, target.y);
ctx.stroke();
}
}
}
// Draw neurons
const layerColors = ['#6495ED', '#7B68EE', '#9370DB']; // Different color for each layer
for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) {
const neuronsInLayer = layers[layerIndex];
for (let neuronIndex = 0; neuronIndex < neuronsInLayer; neuronIndex++) {
const { x, y } = getNeuronPosition(layerIndex, neuronIndex, neuronsInLayer);
// Draw neuron circle
ctx.beginPath();
ctx.arc(x, y, neuronRadius, 0, Math.PI * 2);
ctx.fillStyle = layerColors[layerIndex];
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
}
}
// Add title
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.font = 'bold 20px Arial';
ctx.textAlign = 'center';
ctx.fillText(title + ' Animation', width/2, 40);
// Add message
ctx.font = '16px Arial';
ctx.fillText('Animation placeholder - Check console for errors', width/2, height - 30);
}
function drawPlaceholderNeurons(ctx, width, height) {
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Draw background
ctx.fillStyle = '#f8f9fa';
ctx.fillRect(0, 0, width, height);
// Create random neurons
const neurons = [];
const neuronCount = 50;
for (let i = 0; i < neuronCount; i++) {
neurons.push({
x: Math.random() * width,
y: Math.random() * height,
radius: 3 + Math.random() * 5,
color: Math.random() > 0.8 ? '#6495ED' : '#aaaaaa'
});
}
// Draw connections
ctx.strokeStyle = 'rgba(170, 170, 170, 0.3)';
ctx.lineWidth = 1;
for (let i = 0; i < neurons.length; i++) {
const source = neurons[i];
// Connect to nearby neurons
for (let j = i + 1; j < neurons.length; j++) {
const target = neurons[j];
const distance = Math.sqrt(
Math.pow(target.x - source.x, 2) +
Math.pow(target.y - source.y, 2)
);
// Only connect neurons that are close enough
if (distance < 100) {
ctx.beginPath();
ctx.moveTo(source.x, source.y);
ctx.lineTo(target.x, target.y);
ctx.stroke();
}
}
}
// Draw neurons
neurons.forEach(neuron => {
ctx.beginPath();
ctx.arc(neuron.x, neuron.y, neuron.radius, 0, Math.PI * 2);
ctx.fillStyle = neuron.color;
ctx.fill();
});
// Add title
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.font = 'bold 20px Arial';
ctx.textAlign = 'center';
ctx.fillText('Neural Background Animation', width/2, 40);
// Add message
ctx.font = '16px Arial';
ctx.fillText('Animation placeholder - Check console for errors', width/2, height - 30);
}
// Initial setup - activate the currently selected tab
const activeTabButton = document.querySelector('.tab-button.active');
if (activeTabButton) {
const tabId = activeTabButton.getAttribute('data-tab');
console.log(`Initial active tab: ${tabId}`);
// If the tab manager is loaded, use its function
if (window.activateTab) {
window.activateTab(tabId);
} else {
// Fallback - directly trigger the tab switch event
document.dispatchEvent(new CustomEvent('tabSwitch', {
detail: { tab: tabId }
}));
}
}
});
})();