Projekt 1: Eisige Linien
Zunächst sind unsere Linien weiß, also gehen wir in unser CSS und geben der Leinwand einen dunklen Hintergrund:
canvas {
background: linear-gradient(45deg, #0d1011 0% 20%, #163486);
}
Line Constructor
Nun zurück zu canvas.js
. Erstellen wir eine neue Line
Klasse:
class Line {
constructor(x, y, offset) {
this.x = x;
this.y = y;
this.offset = offset;
this.radians = 0;
this.velocity = 0.01;
}
Abgesehen von der Bestimmung der x
und y
Position jeder Linie, haben wir noch ein paar andere Eigenschaften, um unsere Darstellung interessanter zu machen:
- Wir können die
offset
Eigenschaft verwenden, um die Linien in unterschiedlichen Abständen zueinander darzustellen. - Wir werden in unserem Beispiel auch eine kreisförmige Bewegung verwenden. Mit der Eigenschaft
radians
können wir den Bewegungswinkel und mit der Eigenschaftvelocity
die Geschwindigkeit der Bewegung bestimmen.
Line Draw Method
Als nächstes wollen wir unsere Linien zeichnen. Am unteren Ende jeder Linie befindet sich ein kleiner Kreis, den wir mit der Funktion arc
definieren können, und dann schießt die Linie an den oberen Rand des Bildschirms:
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
}
}
Um zu testen, dass es funktioniert, können Sie eine Beispiellinie erstellen:
const line = new Line(250, 800, 0);
line.draw();
Erzeugen von 100 Linien
Aber wir wollen, dass die Linien den Bildschirm ausfüllen, also müssen wir eine Möglichkeit finden, ein Array mit 100 Linien zu erstellen. Hier ist eine einfache Version:
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)
)
);
};
Um diese Zeilen anzuzeigen, müssen wir ihre draw
Methoden auslösen. Da wir sie bald animieren werden, ist der beste Ort dafür die animate
-Funktion:
function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, window.innerWidth, window.innerHeight);
lineArray.forEach(line => {
line.draw();
});
};animate();
Wir haben jetzt 100 Zeilen! Aber wir können unsere Ausgangsposition interessanter gestalten: Im folgenden Code sorgt die Variable random
für eine subtile Variation, die dem Gesamteffekt ein natürlicheres Aussehen verleiht. (Ich verwende auch Math.sin(i)
, um den Startpositionen eine gewisse Welligkeit zu verleihen. Das ist nicht notwendig, aber eine nette Idee.)
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)
)
);
};
Spielen Sie mit den Zahlen herum, bis Sie ein Startmuster haben, das Ihnen gefällt!
Animation
Ab hier ist es sehr einfach, die gewünschte Animation hinzuzufügen. Gehen Sie zurück zu unserer Line
-Klasse und fügen Sie in der update
-Methode Folgendes hinzu:
this.radians += this.velocity;
this.y = this.y + Math.cos(this.radians + this.offset);
Bei jedem Animationsframe wird this.radians
um this.velocity
erhöht. Wir verwenden dann this.radians
, um eine kreisförmige Bewegung über Math.cos
zu erzeugen.
Wenn Sie Math.sin
oder Math.cos
noch nie gesehen haben (oder Ihre Trigonometrie etwas eingerostet ist!), sollte Sie das nicht davon abhalten, weiterzumachen. Mit Math.cos
können wir eine Hin- und Herbewegung erzeugen, die mit der lila Linie im folgenden Diagramm identisch ist:
Schließlich werden die Linien durch Hinzufügen von this.offset
in verschiedenen Winkeln zu einer Schleife.
Ich denke, das ist ein ziemlich schöner Effekt. Aber um das Ganze abzurunden, sollten wir noch etwas Interaktivität hinzufügen. Wenn der Benutzer den Mauszeiger über die Linien bewegt, sollen sie ihre Farbe ändern.
Interaktivität
Der einfachste Weg, um zu sehen, ob sich die Maus des Benutzers über einer der Linien befindet, ist die Verwendung der in Canvas eingebauten isPointInPath
-Methode.
Aber ohne weitere Anpassungen wird das nicht viel nützen. Die Linien sind nur 1 Pixel breit, so dass die Wahrscheinlichkeit, dass sie Änderungen auslösen, zu gering ist, um interessant zu sein!
Eine gute Lösung für dieses Problem ist es, unsichtbare Linien hinter jeder unserer Linien zu erstellen. Die unsichtbaren Linien sollten breiter sein, und wir können sie benutzen, um isPointInPath.
isPointInPath
Innerhalb unserer draw
Methode, erstellen wir eine Funktion namens drawLinePath
. Sie sollte ein width
für unsere unsichtbaren Linien und ein color
(das unsere sichtbaren Linien werden, wenn die unsichtbaren Linien in Kontakt sind) annehmen:
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;
};
};
(Beachten Sie, dass die Verwendung von Pfeilfunktionen oben implizit den richtigen Kontext für this
bindet).
Wir können dann leicht verschiedene Breiten von unsichtbaren Linien hinzufügen, um verschiedene Farbänderungen auszulösen. Der folgende Code sollte verdeutlichen, was vor sich geht:
drawLinePath(150, 'red');
drawLinePath(50, 'yellow');
Für einen subtileren Effekt versuchen Sie es mit:
drawLinePath(150, '#baf2ef');
drawLinePath(50, '#dcf3ff');
Und das war’s!
Den vollständigen JavaScript-Code finden Sie in diesem Gist.