Crea immagini interattive con JavaScript e HTML5 Canvas

, Author

Progetto 1: Linee ghiacciate

Per i migliori risultati, apri a schermo intero

Per prima cosa, le nostre linee sono bianche, quindi andiamo nel nostro CSS e diamo alla tela uno sfondo scuro:

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

Costruttore di linee

Ora torna a canvas.js . Creiamo una nuova classe Line:

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

Oltre a determinare la posizione x e y di ogni linea, abbiamo alcune altre proprietà per rendere le nostre immagini più interessanti:

  • Possiamo usare la proprietà offset per rendere le linee a varie distanze l’una dall’altra.
  • Abbiamo anche intenzione di usare il movimento circolare nel nostro esempio. Possiamo usare la proprietà radians per definire l’angolo del movimento e la proprietà velocity per determinare la velocità del movimento.

Metodo di disegno delle linee

Prossimo, vogliamo disegnare le nostre linee. C’è un piccolo cerchio nella parte inferiore di ogni linea, che possiamo definire usando la funzione arc, e poi la linea spara in cima allo schermo:

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
}
}

Per provare che funziona, potete creare una linea di esempio:

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

Generazione di 100 linee

Ma noi vogliamo che le linee riempiano lo schermo, quindi abbiamo bisogno di un modo per creare un array di 100 linee. Ecco una versione semplice:

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)
)
);
};

Per visualizzare queste linee, dovremo attivare i loro metodi draw. Dato che presto le animeremo, il posto migliore per farlo è nella funzione animate:

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

Ora abbiamo 100 linee! Ma possiamo rendere la nostra posizione di partenza più interessante: nel codice qui sotto, la variabile random aiuta a fornire una sottile variazione che dà all’effetto complessivo un aspetto più naturale. (Sto anche usando Math.sin(i) per aggiungere qualche ondulazione nelle posizioni di partenza. Non è necessario, ma è un bel tocco.)

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)
)
);
};

Gioca con i numeri finché non hai un modello iniziale che ti piace!

Animazione

Da qui, è molto semplice aggiungere l’animazione che vogliamo. Torniamo alla nostra classe Line e aggiungiamo il seguente nel metodo update:

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

Con ogni fotogramma di animazione, this.radians aumenterà di this.velocity . Useremo quindi this.radians per creare un movimento circolare, tramite Math.cos .

Se non avete mai incontrato Math.sin o Math.cos prima (o la vostra trigonometria è un po’ arrugginita!), questo non dovrebbe impedirvi di seguirci. Sappiate che Math.cos ci permette di creare un movimento avanti e indietro, in un modello identico alla linea viola nel grafico qui sotto:

Onda cosinica

Infine, aggiungendo this.offset , le linee inizieranno a girare ad angoli diversi.

Credo che questo sia un bell’effetto. Ma per un tocco finale, aggiungiamo un po’ di interattività. Quando l’utente passa sopra le linee, facciamole cambiare colore.

Interattività

Il modo più semplice per vedere se il mouse dell’utente è sopra una delle linee è usare il metodo integrato isPointInPath di canvas.

Ma, senza ulteriori modifiche, questo non sarà molto utile. Le linee sono larghe solo 1 pixel, quindi la possibilità di innescare qualsiasi cambiamento sarà troppo bassa per essere interessante!

Un’ottima soluzione a questo problema è creare linee invisibili dietro ciascuna delle nostre linee. Le linee invisibili dovrebbero essere più larghe, e possiamo usarle per attivare isPointInPath.

isPointInPath

All’interno del nostro metodo draw, creiamo una funzione chiamata drawLinePath . Dovrebbe prendere un width per le nostre linee invisibili, e un color (che le nostre linee visibili diventeranno, quando le linee invisibili sono in contatto):

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;
};
};

(Notate che l’uso delle funzioni freccia sopra lega implicitamente il contesto corretto per this ).

Possiamo poi facilmente aggiungere diverse larghezze di linee invisibili per attivare diversi cambiamenti di colore. Il seguente codice dovrebbe chiarire cosa sta succedendo:

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

Ma, per un effetto più sottile, provate:

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

E questo è tutto!

Per il codice JavaScript completo, guardate questo gist.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.