Canvas - Circle progress

0

Siema,
Jak zrobić by funkcja (progressSim) odpowiadała kilku canvas o id"my_canvas"? W tej chwili kod wykonuje się dla jednego canvas.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<canvas id="my_canvas" width="280" height="280" style="border:1px dashed #CCC;"></canvas>
<canvas id="my_canvas" width="280" height="280" style="border:1px dashed #CCC;"></canvas>
</div>
<script>
var ctx = document.getElementById('my_canvas').getContext('2d');
var al = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height; 
var diff;
function progressSim(){
        for (var i=0; i<100; i++)
	diff = ((al / 100) * Math.PI*2*10).toFixed(2);
	ctx.clearRect(0, 0, cw, ch);
	ctx.lineWidth = 10;
	ctx.fillStyle = '#01F';
	ctx.strokeStyle = "#01F";
	ctx.textAlign = 'center';
	ctx.fillText(al+'%', cw*.5, ch*.5+2, cw);
	ctx.beginPath();
	ctx.arc(140, 140, 120, start, diff/10+start, false);
	ctx.stroke();
	if(al >= 100){
		clearTimeout(sim);
	    // Add scripting here that will run when progress completes
	}
	al++;
}
var sim = setInterval(progressSim, 20)
</script>
</body>
1

Wrzuć to ja http://jsfiddle.net i podeślij link

1

Podstawowa sprawa - o ile kojarzę (jeśli to się nie zmieniło w jakichś nowszych standardach - ale nic mi o tym nie wiadomo) to nie możesz mieć kilku elementów z tym samym ID. "The id attribute assigns a unique identifier to an element"

U Ciebie są dwa obiekty z id="my_canvas" - to jest pierwsza rzecz, którą powinieneś zmienić. Jeśli chcesz przypisać większej ilości elementów wspólne parametry - skorzystaj z class zamiast id.

https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute
https://www.w3.org/TR/html4/struct/global.html#adef-id

0

ok, zmieniłem id na class. Teraz jak poprawnie napisać funkcje
https://jsfiddle.net/mgfjq98t/1/

1

Tak na szybko, bo zaraz uciekam od kompa i w domu będę dopiero póżniejszym wieczorem - czy czytałeś opis metody getElementsByClassName()?
https://www.w3schools.com/jsref/met_element_getelementsbyclassname.asp
https://developer.mozilla.org/pl/docs/Web/API/Document/getElementsByClassName

Zwraca obiekt podobny do tablicy, zawierający wszystkie elementy, które mają przypisaną daną klasę.

Czyli nie możesz odwoływać się do wyniku tej funkcji w sposób, w jaki to robisz obecnie - w stylu ctx.lineWidth = 10;, tylko musisz się odwołać do każdego elementu tej "tablicy" osobno. Przykład z w/w linków - x.getElementsByClassName("child")[1].style.backgroundColor = "red"; - tutaj wskazujesz, że chodzi Ci o element o indeksie 1 z zestawu elementów posiadających daną klasę. Możesz sobie "przelecieć" przez te elementy i dla każdego wykonać pewną akcję - https://stackoverflow.com/questions/3871547/js-iterating-over-result-of-getelementsbyclassname-using-array-foreach, ale moim zdaniem to zbytnie skomplikowanie rysowania dwóch kółeczek.

Opcja prostsza: kod odpowiedzialny za rysowanie kółeczka wywalasz do osobnej funkcji, której parametrem jest canvas, na którym chcesz rysować. Robisz tak, jak wcześniej ID dla tych canvasów, ale lekko je zmieniasz - np. "ramka1" i "ramka2". W obsłudze timera wywołujesz dwa razy funkcję rysującą - raz jako parametr podając "ramka1", a potem "ramka2".

Pobaw się, pokombinuj i wrzuć nowy link na jsfiddle.net. Wieczorem postaram się rzucić okiem i w razie czego pomóc. Chociaż mam nadzieję, że sam sobie poradzisz :)

0

Nie wiem czy o to chodziło https://jsfiddle.net/mgfjq98t/3/, ale niby działa. Zastanawia mnie dlaczego w drugim kółku jest 51%,a wpisane jest 50%.

1

Czy oba kółka mają się "posuwać" jednocześnie? W sensie - w tym samym czasie i o taką samą ilość procentów?
Tak w ogóle - po co Ci to jest? Co chcesz z tym zrobić?

Poza tym pisałem, że lepiej jest zrobić jedną funkcję, którą się wywoła z parametrem wskazującym, na którym canvasie ma rysować, a wszystko to robić w obsłudze jednego timera. Teraz jakoś dałeś sobie radę, ale można to zrobić lepiej ;)

0

Tak, oba kółka miały "posuwać" w tym samym czasie, tylko z inną wartością (%). Robię stronkę i chciałem umieścić takie kółka jako wartość. Chciałem też dodać, żeby odpalały się jak dojdę do danej sekcji (one page). Jeśli byś mi mógł wytłumaczyć jak to zrobić prościej to znaczy jak z jedną funkcją to było lepiej, bo niestety nie zrozumiałem.

1

Pierwsza sprawa - czemu nie założysz konta, tylko piszesz anonimowo? :P

A po drugie - skoro mają się przesuwać z różną prędkością, to opisz mi zachowanie, którego oczekujesz. Czy mają startować w tym samym momencie? Jak pierwsze się zapełni, rozumiem, że drugie ma dalej jechać aż do "swojego" końca? Wyjaśnij, czego dokładnie chcesz/potrzebujesz.

0

Konta nie założyłem, bo chciałem uzyskać na szybko odpowiedź, a nie mogłem poradzić sobie z problemem. Bardziej mnie interesuje jak można zoptymalizować kod, żeby było lepiej. Nie zrozumiałem jak można uzyskać efekt za pomocą jednej funkcji z parametrem wskazującym. Mógłbyś mi to jeszcze jakoś nakreślić :P?

1

No to masz dwa kółka, które się zapełniają jednocześnie - https://jsfiddle.net/fr2d89z5/

Jest to napisane dośc brzydko, bo powiem szczerze - nie mam teraz czasu żeby bawić się w dopieszczanie. Zarówno Twój kod, jak i moje poprawki są raczej na poziomie prowizorki - ale ważne jest to, że działa :D

Wyjaśniam, o co chodzi - bo wcześniej pisałeś, że nie rozumiesz o co Cię prosiłem/sugerowałem:

Zauważ, że teraz mamy dwa canvasy - id="my_canvas1" oraz id="my_canvas2".
Stworzyłem nową funkcję, którą nazwałem koleczko().
Całe rysowanie okręgów zawiera się właśnie w funkcji koleczko(), natmiast obsługa timera ogranicza się do wywołania funkcji rysującej dwa razy, z różnymi parametrami - raz z pierwszym, a potem z drugim canvasem.

Czy teraz rozumiesz jak to działa? Jeśli nie, to pytaj - postaram się wyjaśnić.
Tylko pamiętaj, bo to co pisałem wcześniej jest dość ważne. Wprawdzie w tej chwili JS działa tak, jak chciałeś - ale raczej nie jest to zbyt pięknie napisane.

0

Ok, teraz zrozumiałem jak to działa w podany przez Ciebie sposób. Teraz, gdybym chciał aby drugie kółko miało np 40 %, to co musiałbym zrobić?

1

a w jaki sposób teraz sterujesz procentami kółek? Zrób podobnie, ale rozbij to na dwie wartości - osobną dla każdego z kółka. Czy wiesz/rozumiesz o co mi chodzi?

0

Nie rozumiem o co Ci chodzi, jeśli byś mi jeszcze to wytłumaczył to byłbym wdzięczny. Js dopiero uczę się od kilku dni.

1

To nie chodzi o JS, ale o sam sposób, w jaki jest obliczany procent zaawansowania kółeczka.
Powiedz - czy Ty funkcję rysującą kółko stworzyłeś sam, czy skopiowałeś skądś? Podejrzewam opcję numer 2 (chociażby sądząc po użytych nazwach zmiennych). W każdym razie - czy w ogóle rozumiesz, jak ona działa?
Żeby była jasność - ja Cię nie atakuję, tylko staram się pomóc. Ale to ma być pomoc polegająca na wytłumaczeniu i podpowiedzeniu rozwiązania, a nie zrobieniu za Ciebie. W ten sposób przynajmniej się czegoś nauczysz, a nie dostaniesz gotowiec, którego nie będziesz rozumiał.

0

Tak, niestety to nie jest mój kod. Funkcję skopiowałem, ale mniej więcej staram się ją zrozumieć. Może jeszcze nie jest czas, aż na takie rzeczy.

1

Jak możesz to postaraj się ją rozgryźć. Możesz napisać tutaj o tym, co rozkminiłeś. Kwestia do przemyślenia - w jaki sposób jest sterowany "postęp" kólek? Jak go obliczasz? Gdzie tą wartość trzymasz i w jaki sposób wykorzystujesz. Ja jakoś później postaram się ustosunkować do tego, co napisałeś. A jak zrozumiesz jak ta funkcja działa, to przerobienie jej nie powinno być problemem :)

No i weź wreszcie załóż to konto :D Już tak długo tu piszesz, że mógłbyś przestać być anonimowy :P

0

Gdybym w canvas o id="my_canvas1" wpisał wartość value, a później w js stworzył zmienną value1 = document.getElementById('my_canvas1').value i podpiął pod funkcje to dałoby rade?

1

Postaram się wieczorem zająć w miarę porządnie tematem. Na razie musisz poczekać (albo może ktoś inny w tym czasie się udzieli w wątku).

No i weź wreszcie załóż to konto :D Już tak długo tu piszesz, że mógłbyś przestać być anonimowy :P

0

O coś takiego mi chodziło https://jsfiddle.net/fr2d89z5/32/.

1

Nie wiem, co chciałeś pokazać na ostatnim fiddle, bo jak go odpalam to nie ma żadnego kółeczka, a w miejscu procentów jest napis "NaN%". O to właśnie chodziło, czy coś się zepsuło?

No i weź wreszcie załóż to konto :D Już tak długo tu piszesz, że mógłbyś przestać być anonimowy :P

1

Chodziło mi co muszę poprawić, żeby działało. Czy to jest poprawnie napisane?

1

Fajnie, że masz konto :)

Tak, jak pisałem - pod wieczór będę miał więcej czasu i spokoju, żeby się zająć tematem.
A Ty - na razie napisz mi proszę, ale tak, jakbyś tłumaczył dziecku albo idiocie, co chcesz osiągnąć i jak to się ma zachowywać. Opisowo, powoli i ze szczegółami - napisz mi, które kółko i kiedy ma się powiększać, czy z taką samą prędkością itp.

0

Wszystko to chciałem tzn: z prędkościami kółek itd to już rozumiem. Interesuje mnie jeśli będę miał więcej niż 1 kółko, to czy da się zrobić tak, że każde kółko będzie miało inna wartość % w środku (pierwsze 100%, drugie 50% itd). Czy da się to zapisać jako value w canvas (html), a później pobrać w js i podstawić pod wzór, żeby narysowało?

1

Ale co i w jaki sposób ma sterować tymi procentami? Obecnie kółko startuje od zera i dochodzi do 100%. Napisz, jak ma to wyglądać w przypadku większej ilości kółek - czy mają one startować w tym samym momencie, czy w różnych? Czy wszystkie mają zaczynać od zera, czy od jakiejś określonej wartości? Czy mają się zapełniać do 100%, czy zatrzymać jakoś po drodze?

0

Mają startować w tym samym momencie. Wszystkie powinny startować od zera, i powinny zapełniać się do określonej przeze mnie wartości.

1

Ok, chyba rozumiem co chcesz osiągnąć :)

0

Ok, ciesze się, że się rozumiemy. Czekam na wskazówki.

1

Rzuć okiem na https://jsfiddle.net/pjm7wsbn/

Zrobiłem Ci trzy kółeczka, Każde z nich ma swoje ustawienia - można zdefiniować wartość początkową (czyli od której zaczyna "rosnąc"), wartość końcową (czyli przy jakiej wartości się zatrzymuje) oraz prędkość. Oczywiście parametry każdego z kółek są niezależne od pozostałych.

Starałem się napisać to w miarę prosty sposób - wiem,że dałoby się pewne rzeczy zoptymalizować, wydzielić do osobnych funkcji, ładniej i zgrabniej napisać itp., ale chciałem, żeby kod był jak najbardziej przejrzysty - tak, żebyś mógł do niego zajrzeć i rozumieć, o co chodzi, co się dzieje w poszczególnych liniach.

Zauważ, że wszystko się przeskalowuje względem pierwszego canvasa - więc zmieniając jego rozmiar, zmieniasz też rozmiar kółeczka oraz położenie tekstu. Ponieważ już nie chciałem komplikować z pilnowaniem rozmiarów każdego canvasa z osobna, więc po prostu musisz się starać, żeby zmieniając rozmiar canvasów zawsze ustawiać je tak samo.

Prędkość regulujesz w dwóch miejscach - dla każdego kółeczka istnieje parametr prędkość, który masz zdefiniowany na początku skryptu, możesz grzebać także w wywołaniu funkcji setInterval. Parametr prędkość musi być liczbą całkowitą i nie może być mniejszy niż 1. im większa liczba, tym wolniej kółko się zapełnia. Z kolei parametr setInterval jest wspólny dla wszystkich kółeczek i im jest niższy, tym szybciej się będą kręcić.

Daj znać, czy rozumiesz jak to działa i czy tego właśnie potrzebowałeś :)

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