Als ich CSSDesignAwards durchstöberte, habe ich einen Effekt gefunden, der den Bildinhalt aufteilt (Website: https://weareludwig.com). Er fühlte sich sehr cool an, also habe ich versucht, ihn selbst zu implementieren. und der Effekt war ziemlich gut. Überprüfen Sie den Effekt https://codepen.io/geeknoble/pen/OQaOVG
analysierenErstens können wir feststellen, dass der Inhalt des Bildes in kleine Rechtecke unterteilt ist und jedes Rechteck zufällig übersetzt wird. Die Funktion drawImage von Canvas kann den Bildinhalt zuschneiden und in die Canvas-Leinwand zeichnen. Daher besteht das Hauptimplementierungsprinzip dieses Effekts in der Verwendung von drawImage. Es gibt zwei Haupteffekte: Der eine dient zum Unterbrechen und Wiederherstellen des Bildinhalts und der andere zum Wechseln zum nächsten Bild. DrawImage kann für beide Effekte verwendet werden, die Bewegungsentfernung ist jedoch unterschiedlich. Sobald Sie die allgemeine Idee haben, können Sie mit der Umsetzung beginnen.
erste ArbeitZuerst müssen wir einige Variablen initialisieren, z. B. die Breite und Höhe des Bildes, die Anzahl der Rechtecke, die Schnittgröße usw., dann die Koordinaten jedes Rechtecks berechnen und eine Doppelschleife verwenden, um die Rechteckkoordinaten zu speichern in Daten. Jedes Rechteck hat eine zufällige Verschiebung, und diese Verschiebung muss auch zufällig gespeichert werden. Unter diesen stellen x und y die Koordinaten der Leinwand dar, und x1 und y1 repräsentieren die Koordinaten des Bildausschnitts.
init: function (context, width, height, area, img) { this.context = context this.imgWidth = img[0].width; //Bildbreite und -höhe = img[ 0 ].height; this.index = 0; //Aktuelle Bildnummer this.width = width; //Leinwandbreite und -höhe this.area = height/12; //Die Länge des kleinen Rechtecks this.countX = width / this.area; //Die Anzahl der kleinen Rechtecke in horizontaler und vertikaler Richtung this.countY = height / this.area / this .countX; //Bildbreite und -höhe im kleinen Rechteck this.wy = this.imgHeight / this.countY; //Bildstatus, true bedeutet nicht geteilt this.dataFlag = true; Koordinatenstatus, true bedeutet, dass this.duration kein Zufallswert hinzugefügt wird = 1000; //Animationszeit this.duration2 = 0; this.data = []; //Kleiner Rechteckkoordinatenwert //Initialisieren Sie die Rechteckkoordinaten x1 = 0, y1 = 0, x = 0, y = 0; for (var i = 0; i < this.countY; i++) { for (var j = 0; j < this.countX; j++) { context.drawImage(this.img[this.index], x1, y1, this.wx, this.wy, x, y, this.area, this.area); //Speicherung rechteckiger Koordinaten this.data.push({ x1: x1, y1: y1, x: x, y: y }); //Zufällige Werte hinzufügen this.randoms.push(random(-this.area, this.area)); x1 += this.wx } x1 = 0; y1 += this. wy; x = 0; y += this.area;Kanten erkennen
Bevor wir dem Rechteck eine Verschiebung hinzufügen, müssen wir feststellen, ob die verschobenen Koordinaten die Grenze des Bildes überschreiten. Wenn sich das Rechteck beispielsweise entlang der y-Achse bewegt, kann es sich nur nach oben bewegen Die aktuelle Koordinate plus der Verschiebungswert ist kleiner als 0 oder größer als die Breite und Höhe des Bildes. Wenn die aktualisierten Koordinaten kleiner als 0 sind, muss der Zufallswert eine negative Zahl sein. Wenn er größer als die Höhe des Bildes ist, ändern Sie ihn in eine negative Zahl. Da sich jedes Rechteck in eine Richtung bewegt, schreibe ich hier, dass die geraden Bits die x-Achse und die ungeraden Bits die y-Achse bewegen.
// Kante erkennen checkMargin: function () { var self = this; this.data.forEach(function (item, index) { if (index % 2 == 0) { // Verschieben Sie die x-Achse, wenn der Index a ist Vielfaches von 2, andernfalls die y-Achse verschieben if (item.x1 + self.randoms[index] < 0) // In eine positive Zahl ändern self.randoms[index] = -self.randoms[index]; if (item.x1 + self.randoms[index] < 0) .x1 + self.wx + self.randoms[index] > self.imgWidth ) // In negative Zahl ändern self.randoms[index] = -Math.abs(self.randoms[index]) } else { if (item.y1 + self . randoms[index] < 0) self.randoms[index] = -self.randoms[index]; if (item.y1 + self.randoms[index] + self.wy > self.imgHeight) self.randoms[index] = -Math.abs(self.randoms[index]) } }) }Trennung und Genesung
Die Trennung und Wiederherstellung des Animationsinhalts besteht darin, den Wert der rechteckigen Koordinaten zu aktualisieren. Um den Inhalt zu stören, fügen Sie einfach Zufallswerte zu den Koordinaten in den Daten hinzu, und die Wiederherstellung besteht darin, die Zufallswerte zu subtrahieren.
// Kante erkennen checkMargin: function () { var self = this; this.data.forEach(function (item, index) { if (index % 2 == 0) { // Verschieben Sie die x-Achse, wenn der Index a ist Vielfaches von 2, andernfalls die y-Achse verschieben if (item.x1 + self.randoms[index] < 0) // In eine positive Zahl ändern self.randoms[index] = -self.randoms[index]; .x1 + self.wx + self.randoms[index] > self.imgWidth ) // In negative Zahl ändern self.randoms[index] = -Math.abs(self.randoms[index]) } else { if (item.y1 + self . randoms[index] < 0) self.randoms[index] = -self.randoms[index]; if (item.y1 + self.randoms[index] + self.wy > self.imgHeight) self.randoms[index] = -Math.abs(self.randoms[index]) } }) }
Nach dem Speichern der Koordinaten können Sie den Bewegungsvorgang mit einem reibungslosen Übergang durchführen. Dieser Algorithmus verfügt über 4 Parameter: die aktuelle Zeit, die Anfangsposition und die Endposition. Animationszeit. Einzelheiten finden Sie im Artikel von Zhang Xinxu https://www.zhangxinxu.com/wordpress/2016/12/how-use-tween-js-animation-easing/. Tween.js kann verwendet werden, um die Distanz zu berechnen, die in jedem Frame zurückgelegt werden muss, und dann requestAnimationFrame verwenden, um die Koordinaten zu aktualisieren.
blockAnimation: function () { var flag = 1; if (this.state) { // Bestimmen Sie, ob das Bild unterbrochen oder wiederhergestellt werden soll this.update(true) } else { flag = -1; ; } var self = this; this.startTime = +new Date(); // Holen Sie sich die aktuelle Zeit this.state = !this.state(); if (t >= self.startTime + self.duration) { // Endbedingung der Animation return false; } self.data.forEach(function (item, index) { if (index % 2 == 0) { var pos = Math.tween.Expo. easyInOut(t - self.startTime, 0, self.randoms[index] * flag, self.duration); Berechnen Sie die in jedem Frame zurückgelegte Distanz self.context.drawImage(self.img[self.index], item.x1 + pos, item.y1, self.wx, self.wy, item.x, item.y, self. Bereich, self.area); } else { var pos = Math.tween.Expo.easeInOut(t - self.startTime, 0, self.randoms[index] * flag, self.duration); self.context.drawImage(self.img[self.index], item.x1, item.y1 + pos, self.wx, self.wy, item.x, item.y, self.area, self.area); } }); requestAnimationFrame(animation })( );
Zu diesem Zeitpunkt wurde die Animation der Trennung und Wiederherstellung implementiert.
BildumschaltungAls nächstes beginnen wir mit der Verarbeitung des Bildwechselteils. Dies ähnelt der Karussellbildanimation, die die Position jedes Bildes um die Breite des visuellen Fensters verschiebt Höhe zu erreichen y Einschaltachse. Anders als beim Karussellbild haben wir hier nur ein Canvas-Tag. Beim Wechseln müssen wir nur die Koordinaten des aktuellen Bildes und des nächsten Bildes ändern. Die Bewegungsentfernung des aktuellen Bildes beträgt y1 + pos Das nächste Bild ist y1 + pos. - imgHeight (es versteht sich von selbst, warum imgHeight reduziert werden sollte).
//Vertikale Gleitanimation VerticalAnimation: function (val) { return false } this.checkTime(2); Nach oben oder unten schieben if ((this.index + val) < 0 || (this.index + val) >= (this.img.length)) { // Bestimmen Sie, ob die Bildseriennummer das Ende ist return false } dieser.Zustand ? this.update(true) : this.update(false); (function animation() { var t = +new Date(); if (t >= self.startTime + self .duration2) { val === 1 ? self.index--; //Anpassen der Reihenfolge der Bilder self.index < 0 ? self.index = self.img.length - 1 : self.index; .index >= self.img.length ? self.index = 0 : self.index; return false } self.data.forEach(function (item) { var pos = Math.tween.Cubic.easeInOut(t - self.startTime, 0, (self.imgHeight) * val, self.duration2); // Aktuelle Bildkoordinaten aktualisieren self.context.drawImage(self.img[self.index], item.x1, item.y1 + pos, self.wx, self.wy, item.x, item.y, self.area, self.area // Aktualisieren Sie die Koordinaten des nächsten Bildes self.context.drawImage(self.img[ self. index + val], item.x1, item.y1 + pos - self.imgHeight * val, self.wx, self.wy, item.x, item.y, self.area, self.area); }); requestAnimationFrame(animation })() }
Das Gleiche gilt für das Umschalten der x-Achse. Jetzt sind alle Funktionen fast abgeschlossen. Der vollständige Code kann im Codepen angezeigt werden.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.