[3] Drawing (opis) - Patrycja20/ImageChanger GitHub Wiki
Drawing
Ostatnim modułem w aplikacji jest moduł rysowania (drawing). Całość zbudowana jest w oparciu o Canvas z HTML5, który znajduje się w centralnej części okna. Wielkość całego modułu to 800 linii kodu.
Na samej górze okna znajdziemy pasek z narzędziami:
- Kontrolka do wyboru grubości linii. Po prawej możemy podejrzeć aktualnie wybraną wartość.
- Wybór koloru.
- Przełącznik trybu rysowania kształtów. Aktualnie będziemy rysować tylko kontury kształtów. Po zmianie trybu, kształty będą wypełniane kolorem.
- Czyszczenie płótna.
Dalej mamy pięć trybów rysowania:
-
Zwykły mazak(aktualnie wybrany).
-
Linia.
-
Prostokąt.
-
Okrąg.
-
Trójkąt prostokątny.
-
Przycisk umożliwiający zapisanie obrazka jako plik *.jpg.
Rysowanie odbywa się w sposób intuicyjny. Wybieramy grubość linii, kolor oraz narzędzie. Następnie, trzymając wciśnięty LPM, przesuwamy kursorem myszy po płótnie (canvasie).
Technikalia
Moduł ten, tak jak i pozostałe w aplikacji, został oparty o komponenty Reacta. Znajdziemy go w folderze src/components/Drawing
.
Głównym plikiem jest komponent Drawing
. Nie robi on w zasadzie nic ciekawego. Definiuje szkielet modułu i wyświetla dwa pozostałe komponenty: DrawingButtons
oraz DrawingCanvas
.
Przyciski przybornika znajdują się w komponencie DrawingButtons
. Informacje o wybranych parametrach są zapisywane w state aplikacji (via Redux). Domyślny stan znajdziemy w pliku src/store.js
, a wygląda on tak:
drawing: {
drawMode: DRAW,
paintSize: 10,
color: '#6edb31',
canvasRef: null,
isFill: false,
},
Wyjaśnienia mogą wymagać dwa ostatnie rekordy. canvasRef
przetrzymuje referencję (odwołanie) do canvasa. Natomiast flaga isFill
jest ustawiana w zależności od przycisku nr 3 (patrz obrazek nr 2). Sama referencja do canvasa jest ustawiana w komponencie DrawingCanvas
, dzięki czemu mamy dostęp do niego z każdego miejsca w module. Wykorzystuje to przycisk Save as *.jpg, który odwołuje się do canvasa i przetwarza go na obraz JPG oraz wyświetla okno pobierania pliku.
Ostatnim komponentem (i najważniejszym) jest DrawingCanvas
. To on wyświetla canvas i przetwarza akcje myszki na odpowiednie kształty. Podczas montowania komponentu są obliczane i ustawiane marginesy (paddings) i canvas jest wypełniany białym kolorem. Wartości malowania (kolor, grubość kreski) przyjmują domyślne wartości. Ustawiana jest także referencja do canvasa w modelu. Informacje o kolorze, grubości i narzędziu są ustalane za każdym razem, gdy zmieni się model.
Samo rysowanie składa się z trzech etapów - kliknięcie, trzymanie oraz puszczenie lewego przycisku myszy. Na kliknięcie obliczana jest aktualna (relatywna) pozycja myszy nad canvasem. Informacja ta jest zapisywana do stanu komponentu. Zmienia się też flaga mouseDown
na true
. Na canvasie przenosimy punkt początkowy ścieżki (path) do współrzędnych kliknięcia i rozpoczynamy rysowanie nowej ścieżki.
Drugi etap to ruch myszy nad canvasem. Rysowanie mazakiem jest najprostszą czynnością. Przy każdej zmianie odczytujemy aktualną pozycję myszy, oraz rysujemy linię do tego miejsca (dokładając ją do poprzedniej pozycji kursora). Trzeci etap to akcja puszczenia LPM. Wówczas zmieniamy flagę mouseDown
na false
i zaprzestajemy rysowanie.
Rysowanie kształtów jest trochę bardziej skomplikowane. Na ich potrzeby został stworzony drugi canvas, który znajduje się nad tym pierwszym. Drugi canvas jest całkowicie przezroczysty (wartość każdego piksela jest ustawiona na null). Gdy rysujemy kształt, przy każdej zmianie pozycji myszki, drugi canvas jest czyszczony i kształt rysowany jest od nowa. Po skończeniu (puszczeniu LPM) zawartość drugiego canvasa jest nakładana na pierwszy (ten właściwy). Dzięki temu, że drugi canvas jest przezroczysty, nakładany jest tylko narysowany przez nas kształt. Na koniec drugi canvas jest czyszczony.
Algorytmy rysowania kształtów można znaleźć w pliku drawingHelpers.js
. Rysowanie każdego kształtu jest w odpowiedniej metodzie, a za jej wywołanie odpowiada switch
.
Reduxowe akcje znajdziemy w pliku src/actions/index.js
. Stałe oraz reducer
obsługujący te akcje znajdziemy w pliku src/reducers/drawingReducer.js
.