Canvas - Circle progress

0

Dziękuje Ci za pomoc. Właśnie o to chodziło. W jaki sposób przeskalowuje się względem pierwszego canvasa (Co za to jest odpowiedzialne, że dzieje się to automatycznie)? O co chodzi z var zegarek = {}; zegarek.id = null;zegarek.pozycja = 0;?

1

Może wieczorem będę miał czas, żeby Ci to wyjaśnić. Ale starałem się to pisać w sposób dość prosty, więc podejrzewam że jak chwilę pokombinujesz to sam rozgryziesz o co chodzi.

Jeśli możesz, to przeczytaj po kolei to, co napisałem i postaraj się zastanowić, co robią poszczególne linie skryptu.
Możesz sobie pozmieniać parametry (np. prędkość czy wartości start/stop) i obserwuj, co się dzieje.
Jak będziesz miał pytania to je tutaj daj - później postaram się odpowiedzieć.
Tylko taka prośba - zanim zaczniesz grzebać na jsfiddle, skorzystaj z przycisku "fork" (jest na samej górze ekranu) - w ten sposób stworzysz sobie swoją kopię do zabaw i eksperymentów, przez co nie będzie ryzyka, że coś zepsujesz w tym, co ja stworzyłem ;)

Odnośnie pytania dot. skalowania - zobacz, w jaki sposób są zadeklarowane zmienne var wysokosc oraz var szerokosc - to jest odpowiedź na Twoje pytanie :)

2

Tak, jak obiecałem - wieczorem znalazłem trochę czasu, więc wyjaśniam, jak działa JavaScript pod adresem https://jsfiddle.net/pjm7wsbn/

1) w sekcji "HTML" na jfiddle masz przycisk, którego wciśnięcie aktywuje odliczanie oraz 3 elementy typu canvas. Każdy z canvasów ma swój rozmiar (mogą być różne), ale do ustalania wielkości kółka oraz pozycji tekstu w jego środku jest brany pod uwagę tylko pierwszy canvas.
2) w sekcji JavaScript na początku masz var kolko1={}; oraz następujące po nim przypisania dla każdego kółka wartości. Określają one sposób zachowania danego kółka. Start - od jakiej wartości zaczyna się odliczanie, stop - na jakiej się kończy, prędkość - jak szybko następuje postęp. Canvas - jest to pobranie elementu canvas do późniejszego rysowania (lepiej jest pobrać raz i potem się tylko do niego odwoływać, niż pobierać uchwyt za każdym odwołaniem funkcji rysującej). Parametr pozycja na razie nie jest używany - będzie on wykorzystany później, gdy kółeczka zaczną się animować
3) zmienne szerokość i wysokość - pobieramy rozmiary pierwszego elementu canvas, żeby (jak pisałem w pkt. 1) potem się do nich dopasować z rysowaniem kółka oraz wpisywaniem procentów
4) var zegarek - tutaj trzymamy dane potrzebne do obsługi timera. ID jest miejscem, do którego zostanie przypisany identyfikator zwrócony podczas wywołania setInterval, natmiast pozycja będzie później wykorzystana do ustalania, które kółeczko jak szybko będzie się posuwać do przodu (ma to związek z parametrem prędkosc z pkt. 2)
5) funkcja animacja_start jest uruchamiana w odpowiedzi na kliknięcie przycisku "ROZPOCZNIJ ODLICZANIE". Robi ona po kolei: sprawdza, czy timer jest już ustawiony, a jeśli go nie ma, to odpalając funkcję setInterval uruchamia odliczanie. Funkcja setInterval ma dwa parametry - funkcję, która ma zostać uruchomiona za każdym "tyknięciem" zegara oraz czas, co jaki ma zostać "tyknięcie" wygenerowane. Następnie ustala zegarek.pozycja = 0; - bo za każdym wciśnięciem przycisku animacja ma się uruchamiać od nowa. Dlatego - jeśli aktualnie jesteśmy w trakcie, to należy ją przerwać. Wszystkim kółkom ustalamy pozycję bieżącą na pozycję startową - kolko3.pozycja = kolko3.start;, a potem czekamy, aż zdarzenie zegarowe wywoła podaną funkcję, czyli zegarek_event.
5) funkcja koleczko_rysuj(ktore); - jest wywoływana przez funkcję zegarową, a jako parametr przyjmuje kółko, które ma rysować. Funkcja zegarowa wywołuje za każdym "tyknięciem" funkcję rysującą 3 razy - dla kolka1, kolka i kolka3. Funkcja rysująca w swojej pierwszej linii sprawdza, czy aktualna pozycja kółka nie przekracza pozycji końcowej, a jeśli tak się dzieje - oznacza to, że odliczanie doszło do końca i nic dalej nie robimy - polecenie return powoduje natychmiastowe wyjście z danej funkcji.
6) jeśli wyjście nie nastąpiło - idziemy dalej. Kolejne linie odpowiadając za wyczyszczenie obszaru canvas, ustalenie czcionki, kolorów i grubości linii oraz narysowanie kółka. Zmienna postep odpowiada za ustalenie, jak mocno dane kółko ma być zaawansowane i wykorzystuje w tym celu zmienną kolko.pozycja - która odpowiada za przechowywanie aktualnego stopnia zaawansowania danego kółeczka. Ostatnia linia odpowiada za obsługę prędkości danego kółka. Operator % to jest modulo, czyli reszta z dzielenia. Zapis zegarek.pozycja % ktore.predkosc odpowiada za sprawdzeniem, czy aktualna pozycja zegarka jest wielokrotnością prędkości danego kółeczka. Jeśli tak się dzieje, to za pomocą polecenia ktore.pozycja++; zwiększamy wartość zaawansowania danego kółka o jeden.
7) ostatnia funkcja - zegarek_event - nie jest ona wywoływana przez nas bezpośrednio, ale za jej uruchomienie odpowiada funkcja setInterval. Trzy pierwsze linie odpowiadają za wywołanie funkcji rysującej dla każdego z trzech kółeczek. Następnie następuje zwiększenie o jeden aktualnej wartości zegara (jest to używane do obliczeń z poprzedniego punktu). Następnie polecenieif ((kolko1.pozycja > kolko1.stop) && (kolko2.pozycja > kolko2.stop) && (kolko3.pozycja > kolko3.stop)) sprawdza, czy wszystkie 3 kółka już doszły do ustalonych wartości końcowych i jedynie jeśli tak jest, to zostaną wykonane dwa kolejne polecenia, zawarte pomiędzy nawiasami klamrowymi. Pierwsze kasuje timer (dlatego ważne było, żeby gdzieś zapisać sobie ID danego timera, bo nie mając tej wartości, nie dałoby się go skasować. Rysowanie kółeczek by działało poprawnie, ale po ich narysowaniu do końca nie dałoby się timera wyłączyć i cały czas by generował "tyknięcia"), a drugie czyści wartość ID, która była do niego przypisana. Sam fakt skasowania timera nie oznacza, że jego ID zniknie. To jakby mieć numer telefonu do kumpla. Później kumpel może telefon zmienić/zgubić, ale Ty nadal masz zapisany ten numer na kartce (mimo, że jest on już nieprawidłowy). Linia zegarek.id = null; czyści ten numer, szykując miejsce na nowy (czyli na kolejne wciśnięcie przycisku uruchamiającego odliczanie). Poza tym zgodne z pkt. 5 - na podstawie tego ID jest oceniane, czy mamy aktywny i działający zegar, czy trzeba stworzyć nowy.

Jeżeli nadal czegoś nie rozumiesz - pisz i pytaj. Tylko postaraj się zadać w miarę konkretne pytania, z których będzie wynikać, że przeczytałeś to, co pisałem i że starałeś się to zrozumieć ;)

0

Już teraz rozumiem jak działa powyższy kod. Teraz sobie uświadomiłem, że było to jak porywanie się z motyką na księżyc przy dość skromnej wiedzy na temat Js. Dziękuje Ci za wyczerpujące odpowiedzi i za pomoc.

1

Nie ma sprawy, do usług :)

A co do motylki i słońca - fajnie, że umiesz obiektywnie ocenić swoje umiejętności. Niestety, ale długa droga przez Tobą. Pamiętaj, że to, co dla Ciebie zrobiłem to żadne "słońce" nie jest, ale dość krótki i prosty skrypt.

1 użytkowników online, w tym zalogowanych: 0, gości: 1