No to na początek wyjaśnienie czemu to nie działa. Problem polega na tym, że podczas twojego ruchu myszą twój mouseEvent wykonywany jest pewną ograniczoną ilość razy a twoje rysowanie odbywa się poprzez rysowanie wielu małych linii z punktu do punktu (w momentach kiedy ten mouseEvent jest triggerowany).
W momencie kiedy szybko wyjeżdżasz kursorem za canvasi na niego wracasz to twój mouseEvent wykonuje się ze zbyt małą częstotliwością aby idealnie "wstrzelić" się w moment wejścia/wyjścia z canvasu.
Tutaj podeślę nawet przykład z dokumentacji, który robi dokładnie to samo co twój kod, i uwaga.. jest tam ten sam problem co u Ciebie.
Przykład z dokumentacji
No ale sytuacja nie jest taka beznadziejna bo dalej można to poprawić.
nic nie stoi na przeszkodzie aby w metodach canvasu, podczas rysowania, podawać pozycje, które wykraczają za canvas, a więc możesz przenieść swoje event listenery z canvasu do np body.
na canvasie zostawiłbym tylko listener, który sprawdza czy został wciśnięty przycisk myszy odpowiedzialny za rysowanie i rysowałbym tak długo aż ten przycisk nie zostanie puszczony, niezależnie od tego czy będzie on nad canvasem czy nie.
Tylko teraz pojawi nam się mały problem z różnymi pozycjami myszki i tego gdzie rysujemy (zależnie od ustawienia elementów nasza linia może się pojawiać w innym miejscu niż kliknęliśmy). No ale to nie problem, bo znamy nasz aktualny scroll strony, możemy też odczytać pozycję naszego canvasu względem rodziców lub całego ekranu więc możemy dokonać obliczeń korygujących pozycję.
Jeszcze tylko pokażę jak zmieniając jedno słowo rozwiązać ten problem w przykładzie z dokumentacji.
Myślę, że będzie to pomocne też dla innych bo jest to dokładnie ten sam problem co w pytaniu.
/* oryginał */
myPics.addEventListener('mousemove', e => {
if (isDrawing === true) {
drawLine(context, x, y, e.offsetX, e.offsetY);
x = e.offsetX;
y = e.offsetY;
}
});
/* zmiana */
document.addEventListener('mousemove', e => {
if (isDrawing === true) {
drawLine(context, x, y, e.offsetX, e.offsetY);
x = e.offsetX;
y = e.offsetY;
}
});