Vytváření interaktivních vizualizací pomocí JavaScriptu a plátna HTML5

, Author

Projekt 1: Ledové čáry

Pro nejlepší výsledky otevřete na celou obrazovku

Nejprve jsou naše čáry bílé, takže přejděme do CSS a dejme plátnu tmavé pozadí:

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

Konstruktor čar

Nyní se vrátíme k canvas.js . Vytvoříme novou třídu Line:

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

Kromě určení polohy každé čáry x a y máme několik dalších vlastností, které nám zpestří vizuální stránku:

  • Můžeme použít vlastnost offset pro vykreslení čar v různých vzdálenostech od sebe.
  • V našem příkladu budeme také používat kruhový pohyb. K určení úhlu pohybu můžeme použít vlastnost radians a k určení rychlosti pohybu vlastnost velocity.

Metoda kreslení čar

Dále budeme chtít vykreslit naše čáry. V dolní části každé čáry je malé kolečko, které můžeme definovat pomocí funkce arc, a pak čára vystřelí do horní části obrazovky:

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

Pro vyzkoušení, že to funguje, můžete vytvořit ukázkovou čáru:

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

Generování 100 čar

Chceme však, aby čáry vyplnily obrazovku, takže budeme potřebovat způsob, jak vytvořit pole 100 čar. Zde je jednoduchá verze:

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

Pro zobrazení těchto řádků budeme muset spustit jejich metody draw. Protože je budeme brzy animovat, nejlépe to uděláme ve funkci animate:

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

Máme nyní 100 řádků! Můžeme však naši výchozí pozici udělat zajímavější: v níže uvedeném kódu nám proměnná random pomůže zajistit jemnou variabilitu, která dodá celkovému efektu přirozenější vzhled. (Používám také proměnnou Math.sin(i), abych do počátečních pozic přidal trochu vlnění. Není to nutné, ale je to příjemný prvek)

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

Hrajte si s čísly, dokud nezískáte počáteční vzor, který se vám líbí!“

Animace

Odtud je velmi jednoduché přidat požadovanou animaci. Vraťte se do naší třídy Line a do metody update přidejte následující:

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

S každým snímkem animace se this.radians zvýší o this.velocity . Pomocí this.radians pak vytvoříme kruhový pohyb, a to prostřednictvím Math.cos .

Pokud jste se s Math.sin nebo Math.cos ještě nesetkali (nebo je vaše trigonometrie trochu zrezivělá!), nemělo by vám to bránit v dalším postupu. Jen vězte, že Math.cos nám umožňuje vytvořit pohyb tam a zpět, a to podle vzoru shodného s fialovou čarou v grafu níže:

Kosinová vlna

Nakonec přidáním this.offset , začnou čáry smyčkovat pod různými úhly.

Myslím, že je to docela pěkný efekt. Ale na závěr přidáme nějakou interaktivitu. Když uživatel najede na čáry, zařídíme, aby změnily barvu.

Interaktivita

Nejjednodušší způsob, jak zjistit, zda se uživatelova myš nachází nad jednou z čar, je použít vestavěnou metodu isPointInPath plátna.

Bez dalších úprav to ale nebude moc platné. Čáry jsou široké pouze 1 pixel, takže šance na vyvolání nějaké změny bude příliš malá na to, aby to bylo zajímavé!“

Skvělým řešením tohoto problému je vytvoření neviditelných čar za každou z našich čar. Neviditelné čáry by měly být širší a můžeme je použít ke spuštění isPointInPath.

isPointInPath

Uvnitř naší metody draw vytvoříme funkci s názvem drawLinePath . Ta by měla přijmout width pro naše neviditelné čáry a color (ve kterou se promění naše viditelné čáry, když jsou neviditelné čáry v kontaktu):

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

(Všimněte si, že použití šipkových funkcí výše implicitně váže správný kontext pro this ).

Můžeme pak snadno přidávat různé šířky neviditelných čar, aby se spouštěly různé změny barev. Následující kód by měl jasně ukázat, o co jde:

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

Ale pro jemnější efekt zkuste:

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

A to je vše!

Pro kompletní kód JavaScriptu se podívejte na tento gist.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.