[ johnnyc @ 13.10.2009. 00:20 ] @
Pozdrav,

Na formi imam picturebox, koji treba da klizi sa gore na dole.

Pokusavam da resim sa Y koordinatom, koja se menja u vremenu, na svakih nekoliko milisekundi se Y smanji za 1.

Ono sto me nervira je da taj "slide" uopste ne ide tecno, kao sto bi bio npr. u Flash-u.... Cesto i po malo "zapinje"...

Da li to moze nekako da se resi?


Veliko hvala unapred!

[Ovu poruku je menjao johnnyc dana 13.10.2009. u 01:38 GMT+1]
[ Sapphire @ 13.10.2009. 16:56 ] @
WinForms je tehnologija koja nikad nije bila previđena za pravljenje animacija, te zbog toga, u njoj nedostaju mnoge stvari da olakšaju taj posao. Preporuka koju će ti bilo ko dati je, ako je moguće, da pređeš na WPF za ovo ...

Ipak, solucije postoje, a ti nisi naveo kako animiraš pokretanje panel-a. Ako u OnPaint event-u pozivaš Thread.Sleep(), to je najgore i najlošije rješenje. WinForms ima probleme sa animacijama zbog dva glavna razloga:
- crtanje se obično radi sa GDI+-om, koji je inače vrlo spor u usporedbi s ostalim tehnologijama
- WinForms aplikacije su napravljene da iskorištavaju što manje procesorskog vremena, te zbog toga animacija često nije fluentna (ako recimo tebi baš treba da program dobije svoj slice svakih n ms, to je ovdje na standardne načine nemoguće garantovati)

Iako ovaj prvi razlog ovdje kod tebe skoro nema smisla (samo crtanje panel-a unutar .NET ne ide sa GDI+, već se koristi mnogo brži i stariji GDI), ovaj drugi je problem koji je zajednički svim pokušajima animacija.

Prva solucija, koja je i daleko najčešća, je animacija sa Timer-om. Unutar timera se namjesti interval u kojem će se pozivati samo crtanje neke komponente, a taj interval (kao i inteval timera) se cilja negdje na 30FPS, zavisno opet od namjene animacije (što jednostavnija animacija - znači bez pomjeranja po ekranu - to manje potreban FPS). Ja sam na ovaj način uradio nekoliko animiranih kontrola, od kojih su sve radile perfektno (ali se nije radilo o nikakvom pomjeranju po ekranu, nego samo recimo o animiranim button-ima koji su na rollover mjenjali gradient-e i sl.)
Druga solucija, koja je moguća, i mnogo fleksibilnija / bolja, je kreiranje posebnog thread-a koji izvršava animaciju, i to nekako ovako:

1. Kreiraš posebnu Animation klasu
2. u njoj, napraviš neku StartAnimation() metodu koja pokreće novi thread sa recimo private Animate() metodom.
3. unutar Animate(), namjestiš FPS i "okidanje" nekog NotifyAnimation event-a
4. gdje je potrebno, registruješ se na NotifyAnimation event

Ova druga solucija je na ovaj način fleksibilnija od recimo Thread timer-a, te je zato i preferabilna.

Kad sam radio animirani chart, na prvi način je bilo nemoguće namjestiti da animacija bude dovoljno fluidna ...

Sve u svemu, ovo je donekle komplikovanije područje, i ako želiš da sve bude kako treba, imat ćeš mnogo posla posvećivanju pažnje da svi grafički objekti budu pravilno Dispose-ovani, itd...