summary refs log blame commit diff stats
path: root/TODO
blob: b1bad60a1b27e331b61ace61a63b03d3e05e2afb (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */
Console

   (X) #0   09/12/06  console commands
   (X) #1   09/12/06  quick find
   ( ) #2   09/12/06  open with
   ( ) #3   09/12/06  MVC for widgets
   (X) #4   09/12/06  history for console


General

   (X) #5   09/12/06  move code from fm into objects
   (X) #6   09/12/06  move main to __init__
   (X) #7   09/12/06  cooler titlebar
   ( ) #9   09/12/24  add a widget for managing running operations
   (X) #10  09/12/24  sorting


Filesystem Modification Operations

   (X) #8   09/12/17  Add operations to modify files/directories
overflow: hidden; display: flex; flex-direction: column; height: 100%; } canvas { display: block; width: 100%; background-color: beige; } .controls { display: flex; justify-content: space-around; padding: 10px; background-color: white; box-shadow: 0 -2px 5px rgba(0,0,0,0.1); } input, button { font-size: 1.5rem; } </style> </head> <body> <canvas id="sandCanvas"></canvas> <div class="controls"> <input type="number" id="bpmInput" value="60" min="10" max="300"> <div> <button id="clearSand">Clear</button> <button id="toggleButton">Start</button> </div> </div> <script> const canvas = document.getElementById('sandCanvas'); const ctx = canvas.getContext('2d'); const bpmInput = document.getElementById('bpmInput'); const toggleButton = document.getElementById('toggleButton'); const clearSandButton = document.getElementById('clearSand'); const controls = document.querySelector('.controls'); let bpm = 60; let isRunning = false; let sandParticles = []; let intervalId; // Set canvas size to avoid overlapping with controls function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight - controls.offsetHeight; } window.addEventListener('resize', resizeCanvas); resizeCanvas(); const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); function playTone() { const oscillator = audioCtx.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // 440 Hz tone oscillator.connect(audioCtx.destination); oscillator.start(); oscillator.stop(audioCtx.currentTime + 0.1); // Short beep } function createSandParticle() { return { x: Math.random() * canvas.width, y: 0, size: 5 + Math.random() * 5, // Vary size a bit velocityY: 0, atRest: false // Track if the particle is at rest }; } // Update sand particle positions function updateSand() { for (let particle of sandParticles) { if (!particle.atRest) { particle.velocityY += 0.1; // Accelerate! Gravity! particle.y += particle.velocityY; // Check if sand particle has hit the bottom if (particle.y + particle.size >= canvas.height) { particle.y = canvas.height - particle.size; particle.atRest = true; // Mark the particle as at rest } // Check if sand particle has landed on another particle for (let otherParticle of sandParticles) { if (otherParticle !== particle && otherParticle.atRest) { let distY = otherParticle.y - (particle.y + particle.size); let distX = Math.abs(otherParticle.x - particle.x); if (distY <= 0 && distX < particle.size) { particle.y = otherParticle.y - particle.size; particle.atRest = true; break; } } } } } } // Draw sand particles on the canvas function drawSand() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'teal'; for (let particle of sandParticles) { ctx.beginPath(); ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2); ctx.fill(); } } // Main loop function gameLoop() { updateSand(); drawSand(); } // Control the BPM and start/stop the loop function toggleBPM() { isRunning = !isRunning; if (isRunning) { let interval = (60 / bpm) * 1000; // Convert BPM to interval in milliseconds intervalId = setInterval(() => { sandParticles.push(createSandParticle()); // Generate new sand playTone(); // Play the tone }, interval); toggleButton.textContent = 'Stop'; } else { clearInterval(intervalId); toggleButton.textContent = 'Start'; } } // Event Listeners toggleButton.addEventListener('click', toggleBPM); clearSandButton.addEventListener('click', () => { sandParticles = []; }); bpmInput.addEventListener('input', (e) => { bpm = parseInt(e.target.value); if (isRunning) { clearInterval(intervalId); toggleBPM(); } }); function animate() { gameLoop(); requestAnimationFrame(animate); } animate(); </script> </body> </html>