import React, { useRef, useEffect, useState, useCallback } from ‘react’;
// Main App Component
const App = () => {
const canvasRef = useRef(null);
const animationFrameId = useRef(null);
const [syncLevel, setSyncLevel] = useState(0); // 0 to 1 for synchronization
const [waves, setWaves] = useState([]);
const [isSyncing, setIsSyncing] = useState(false);
// Initial setup for waves
const initializeWaves = useCallback(() => {
const numWaves = 8;
const initialWaves = Array.from({ length: numWaves }).map((_, i) => ({
amplitude: 30 + Math.random() * 20, // Varying amplitude
frequency: 0.02 + Math.random() * 0.01, // Slightly varying frequency
phase: Math.random() * Math.PI * 2, // Random initial phase
color: `hsl(${i * (360 / numWaves) + 240}, 80%, 70%)`, // HSL for blue-purple range
// Add a target phase for synchronization
targetPhase: 0, // Will be updated to a common phase
}));
setWaves(initialWaves);
setSyncLevel(0);
setIsSyncing(false);
}, []);
useEffect(() => {
initializeWaves();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Drawing function for the canvas
const draw = useCallback(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext(‘2d’);
const { width, height } = canvas;
ctx.clearRect(0, 0, width, height); // Clear canvas
const centerY = height / 2;
waves.forEach(wave => {
ctx.beginPath();
ctx.strokeStyle = wave.color;
ctx.lineWidth = 2;
ctx.shadowBlur = 10;
ctx.shadowColor = wave.color;
for (let x = 0; x < width; x++) {
// Calculate y based on sine wave
const y = centerY + Math.sin(x * wave.frequency + wave.phase) * wave.amplitude;
if (x === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
});
}, [waves]);
// Animation loop
const animate = useCallback(() => {
setWaves(prevWaves => {
const newWaves = prevWaves.map(wave => {
let newPhase = wave.phase + 0.05; // Base movement
if (isSyncing) {
// Gradually pull phase towards a common target phase based on syncLevel
const commonTargetPhase = prevWaves[0].targetPhase; // Use the first wave as a reference
const phaseDifference = commonTargetPhase – newPhase;
// Normalize phase difference to be between -PI and PI
const normalizedPhaseDifference = (phaseDifference + Math.PI * 3) % (Math.PI * 2) – Math.PI;
newPhase += normalizedPhaseDifference * syncLevel * 0.05; // Adjust based on syncLevel
}
return { …wave, phase: newPhase };
});
return newWaves;
});
draw(); // Redraw waves
animationFrameId.current = requestAnimationFrame(animate);
}, [draw, isSyncing, syncLevel]);
useEffect(() => {
// Start animation loop
animationFrameId.current = requestAnimationFrame(animate);
// Cleanup on unmount
return () => {
if (animationFrameId.current) {
cancelAnimationFrame(animationFrameId.current);
}
};
}, [animate]);
// Handler for synchronization button
const handleSyncToggle = () => {
if (!isSyncing) {
// When starting sync, set a common target phase for all waves
setWaves(prevWaves => prevWaves.map(wave => ({ …wave, targetPhase: prevWaves[0].phase })));
setSyncLevel(0.5); // Start with a moderate sync level
} else {
setSyncLevel(0); // Reset sync level
}
setIsSyncing(prev => !prev);
};
// Handler for slider change
const handleSliderChange = (e) => {
setSyncLevel(parseFloat(e.target.value));
if (parseFloat(e.target.value) > 0 && !isSyncing) {
// If slider is moved to sync and not already syncing, set target phase
setWaves(prevWaves => prevWaves.map(wave => ({ …wave, targetPhase: prevWaves[0].phase })));
setIsSyncing(true);
} else if (parseFloat(e.target.value) === 0 && isSyncing) {
setIsSyncing(false);
}
};
return (
Resonance & Conscious Experience
Observe how individual oscillations (representing neural activity) can synchronize, leading to a state of heightened coherence, analogous to conscious awareness.
);
};
export default App;