33800 Docs

← Retour

Canvas interactions directes - click, clic droit, scroll molette

Status : IMPLEMENTEE

Contexte

Le WS screencast fonctionne (receive-only). Les actions passent par REST avec boutons UI (Click mode, boutons scroll). On veut des interactions directes sur le canvas comme un vrai navigateur.

Approche

Ajouter des event listeners vanilla JS sur le canvas dans useVisibleTask$ (meme scope que le WS). Pas de QRL Qwik, pas de probleme de serialisation. Les messages sont envoyes via le WS deja ouvert.

Changements

1. Backend - Support clic droit (index.ts)

Dans le handler case 'click': du WS, ajouter le parametre button :

case 'click': {
  const button = msg.button === 'right' ? 'right' : 'left';
  await page.mouse.click(msg.x, msg.y, { button });
  // ...
}

1 ligne modifiee.

2. Frontend - Event listeners canvas (ScrapperTool.tsx)

Dans useVisibleTask$, apres ws.onopen, ajouter des listeners sur le canvas :

// Quand WS est pret, ajouter interactions directes sur le canvas
ws.onopen = () => {
  wsConnected.value = true;

  const canvas = canvasRef.value;
  if (!canvas) return;

  // Click gauche direct
  const handleClick = (e: MouseEvent) => {
    if (state.clickMode) return; // laisser le handler Qwik gerer le click mode REST
    const rect = canvas.getBoundingClientRect();
    const x = Math.round((e.clientX - rect.left) * (canvas.width / rect.width));
    const y = Math.round((e.clientY - rect.top) * (canvas.height / rect.height));
    ws.send(JSON.stringify({ type: 'click', x, y }));
  };

  // Click droit
  const handleContextMenu = (e: MouseEvent) => {
    e.preventDefault();
    const rect = canvas.getBoundingClientRect();
    const x = Math.round((e.clientX - rect.left) * (canvas.width / rect.width));
    const y = Math.round((e.clientY - rect.top) * (canvas.height / rect.height));
    ws.send(JSON.stringify({ type: 'click', x, y, button: 'right' }));
  };

  // Scroll molette
  const handleWheel = (e: WheelEvent) => {
    e.preventDefault();
    const direction = e.deltaY > 0 ? 'down' : 'up';
    ws.send(JSON.stringify({ type: 'scroll', direction, amount: Math.min(Math.abs(e.deltaY), 500) }));
  };

  canvas.addEventListener('click', handleClick);
  canvas.addEventListener('contextmenu', handleContextMenu);
  canvas.addEventListener('wheel', handleWheel, { passive: false });

  // Cleanup dans le cleanup existant
  cleanup(() => {
    canvas.removeEventListener('click', handleClick);
    canvas.removeEventListener('contextmenu', handleContextMenu);
    canvas.removeEventListener('wheel', handleWheel);
    ws.close();
  });
};

Ce qui ne change PAS