Zrobimy sobie ciekawe ćwiczenie z mouse events. Później to sobie jeszcze rozbudujemy. Do dzieła.

Ok, najpierw markup:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div></div>
    <script type="module" src="./main.js"></script>
</body>
</html>

Do rzeczy z type module potrzebujemy serwera, może być live server, może być xampp i tam te pliki wrzucamy i otwieramy przez localhosta przez http, nie file…

Ok, szybki CSS:

body {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}


div {
    width: 1200px;
    height: 600px;
    background-color: teal;
}

Funkcje symulujące rysowanie, które będzie eksportować i będą importowane w type module:

export function drawCircle(centerX, centerY) {
    console.log(`Drawing circle with center X:${centerX} Y:${centerY}`);
}

export function drawLine(startX, startY, endX, endY) {
    console.log(`Drawing line. StartX:${startX} StartY: ${startY} EndX: ${endX} EndY: ${endY}`);
}

Teraz nasz moduł:

import { drawCircle, drawLine } from "./drawing.js";

let isPressed = false;
let x;
let y;

let div = document.querySelector("div");

Pamiętamy ripple effect? I offsetX/Y? Ok, nasz listener na mousedown:

div.addEventListener('mousedown', (e) => {
    isPressed = true;

    x = e.offsetX;
    y = e.offsetY;
})

Po pierwsze, mousedown zmienia nam isPressed na true, sygnalizuje, że mysz została kliknięta. Po drugie, zapisuje początkowe koordynaty, gdzie została kliknięta (końcowe będziemy mieli w e.offsetX/Y w mousemove).

To teraz co się ma stać gdy zwolnimy przycisk myszy i gdzie:

document.addEventListener('mouseup', (e) => {
    isPressed = false;

    x = undefined;
    y = undefined;
})

Nieważne, gdzie mysz zwolnimy, ma być aktualizacja, że nie jest już wciśnięta, nie ma też już początkowych koordynatów.

Teraz pozostaje nam samo rysowanie:

div.addEventListener('mousemove', (e) => {
    if(isPressed) {
        const x2 = e.offsetX;
        const y2 = e.offsetY;

        drawCircle(x2, y2);
        drawLine(x, y, x2, y2);

        x = x2;
        y = y2;
    }
})

Poruszanie po divie myszą nic nie robi. No chyba, że guzik jest wciśnięty. Wtedy:

  • bierzemy x2 i y2, czyli akrualne koordynaty gdzie jest teraz mysz
  • tam, gdzie jest teraz mysz rysujemy kółko ze środkiem idealnie gdzie jest teraz mysz
  • rysujemy linię od początkowych koordynatów (tam, gdzie mysz była w momencie wciśnięcia jej przycisku) do aktualnych koordynatów
  • aktualizujemy te początkowe koordynaty

Mam nadzieję, że wszystko jasne, bo niedługo zrobimy to sobie korzystając z canvas…