Transformarea Directcomposition și animație

În ultimul articol (msdn.microsoft.com/magazine/dn759437) am arătat cum DirectComposition API-ul poate fi utilizat împreună cu Direct2D, pentru a obține cel mai bun din ambele lumi - salvați modul grafic (modul reținut) și modul direct (modul imediat). proiect de probă care este inclus în articol, ilustrat acest concept cu o aplicație simplă, care vă permite să creați un cerc, mutați-le în jurul ferestrei, și ușor de a gestiona lor Z-ordine. În acest articol vreau să arăt cât de ușor este de a adăuga unele efecte impresionante cu ajutorul de transformare și de animație. În primul rând, trebuie să vă dați seama că DirectComposition oferă versiuni supraincarcate ale multor proprietăți scalare. Probabil ați observat că, dacă mi-a urmat în ultimele câteva luni, când am cercetat acest API. De exemplu, deplasarea vizual poate fi setată folosind metodele și SetOffsetX SetOffsetY:

Dar interfața IDCompositionVisual, din care moștenește IDCompositionVisual2, prevede, de asemenea, o supraîncărcare a acestor metode, care au obiect de animație, mai degrabă decât o valoare în virgulă mobilă. Această animație obiect se materializează ca o interfață IDCompositionAnimation. De exemplu, am putea stabili diferența de un mijloc vizual de unul sau două obiecte în animație, în funcție de faptul dacă am nevoie de animație într-o singură axă, sau ambele:

Dar mecanismul compoziției are o capacitate mult mai mare în animație. Visuals sprijină, de asemenea, transformarea cu două și trei dimensiuni. SetTransform metodă vizuală poate fi utilizată pentru aplicarea unei bidimensională de transformare pentru o valoare scalară dată:

Acolo DirectComposition fapt se bazează pe 3 x 2 matrice definită în Direct2D API. Cu el puteți efectua diverse operații, cum ar fi rotație, translație, zoom și înclinarea vizuală. Aceasta afectează spațiul de coordonate, care este proiectat pe conținutul vizual, dar este limitat la două-dimensional grafic cu axele X și Y.

În mod firesc, interfața IDCompositionVisual oferă o metodă versiune SetTransform supraîncărcată, dar nu acceptă în mod direct obiect de animație. Vezi tu, obiectul de animație este responsabil pentru animație doar o singură valoare pentru ceva timp. Matricea prin definiție, constă dintr-un set de valori. S-ar putea dori pentru a anima un anumit număr de membri ai săi, în funcție de efectul dorit. Prin urmare, versiunea supraîncărcată ia SetTransform transforma obiect:

Asta transforma obiectul, sau mai degrabă, o varietate de interfețe derivate din IDCompositionTransform, prevede metode supraîncărcate, care iau o valoare scalară sau animație obiect. Astfel, ai putea defini o matrice cu un unghi de rotație animat de rotație, dar cu un punct central fix și axe. Ce anume te anima, desigur, face cel mai rau. Aici este un exemplu simplu:

Interfața moștenește de la IDCompositionRotateTransform IDCompositionTransform si reprezinta transforma o bidimensională care afectează rotația vizuală în jurul axei Z. Aici, un punct central, am atribui o valoare fixă, pe baza unor valori de lățime și înălțime, și folosind obiect de animație pentru unghiul de control.

Acesta este modelul de bază. Am descris doar o transformare bidimensională, dar transformarea tridimensională funcționează în mare parte în același mod. Acum, permiteți-mi să ilustreze un exemplu practic care arată modul de utilizare a proiectului de la ultimul meu articol, și de a converti animația o varietate de moduri utilizând Managerul Direct2D și Windows Animație.

Apoi, în metoda SampleWindow CreateFactoryAndGeometry voi primi Direct2D-fabrica pentru a crea geometria dreptunghiului în loc de o geometrie elipse:

Asta e tot. Restul aplicației utilizează pur și simplu captarea de redare geometriei și verificarea infiltrării, la fel ca înainte. Rezultatul este prezentat în Fig. 1.

Transformarea Directcomposition și animație

Fig. 1. Ilustrarea transformare și de animație, folosind în loc de cercuri pătrate

În continuare, am de gând să adăugați un handler simplu pentru a răspunde la WM_KEYDOWN mesajului. Metoda de MessageHandler SampleWindow I rândul său, la această expresie în cazul în care:

Fig. 2. I Am dispozitiv de legare pentru recuperarea de la pierderea

În acest moment, eu sunt dispus să experimenteze cu transformări și animații. Să începem cu o bază de rotație bidimensională de transformare. În primul rând, trebuie să definească punctul central al care va reprezenta axa Z, sau punctul în jurul căruia rotația va avea loc. Deoarece DirectComposition așteaptă coordonatele un pixel fizic, eu pot apela doar funcția de aici GetClientRect:

Apoi vom obține punctul central al zonei client a ferestrei:

Mai mult, este posibil să se bazeze pe matrice suport funcția Direct2D în proiectarea matricele care descriu transformarea rotației bidimensională de 30 de grade:

Și apoi cere doar proprietatea transforma dintr-un vizual și să treacă o modificare a arborelui de obiecte vizuale. Pentru simplificare, voi folosi această schimbare la rădăcina unui vizual:

Desigur, puteți utiliza orice număr de modificări la orice număr de mecanism vizual și compoziția se ocupă de coordonarea acestor modificări. Rezultatele acestui simplu bidimensională transformatei este prezentată în Fig. 3. S-ar putea să fi observat puține defecte (aliasing). Deși Direct2D implicit efectuează netezirea (anti-aliasing), se presupune că imaginea va apărea în spațiul de coordonate, care a efectuat redarea acestuia. Mecanismul compoziției nu știe nimic despre geometrie, folosind a fost făcută o suprafață de redare a compoziției, astfel încât nu este posibil pentru a corecta acest lucru. În orice caz, odată ce amestecul se adaugă la animație, aliasing va fi văzut în timp extrem de scurt, și, prin urmare, aproape invizibil.

Transformarea Directcomposition și animație

Fig. 3. Un simplu bidimensională transforma

Pentru a adăuga animație la această transformare, este necesar să se elimine structura matricei pentru conversia compoziției. Eu va înlocui structura D2D1_POINT_2F și D2D1_MATRIX_3X2_F o transformare de rotație. În primul rând aveți nevoie pentru a crea această transformare, folosind dispozitivul de compoziție:

(Rețineți că, chiar și astfel de obiecte aparent simple, trebuie să fie eliminate când și în cazul în care dispozitivul este pierdut și re-creat.) Apoi am stabilit punctul central și unghiul, folosind metodele de interfață în loc de o structură de matrice de Direct2D:

Și compilator selectează versiunea corespunzătoare supraîncărcat pentru prelucrarea de conversie a compoziției:

Pentru îndeplinirea acestui cod are același efect ca și în Fig. 3. Din moment ce nu am adăugat încă animația. Crearea de animație obiect este destul de simplu:

Apoi am putea folosi acest obiect de animație în loc de valori constante pentru setarea unghiului:

Lucrurile devin un pic mai interesant atunci când încercați să configurați animație. animație simplă este relativ simplă. Așa cum am spus, animația descrisă de funcții cubice, și unde sinusoidale. Acest unghi poate fi animat folosind o tranziție liniară, unde valoare crește de la 0 la 360 în fiecare secundă, prin adăugarea unei funcții cub:

Al treilea parametru specifică metoda AddCubic raport liniar de mărire, astfel încât acesta are sens. Dacă aș fi lăsat totul în așa fel, vizualul să fie pentru totdeauna rotit la 360 de grade. Animația poate fi oprit imediat ce unghiul devine egal cu 360 de grade:

Primul parametru al End indică abaterea de la începutul animație, indiferent de funcția de animație. A doua opțiune - este valoarea sfârșitul animației. Păstrați acest lucru în minte precum și animație va „sari“ la această valoare atunci când aleasă în mod corespunzător pas care va duce la efectul vizual al unui progres.

În astfel de animații liniare destul de ușor de înțeles, dar mai complicate animație pot fi extrem de complicate. Aici intră în joc pentru Windows Animație Manager. În schimb provoca diferite metode IDCompositionAnimation, pentru a adăuga segmentele sinusoidale segmente cubi polinomiale repetarea, și așa mai departe. D. Storyboard de animație pot fi construite folosind Manager pentru Windows Animație și biblioteci tranzițiile bogate (tranziții). Variabila rezultată animație este folosită pentru a umple compoziția de animație. Acest lucru necesită scrierea de cod ceva mai mult, dar avantajul - mult mai multe capacități și controlul asupra animației în cerere. Pentru a începe, trebuie să creeze el însuși un manager de animație:

Da, Windows Animation Managerul se bazează pe COM-activare, astfel încât să fie sigur de a apela CoInitializeEx sau RoInitialize pentru a inițializa runtime. În plus, necesitatea de a crea o bibliotecă de tranziții:

De regulă, cererea va păstra cele două obiecte pe parcursul întregului ciclu de viață, deoarece acestea sunt necesare pentru animație continuă și în special pentru sincronizare (potrivirea viteză) de viteză. Apoi, am să creeze o animație storyboard (animație storyboard):

Storyboard - ce se conectează tranziții cu animație variabilă, și determină programele lor relative de ceva timp. Storyboard capabile să agrege tranziții diferite, care sunt aplicate la diferite variabile de animație; asigură sincronizarea lor și planificate în ansamblu. (Desigur, puteți crea mai multe scenarii pentru planificarea animații independente.) Acum trebuie să întreb managerul pentru a crea o animație de animație variabilă:

Odată ce storyboard este programată, Animation Manager este responsabil pentru menținerea relevanței unei variabile, astfel încât aplicația poate interoga valoarea curentă în acest moment. În acest caz, eu folosesc doar animație variabilă pentru a umple de animație segment compoziție, și apoi ștergeți-le. Acum puteți utiliza biblioteca puternic tranziții pentru a crea un efect de tranziție interesant pentru animație variabilă:

Tranziția va determina accelerarea variabilei animație, apoi încetinind pentru un interval predeterminat până când animația este terminat cu valoarea sa finală. Ratele aplicate influențează măsura în care relativ rapid variabilă va accelera și apoi încetini. Rețineți că o combinație de factori care nu poate depăși 1. Se prepară o animație variabilă de tranziție, eu le pot adăuga la storyboard:

Acum storyboard gata de planificare:

Singurul parametru al Programarea rapoartelor planificatorului curente animație de timp. Este mai util să se coordoneze animatia si sincronizarea acestuia cu rata de reîmprospătare utilizată de motorul compoziției, dar va veni la îndemână acum. În acest moment, animația „încărcat“ variabilă, și îi pot cere să completeze curbele de animație ale compoziției:

În acest caz, este echivalent, ca și în cazul în care am cauzat această compoziție de animație:

Nu necesită cu siguranță mult mai puțin cod decât cu Windows Animation Manager, dar să înțeleagă că nu este ușor în toată matematică. Managerul pentru Windows Animation, de asemenea, vă permite să coordoneze și să execute fără probleme tranziții între animații, ceea ce este extrem de dificil de a face cu mâna.