Creați imagini interactive cu JavaScript și HTML5 Canvas

, Author

Proiect 1: Linii de gheață

Pentru cele mai bune rezultate, deschideți în ecran complet

În primul rând, liniile noastre sunt albe, așa că haideți să intrăm în CSS-ul nostru și să dăm pânzei un fundal întunecat:

canvas {
background: linear-gradient(45deg, #0d1011 0% 20%, #163486);
}

Constructor de linii

Acum, înapoi la canvas.js . Să creăm o nouă clasă Line:

class Line {
constructor(x, y, offset) {
this.x = x;
this.y = y;
this.offset = offset;
this.radians = 0;
this.velocity = 0.01;
}

În afară de determinarea poziției fiecărei linii x și y, avem alte câteva proprietăți pentru a face vizualurile noastre mai interesante:

  • Potem folosi proprietatea offset pentru a reda liniile la diferite distanțe una față de cealaltă.
  • De asemenea, vom folosi mișcarea circulară în exemplul nostru. Putem folosi proprietatea radians pentru a defini unghiul de mișcare și proprietatea velocity pentru a determina viteza de mișcare.

Metoda de desenare a liniilor

În continuare, vom dori să desenăm liniile noastre. Există un mic cerc în partea de jos a fiecărei linii, pe care îl putem defini cu ajutorul funcției arc, iar apoi linia se lansează spre partea de sus a ecranului:

class Line {
constructor(x, y, offset) {
this.x = x;
this.y = y;
this.offset = offset;
this.radians = 0;
this.velocity = 0.01;
} draw = () => {
c.strokeStyle = 'rgba(255, 255, 255, 0.5)';
c.fillStyle = 'rgba(255, 255, 255, 0.3)'; c.beginPath();
c.arc(this.x, this.y, 1, 0, Math.PI * 2, false);
c.fill();
c.moveTo(this.x, this.y);
c.lineTo(this.x + 300, this.y - 1000);
c.stroke();
c.closePath(); this.update();
} update = () => {
// this is where we control movement and interactivity
}
}

Pentru a testa dacă funcționează, puteți crea o linie de probă:

const line = new Line(250, 800, 0);
line.draw();

Generarea a 100 de linii

Dar vrem ca liniile să umple ecranul, așa că vom avea nevoie de o modalitate de a crea o matrice de 100 de linii. Iată o versiune simplă:

const lineArray = ;for (let i = 0; i < 100; i++) { const start = { x: -250, y: 800 };
const unit = 25; lineArray.push(
new Line(
start.x + unit * i,
start.y + i * -3,
0.1 + (1 * i)
)
);
};

Pentru a vizualiza aceste linii, va trebui să declanșăm metodele lor draw. Deoarece le vom anima în curând, cel mai bun loc pentru a face acest lucru este în funcția animate:

function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, window.innerWidth, window.innerHeight);
lineArray.forEach(line => {
line.draw();
});
};animate();

Acum avem 100 de linii! Dar putem face poziția noastră de pornire mai interesantă: în codul de mai jos, variabila random ne ajută să oferim o variație subtilă care conferă efectului general un aspect mai natural. (De asemenea, folosesc Math.sin(i) pentru a adăuga o oarecare ondulație în pozițiile de pornire. Acest lucru nu este necesar, dar este o atingere plăcută.)

const lineArray = ;for (let i = 0; i < 100; i++) { const start = { x: -250, y: 800 };
const random = Math.random() - 0.5;
const unit = 25; lineArray.push(
new Line(
start.x + ((unit + random) * i),
start.y + (i + random) * -3 + Math.sin(i) * unit,
0.1 + (1 * i)
)
);
};

Jucă-te cu numerele până când ai un model de pornire care îți place!

Animare

De aici, este foarte simplu să adăugăm animația pe care o dorim. Întoarceți-vă la clasa noastră Line și apoi adăugați următoarele în metoda update:

this.radians += this.velocity;
this.y = this.y + Math.cos(this.radians + this.offset);

Cu fiecare cadru de animație, this.radians va crește cu this.velocity . Vom folosi apoi this.radians pentru a crea mișcarea circulară, prin Math.cos .

Dacă nu ați mai întâlnit Math.sin sau Math.cos până acum (sau trigonometria dvs. este puțin ruginită!), acest lucru nu ar trebui să vă împiedice să urmăriți. Aflați doar că Math.cos ne permite să creăm o mișcare înainte și înapoi, într-un model identic cu linia mov din graficul de mai jos:

Unda cosinusoidală

În cele din urmă, prin adăugarea lui this.offset , liniile vor începe să se bucleze în unghiuri diferite.

Cred că acesta este un efect destul de frumos. Dar pentru o notă finală, să adăugăm puțină interactivitate. Când utilizatorul trece pe deasupra liniilor, haideți să le facem să își schimbe culoarea.

Interactivitate

Cel mai simplu mod de a vedea dacă mouse-ul utilizatorului se află deasupra uneia dintre linii este să folosim metoda isPointInPath încorporată în canvas.

Dar, fără alte modificări, aceasta nu va fi de mare folos. Liniile au o lățime de numai 1 pixel, așa că șansele de a declanșa orice schimbare vor fi prea mici pentru a fi interesante!

O soluție excelentă la această problemă este de a crea linii invizibile în spatele fiecărei linii a noastră. Liniile invizibile ar trebui să fie mai late, și le putem folosi pentru a declanșa isPointInPath.

isPointInPath

În interiorul metodei noastre draw, să creăm o funcție numită drawLinePath . Aceasta ar trebui să preia un width pentru liniile noastre invizibile și un color (în care liniile noastre vizibile vor deveni, atunci când liniile invizibile sunt în contact):

const drawLinePath = (width = 0, color) => {
c.beginPath();
c.moveTo(this.x - (width / 2), this.y + (width / 2));
c.lineTo(this.x - (width / 2) + 300, this.y - (width / 2) - 1000);
c.lineTo(this.x + (width / 2) + 300, this.y - (width / 2) - 1000);
c.lineTo(this.x + (width / 2), this.y - (width / 2));
c.closePath();
if (c.isPointInPath(mouse.x, mouse.y) && color) {
c.strokeStyle = color;
};
};

(Rețineți că utilizarea funcțiilor săgeată de mai sus leagă implicit contextul corect pentru this ).

Potem apoi adăuga cu ușurință diferite lățimi ale liniilor invizibile pentru a declanșa diferite schimbări de culoare. Următorul cod ar trebui să clarifice ce se întâmplă:

drawLinePath(150, 'red');
drawLinePath(50, 'yellow');

Dar, pentru un efect mai subtil, încercați:

drawLinePath(150, '#baf2ef');
drawLinePath(50, '#dcf3ff');

Și asta e tot!

Pentru codul JavaScript complet, verificați acest gist.

Lasă un răspuns

Adresa ta de email nu va fi publicată.