Skip to content

Mouse & Click Tracking

Open the editor to try click spawning live.

How Clicks Work

Canvas clicks write state.clickX and state.clickY. Your code reads them and must clear them.

javascript
if (!state.init) {
  state.particles = [];
  state.init = true;
}

if (state.clickX !== undefined) {
  for (let i = 0; i < 5; i++) {
    const angle = Math.random() * Math.PI * 2;
    const speed = 50 + Math.random() * 150;
    state.particles.push({
      x: state.clickX,
      y: state.clickY,
      vx: Math.cos(angle) * speed,
      vy: Math.sin(angle) * speed,
      life: 1,
    });
  }
  state.clickX = undefined;
  state.clickY = undefined;
}

state.particles = state.particles.filter((p) => {
  p.x += p.vx * dt;
  p.y += p.vy * dt;
  p.vy += 100 * dt;
  p.life -= dt;
  return p.life > 0;
});

return {
  particles: state.particles.map((p) => ({
    x: p.x,
    y: p.y,
    r: 3 + p.life * 4,
    color: `rgba(139,92,246,${p.life})`,
  })),
  text: {
    hint: 'Click the canvas',
    Particles: state.particles.length,
  },
};

Click Lifecycle

User clicks canvas
  → engine sets state.clickX / state.clickY
  → your code reads them
  → you set both to undefined
  → next frames see no click until the next press

If you never clear them, the same click is handled every frame.

Coordinate System

Same as drawing space:

OriginXY
Top-leftRightwardDownward

Center ≈ (w/2, h/2). Bottom-right ≈ (w, h). Values already account for device pixel ratio.

Patterns

Spawn at click

javascript
if (state.clickX !== undefined) {
  state.particles.push({ x: state.clickX, y: state.clickY, vx: 0, vy: 0 });
  state.clickX = undefined;
  state.clickY = undefined;
}

Move toward click

javascript
if (state.clickX !== undefined) {
  state.targetX = state.clickX;
  state.targetY = state.clickY;
  state.clickX = undefined;
  state.clickY = undefined;
}

if (state.targetX !== undefined) {
  state.x += (state.targetX - state.x) * 3 * dt;
  state.y += (state.targetY - state.y) * 3 * dt;
}

Count clicks

javascript
if (!state.init) {
  state.clickCount = 0;
  state.init = true;
}

if (state.clickX !== undefined) {
  state.clickCount++;
  state.clickX = undefined;
  state.clickY = undefined;
}

WARNING

Forgetting to clear clickX / clickY causes continuous spawning or tracking. Always consume after handling.

Keyboard Input

Combine mouse clicks with keyboard input via the keys global. See the Keyboard Input guide for details and game-building patterns.

What Is Not Supported

Hover, drag, and mousemove are not currently available.