Canvas de la zero desen avansat

În articolul precedent din această serie, ați aflat despre elementul de pânză și despre elementele de bază ale desenului. În acest articol, voi demonstra câteva dintre funcțiile avansate de desen.


Configurare

Vom folosi același șablon HTML din articolul precedent; deschideți editorul dvs. favorit și lipiți-l în următorul cod:

    Canvas de la zero          

Aceasta nu este altceva decât o pagină HTML de bază cu un pânză element și unele JavaScript care rulează după încărcarea DOM. Nimic nebun.


Cercuri de desenare

În ultimul articol i-am arătat cum să desenezi forme și căi de bază; în această secțiune vă voi arăta cum să faceți lucrurile cu un pas mai departe și să trageți cercuri. Nu este așa de ușor cum credeți, dar nu este deloc greu.

Nu există o metodă în panza care să vă permită să desenați un cerc cu o singură linie de cod, cum ar fi cum fillRect funcționează pentru dreptunghiuri. În schimb, trebuie să desenați cercuri cu o cale folosind arc metodă; un cerc este doar un arc de 360 ​​de grade. Motivul pentru aceasta este că cercurile sunt, de fapt, forme foarte complexe, și arc metoda permite tot felul de control asupra modului în care le desenați. De exemplu, ați putea dori doar să desenați un semi-cerc. arc vă permite să faceți acest lucru. Puteți chiar să combinați arc metoda cu trasee standard drepte pentru a desena felii de pizza si sferturi de cercuri.

Voi explic cum arc metoda funcționează în curând, dar pentru moment, să trasăm un cerc prin adăugarea următorului cod sub CTX variabil:

 cxt.beginPath (); ctx.arc (100, 100, 50, 0, Math.PI * 2, fals); ctx.closePath (); ctx.fill ();

Acest lucru va atrage un cerc poziționat ușor departe de stânga sus a pânzei:

Arată simplu, nu? Și este, dar să aruncăm o privire mai atentă la ceea ce se întâmplă.

arc metoda are un total de șase argumente:

  • Primul este X poziția punctului de origine (centrul cercului).
  • Al doilea este y poziția punctului de origine.
  • Al treilea este raza cercului.
  • Cel de-al patrulea este unghiul de pornire al cercului.
  • Al cincilea este unghiul de capăt al cercului.
  • Și a șasea este direcția de a trage arcul (adevărat este în sens invers acelor de ceasornic, iar falsul este în sensul acelor de ceasornic)

Scris în pseudocod, arc ar arata astfel:

 arc (x, y, rază, startAngle, endAngle, în sens invers acelor de ceasornic);

Primele trei argumente sunt explicative, la fel ca și ultimul, dar despre unghiul de început și final? Lasă-mă să explic.

După cum am menționat anterior, cercurile sunt doar arcuri de 360 ​​de grade. În panza, un arc este definit ca o linie curbată care începe la o distanță distanță de un punct de origine care este distanța dintre rază. Linia curbată începe la un unghi definit ca argument al unghiului de pornire (a patra) și continuă în jurul circumferinței unui cerc imaginar până când atinge unghiul definit ca argumentul unghiului final (al cincilea). Sună simplu, corect?

Poate o ilustrare va ajuta la explicarea situației:

Poate arata nebun, dar are multe sensuri odata ce ai putea sa-ti faci capul in jurul ei.

Unghiuri în pânză

În acest moment, este probabil de remarcat faptul că unghiurile din panza sunt realizate în radiani, nu în grade. Aceasta înseamnă că unghiurile merg de la 0 la pi multiplicate cu două. Unghiurile în panza încep de asemenea din partea dreaptă, după cum se poate vedea în următoarea ilustrație:

Dacă într-adevăr nu vă place radiani, puteți converti ușor gradele în radiani cu următoarea formulă JavaScript:

 var. grade = 270; var radians = grade * (Math.PI / 180);

Această formulă este simplă și este extrem de valoroasă dacă doriți să tratați în grade.


Traseele B? Zier

Arcurile sunt distractive și toate, dar sunt destul de limitate pentru felul de curbe care pot fi create cu pânză. Pentru ceva mai complex, veți dori să începeți să vă uitați la metodele curbei B? Zier quadraticCurveTo, și bezierCurveTo. Aceste metode vă permit să creați căi curbe care au o rază care nu este centrală pentru curbă și, de asemenea, să creați căi care au mai multe curbe.

Căile Biezier folosesc punctele de control pentru a defini cum și unde să deseneze curbele. De exemplu, quadraticCurveTo are un punct de control, în timp ce bezierCurveTo Are doua. Consultați ilustrația de mai jos pentru a vedea cum punctele de control afectează modul în care este trasă o curbă:

Dacă ați folosit deja o aplicație de desen vectorial, cum ar fi Adobe Illustrator, atunci s-ar putea să fiți deja confortabil cu aceste tipuri de curbe.

Să intrăm și să creăm o cale patrată B? Zier. Înlocuiți codul de arc cu următoarele:

 ctx.lineWidth = 8; ctx.beginPath (); ctx.moveTo (50,150); ctx.quadraticCurveTo (250, 50, 450, 150); ctx.stroke ();

Aceasta va atrage o cale curbată care arată ca cea din stânga ilustrației de mai sus:

quadraticCurveTo metoda are patru argumente:

  • Primul este X poziția punctului de control.
  • Al doilea este y poziția punctului de control.
  • Al treilea este X poziția sfârșitului căii.
  • Și a patra este y poziția sfârșitului căii.

Scris în pseudocod, quadraticCurveTo ar arata astfel:

 quadraticCurveTo (cpx, cpy, x, y);

Poziția de pornire a curbei este oriunde se află în prezent calea. De exemplu, în codul de mai sus ați mutat începutul căii apelând MoveTo metodă.

Să urcăm un nivel și să creăm o cale cubică B? Zier. Înlocuiți codul anterior cu următoarele:

 ctx.lineWidth = 8; ctx.beginPath (); ctx.moveTo (50,150); ctx.bezierCurveTo (150, 50, 350, 250, 450, 150); ctx.stroke ();

Aceasta va atrage o cale curbată care arată ca cea din dreapta ilustrației de mai sus:

bezierCurveTo metoda are șase argumente:

  • Primul este X poziția primului punct de control.
  • Al doilea este y poziția primului punct de control.
  • Al treilea este X poziția celui de-al doilea punct de control.
  • A patra este y poziția celui de-al doilea punct de control.
  • Al cincilea este X poziția sfârșitului căii.
  • Și a șasea este y poziția sfârșitului căii.

Scrisul este pseudocod, bezierCurveTo ar arata astfel:

 bezierCurveTo (cp1x, cp1y, cp2x, cp2y, x, y);

Pe propriile căi B? Zier nu sunt super uimitoare, dar când sunt combinate cu căi normale sau când sunt folosite de mai multe ori, rezultatele pot fi destul de profunde. Ele vă permit să creați tot felul de forme complicate și nebune în panza!

S-ar putea să doriți să verificați pluginul Ai-> Canvas pentru Adobe Illustrator, care vă permite să exportați desenul dvs. de vector fantezist ca un cod de panza. Este destul de curat, și vă va salva mult timp!


Statul de tragere

În articolul precedent din această serie, am detaliat modul de schimbare a stilului de umplere și accident vascular cerebral al panzei, precum și modul de modificare a lățimii liniei. Una dintre problemele care trebuie să fie conștiente când se schimbă aceste proprietăți este că va trebui să modificați manual culorile și lățimea liniei înapoi dacă doriți culoarea sau lățimea pe care ați avut-o inițial. Din fericire, ca întotdeauna, există o modalitate mai bună de a face acest lucru; se numește starea desenului.

Starea desenului în panza este în esență o stivă pe care puteți salva stilurile curente și apoi le puteți restabili din nou la o dată ulterioară.

Este un concept degevil de simplu, dar unul care vă permite să faceți atât de mult atunci când ați înțeles pe deplin. De fapt, starea desenului deține o cantitate masivă de informații vizuale despre panza, cum ar fi matricea de transformare, regiunea de tăiere și următoarele proprietăți; globalAlpha, globalCompositeOperation, strokeStyle, stil de completare, lățimea liniei, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, font, aliniere text, și textBaseline. Cele mai multe dintre acestea vor fi noi pentru tine, așa că nu vă faceți griji. Veți învăța despre transformări și alte lucruri distractive, cum ar fi umbrele, în articolul următor.

Salvarea stării desenului

Utilizarea stării desenului este simplă, dar înțelegerea completă poate dura puțin timp. Înlocuiți codul din ultima secțiune cu următoarele:

 ctx.fillStyle = "rgb (0, 0, 255)"; ctx.save (); ctx.fillRect (50, 50, 100, 100);

Acest lucru este cu adevărat tot ce aveți nevoie pentru a salva starea de desen: un singur apel la Salvați metodă. Ți-am spus că e simplu!

Ce se întâmplă aici este că schimbați stilul de umplere al pânzei în albastru, apoi salvați starea desenului, care împinge starea actuală în teancul pe care vorbeam mai devreme. În mod implicit, stiva de stări de desen este goală.

Este important să rețineți că stiva funcționează la fel ca un teanc de hârtie de pe birou; primul element din stiva este în partea de jos, cu cel mai nou element din partea de sus. Dacă doriți să ajungeți la primul element din nou, trebuie să scoateți mai întâi toate elementele de deasupra. Aceasta este cunoscută ca un prim sistem de ultimă oră, sau ultimul în primul rând, dacă doriți să o priviți invers.

Restaurarea stării desenului

Salvarea stării de desen este minunat și totul, dar de fapt, folosirea ei din nou este în mod corespunzător un pic mai util. Pentru a face asta, veți folosi restabili metodă.

Adăugați următorul cod la codul de mai sus:

 ctx.fillStyle = "rgb (255, 0, 0)"; ctx.fillRect (200, 50, 100, 100);

Acest lucru va atrage un alt dreptunghi pe pânză, dar de această dată într-o altă culoare (roșu):

Toate lucrurile destul de standard până acum, dar ce se întâmplă dacă doriți să reveniți la culoarea albastră și să desenați un alt dreptunghi? Ei bine, ai putea seta stilul de umplere manual ca albastru, dar asta ar fi plictisitor. Să încercăm să folosim metoda de restaurare și să vedem ce se întâmplă.

Adăugați următorul cod:

 ctx.restore () ctx.fillRect (350, 50, 100, 100);

Acest lucru va atrage un alt dreptunghi, dar de data aceasta cu stilul original de umplere:

Cât de ușor a fost asta? Apelul la restabili a scos și a scos ultima stare de desen adăugată în teanc și apoi a aplicat-o pe panza, economisind o grămadă de timp. Bine, s-ar putea să nu ți-am salvat un număr masiv de timp în acest exemplu, dar ar fi schimbat tot felul de proprietăți și ai făcut transformări pe pânză.

Utilizarea mai multor stări de desen

Deci știi cum să folosești starea desenului pentru o singură apariție, dar ce se întâmplă dacă salvezi mai multe stări de desen? Pentru ochii ascuțiți s-ar putea să vă amintiți că m-am referit la stivă ca o grămadă de hârtie; ultima în, prima afară. Să vedem cum funcționează acest lucru în cod.

Actualizați codul anterior pentru a salva starea desenului după ce ați setat stilul de umplere pe roșu:

 ctx.fillStyle = "rgb (0, 0, 255)"; ctx.save (); ctx.fillRect (50, 50, 100, 100); ctx.fillStyle = "rgb (255, 0, 0)"; ctx.save (); ctx.fillRect (200, 50, 100, 100); ctx.restore () ctx.fillRect (350, 50, 100, 100);

Chiar dacă acest lucru este practic același cod ca înainte, totul s-ar fi schimbat, deoarece ultima stare de desen adăugată în stivă conține stilul de umplere roșu:

Pentru a restabili prima stare (stilul albastru de umplere), va trebui să apelați restabili pentru a doua oară, adăugați următorul cod:

 ctx.restore (); ctx.fillRect (50, 200, 100, 100);

Aceasta va trage și va scoate prima stare de pe stivă și o va aplica pe panza, oferindu-vă un stil de umplere albastră:

Prin utilizarea mai multor stări de desen ca aceasta puteți salva o grămadă de timp. E destul de drăguț!


Înfășurarea lucrurilor

Sper că nu am trecut prea repede prin toate astea. Unele dintre conceptele pe care le-am acoperit sunt destul de avansate și vă încurajez să recitiți articolul și să jucați cu codul pentru a înțelege mai bine ce se întâmplă.

În următorul articol veți învăța cum să efectuați transformări pe panza, precum și cum să utilizați umbre și gradienți. Momente incitante!

Cod