const api: ModuleClientApi = new ModuleApi(); // Configuration with default values const config = { amplitude: 50, frequency: 1, speed: 1, color: '#4287f5', lineWidth: 3 }; // Get DOM elements const container = api.dom(); const canvas = container.querySelector('#sineCanvas') as HTMLCanvasElement; const ctx = canvas.getContext('2d'); // Animation variables let animationId: number; let startTime = Date.now(); // Initialize the canvas function initCanvas() { const rect = container.getBoundingClientRect(); canvas.width = rect.width; canvas.height = rect.height; } // Draw the sine wave function drawSineWave() { if (!ctx) return; // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Set line style ctx.strokeStyle = config.color; ctx.lineWidth = config.lineWidth; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; // Draw the wave const now = Date.now(); const elapsed = (now - startTime) / 1000; const timeOffset = elapsed * config.speed; ctx.beginPath(); // Start from the left side of the canvas const centerY = canvas.height / 2; for (let x = 0; x <= canvas.width; x++) { // Calculate the y position for each x point along the sine wave const xValue = x / canvas.width * Math.PI * 2 * config.frequency; const sineValue = Math.sin(xValue + timeOffset); const y = centerY + sineValue * config.amplitude; if (x === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // Request the next frame animationId = requestAnimationFrame(drawSineWave); } // Start the animation function startAnimation() { if (animationId) { cancelAnimationFrame(animationId); } startTime = Date.now(); animationId = requestAnimationFrame(drawSineWave); } // Handle window resize function handleResize() { initCanvas(); drawSineWave(); } // Setup property listeners api.onPropertyUpdate('amplitude', (value) => { config.amplitude = value; }); api.onPropertyUpdate('frequency', (value) => { config.frequency = value; }); api.onPropertyUpdate('speed', (value) => { config.speed = value; }); api.onPropertyUpdate('color', (value) => { config.color = value; }); api.onPropertyUpdate('lineWidth', (value) => { config.lineWidth = value; }); // Handle resize events api.onResize(() => { handleResize(); }); // Initialize window.addEventListener('load', () => { initCanvas(); startAnimation(); });