...`. No meta tags needed for simplicity, but I'll include a viewport tag for mobile safety. * *CSS:* Reset margins/padding, set canvas to `display: block`, add some nice gradients or fonts (e.g., 'Inter', system-ui) for polish. Add a title overlay with a hint about dragging/moving bodies. * *JS - Setup:* Get the canvas element, get context (`ctx`), handle resizing. Define constants like gravity ($G$), initial body count (maybe 20-30). * *JS - Body Class/Object:* Create a class or factory function for a body with properties: `x`, `y`, `vx`, `vy`, `mass`, `color`. Maybe add a property for "age" to fade trails. * *JS - Initial Pop:* Function to spawn bodies either randomly distributed or at mouse position if clicked/dragged. For the initial state, I'll create them in a cluster near the center with slight random velocities so they don't just collapse instantly. * *JS - Physics Loop:* In `requestAnimationFrame`, clear canvas (or draw trails). For each body, calculate net force from all others: iterate over all bodies $j$, compute distance $r = \sqrt{(x_i-x_j)^2 + (y_i-y_j)^2}$, if $r > 0$ avoid division by zero, apply $F_x = G m_i m_j / r^2 * \Delta x$, same for $F_y$. Sum these forces. Update velocity: $v += F/m$. Update position. Optionally add damping or trail length logic (e.g., only draw if age < threshold). * *JS - Rendering:* Draw each body as a circle with gradient fill based on mass/velocity, maybe stroke for trails. Add stars in the background for visual depth. * *JS - Interaction:* Handle `mousedown`, `mousemove`, `mouseup` to spawn new bodies or scatter existing ones. This adds polish and interactivity. 5. **Refining Visuals & Polish:** * *Colors:* Use HSL or RGB gradients based on mass/velocity to make it look dynamic. Maybe dark background with bright trails. * *Trails:* Instead of clearing canvas every frame, I'll draw a semi-transparent rectangle over the whole screen each frame (`ctx.fillStyle = 'rgba(0,0,0,0.1)')` to create fading trails. This gives motion blur without needing extra buffers. * *Title Overlay:* Add an HTML overlay with a nice font and hint about dragging/interacting. 6. **Writing the Code (Mental Draft):** * Start with ``. * Add `` with meta viewport, title "Orbit — N-Body Gravity". * Style: CSS reset, canvas block, body flex-center. * Script tag: define constants ($G$, trail length). Define function `spawnBodies(x, y)` to create random initial conditions. In the main loop, calculate forces, update positions, draw stars and bodies. Add event listeners for mouse/touch. 7. **Self-Correction during drafting:** * *Issue:* If I clear canvas every frame, trails disappear instantly. *Fix:* Use `ctx.fillStyle = 'rgba(0,0,0,0.1)'` to draw over previous frames (fading effect). This is standard for particle effects. * *Issue:* Bodies might collapse too fast. *Fix:* Give them a minimum velocity or spread initial positions slightly apart with random directions. Also add some angular momentum by giving tangential velocities. * *Issue:* Too many bodies? *Fix:* Limit to ~30-40 initially, maybe spawn more on interaction. 8. **Final Polish:** Ensure all code is within one file, no external dependencies beyond basic canvas API. Test logic mentally: loop runs, forces calculated correctly, rendering updates trail effect, interactions work. Title hint present. Mobile-safe resizing handled via `window.addEventListener('resize', ...)` and maybe `touchstart`. 9. **Output Generation:** Produce the raw HTML string exactly as requested—no markdown fences, no extra text. Orbit — N-Body Gravity ⭐ Built in the Agent OS — get it inside the AI Profit BoardroomJoin AIPB →
Drag anywhere to scatter • Double-tap to reset