Gehen

Joseph Gordon-Levitt
Freigeben: 2025-03-25 10:23:10
Original
224 Leute haben es durchsucht

Gehen

Ich bin mir nicht sicher, wie dieser zustande kam. Aber es ist eine Geschichte. In diesem Artikel geht es mehr darum, ein Konzept zu schulen, das Ihnen dabei hilft, Ihre Animationen auf andere Weise nachzudenken. Es kommt so vor, dass dieses bestimmte Beispiel unendlich scrolling - insbesondere die „perfekte“ unendliche Schriftrolle für ein Kartenspiel, ohne sie zu duplizieren.

Warum bin ich hier? Nun, das alles begann von einem Tweet. Ein Tweet, der mich über Layouts und Side-Scrolling-Inhalte nachdachte.

Ich habe dieses Konzept genommen und es auf meiner Website verwendet. Und zum Zeitpunkt des Schreibens ist es immer noch in Aktion.

Dann musste ich mehr über Galerieansichten und Side-Scrolling-Konzepte nachdenken. Wir sprangen auf einen Livestream und beschlossen, zu versuchen, so etwas wie das alte Apfel -Cover -Flussmuster zu machen. Erinnerst du dich daran?

Meine ersten Gedanken, dies zu machen, nahm an, dass ich dies machen würde, damit es ohne JavaScript funktioniert, wie es in der obigen Demo so ist, dass es „progressive Verbesserung“ verwendet. Ich griff nach Greensock und scrolltrigger, und wir gingen aus. Ich kam von dieser Arbeit ziemlich enttäuscht. Ich hatte etwas, konnte aber nicht ganz unendlich scrollen, um zu arbeiten, wie ich wollte. Die Tasten „Weiter“ und „vorherige“ wollten keinen Ball spielen. Sie können es hier sehen und es erfordert horizontales Scrollen.

Also habe ich im Greensock Forum einen neuen Thread geöffnet. Ich wusste nicht, dass ich mich einem ernsthaften Lernen öffnen würde! Wir haben das Problem mit den Tasten gelöst. Aber ich musste mich fragen, ob etwas anderes möglich war. Gab es einen „sauberen“ Weg, um unendlich zu scrollen? Ich hatte etwas im Stream ausprobiert, hatte aber kein Glück. Ich war neugierig. Ich hatte eine in diesem Stift verwendete Technik ausprobiert, die ich für die Scrolltrigger -Version erstellt habe.

Die erste Antwort war, dass es irgendwie schwierig ist zu tun:

Der schwierige Teil an unendlichen Dingen bei Scroll ist, dass die Bildlaufleiste begrenzt ist, während der Effekt, den Sie wollen, nicht ist. Sie müssen also entweder die Bildlaufposition wie diese Demo (gefunden im Abschnitt "Scrolltrigger-Demos) schleifen oder direkt in die scrollbezogenen Navigationsereignisse (wie das Rad-Ereignis) angeschlossen werden, anstatt die eigentliche Scroll-Position tatsächlich zu verwenden.

Ich dachte, das sei der Fall und war froh, es "As-is" zu lassen. Ein paar Tage vergingen und Jack ließ eine Antwort fallen, die mich irgendwie umgehauen hat, als ich anfing, mich hineinzugraben. Und jetzt, nachdem ich es durchgemacht habe, bin ich hier, um die Technik mit Ihnen zu teilen.

Irgendetwas animieren

Eine Sache, die oft mit GSAP übersehen wird, ist, dass Sie fast alles daran animieren können. Dies liegt oft daran, dass visuelle Dinge das sind, was sich beim Nachdenken über die Animation einspringt - die tatsächliche physische Bewegung von etwas. In unserem ersten Gedanken geht es nicht darum, diesen Prozess auf einen Meta-Ebene zu bringen und von einem Schritt zurück zu animieren.

Denken Sie jedoch in größerem Maßstab über die Animationsarbeit nach und zerlegen Sie sie dann in Schichten. Zum Beispiel spielst du einen Cartoon. Der Cartoon ist eine Sammlung von Kompositionen. Jede Komposition ist eine Szene. Und dann haben Sie die Kraft, diese Sammlung von Kompositionen mit einer Fernbedienung zu schrubben, sei es auf YouTube, mit Ihrer TV -Fernbedienung oder was auch immer. Es gibt fast drei Ebenen zu dem, was passiert.

Und dies ist der Trick, den wir benötigen, um verschiedene Arten von unendlichen Schleifen zu erstellen. Dies ist das Hauptkonzept hier. Wir animieren die Spielposition einer Zeitleiste mit einer Zeitleiste. Und dann können wir diese Zeitleiste mit unserer Bildlaufposition schrubben.

Mach dir keine Sorgen, wenn das verwirrend klingt. Wir werden es zerlegen.

"Meta" gehen

Beginnen wir mit einem Beispiel. Wir werden ein Tween erstellen, das einige Kisten von links nach rechts bewegt. Hier ist es.

Zehn Kisten, die weiter nach rechts gehen. Das ist bei Greensock ziemlich einfach. Hier verwenden wir und wiederholen wir, um die Animation am Laufen zu halten. Aber wir haben zu Beginn jeder Iteration eine Lücke. Wir nutzen auch Staffel, um die Bewegung zu platzieren, und das wird eine wichtige Rolle spielen, wenn wir fortfahren.

 gsap.fromto ('. box', {
  Xpercent: 100
}, {
  Xpercent: -200,
  Staffelung: 0,5,
  Dauer: 1,
  Wiederholen: -1,
  Leichtigkeit: 'keine',
})
Nach dem Login kopieren

Jetzt kommt der lustige Teil. Lassen Sie uns das Tween pausieren und es einer Variablen zuweisen. Dann erstellen wir ein Tween, das es spielt. Wir können dies tun, indem wir die Gesamtzeit des Tween veröffentlichen, was es uns ermöglicht, die Playhead -Tween des Tweens zu erhalten oder zu setzen, während wir Wiederholungen und Wiederholungsverzögerungen in Betracht ziehen.

 const revers = gsap.fromto ('. box', {
  Xpercent: 100
}, {
  pausiert: wahr,
  Xpercent: -200,
  Staffelung: 0,5,
  Dauer: 1,
  Wiederholen: -1,
  Leichtigkeit: 'keine',
})

const duration = Shift.duration ()

gsap.to (Shift, {
  Gesamtzeit: Dauer,
  Wiederholen: -1,
  Dauer: Dauer,
  Leichtigkeit: 'keine',
})
Nach dem Login kopieren

Dies ist unser erster "Meta" Tween. Es sieht genauso aus, aber wir fügen ein weiteres Maß an Kontrolle hinzu. Wir können die Dinge auf dieser Ebene ändern, ohne die ursprüngliche Ebene zu beeinflussen. Zum Beispiel könnten wir die Tween -Leichtigkeit in Power4 ändern. Dies ändert die Animation vollständig, ohne die zugrunde liegende Animation zu beeinflussen. Wir schützen uns irgendwie mit einem Fallback.

Nicht nur das, wir könnten uns entscheiden, nur einen bestimmten Teil der Zeitleiste zu wiederholen. Wir könnten das mit einem anderen von so machen, wie folgt:

Der Code dafür wäre so etwas.

 gsap.fromto (Shift, {
  Gesamtzeit: 2,
}, {
  Gesamtzeit: Dauer - 1,
  Wiederholen: -1,
  Dauer: Dauer,
  Leichtigkeit: 'Keine'
})
Nach dem Login kopieren

Sehen Sie, wohin das geht? Beobachten Sie das Tween. Obwohl es weiter schlauft, flippen die Zahlen bei jeder Wiederholung. Die Kästchen sind jedoch in der richtigen Position.

Erreichen der „perfekten“ Schleife

Wenn wir zu unserem ursprünglichen Beispiel zurückkehren, besteht zwischen jeder Wiederholung eine spürbare Lücke.

Hier kommt der Trick. Der Teil, der alles freischaltet. Wir müssen eine perfekte Schleife bauen.

Beginnen wir damit, die Verschiebung dreimal zu wiederholen. Es entspricht der Verwendung von Wiederholung: 3. Beachten Sie, wie wir Wiederholung entfernt haben: -1 aus dem Tween.

 const getShift = () => gsap.fromto ('. Box', {
  Xpercent: 100
}, {
  Xpercent: -200,
  Staffelung: 0,5,
  Dauer: 1,
  Leichtigkeit: 'keine',
})

const Loop = gsap.timeline ()
  .add (getShift ())
  .add (getShift ())
  .add (getShift ())
Nach dem Login kopieren

Wir haben die anfängliche Tween in eine Funktion gemacht, die das Tween zurückgibt, und wir fügen sie dreimal zu einer neuen Zeitleiste hinzu. Und das gibt uns Folgendes.

OK. Aber es gibt immer noch eine Lücke. Jetzt können wir den Positionsparameter zum Hinzufügen und Positionieren dieser Tweens einbringen. Wir wollen, dass es nahtlos ist. Das bedeutet, dass jede Reihe von Tweens vor dem vorherigen endet. Das ist ein Wert, der auf der Staffelung und der Anzahl der Elemente basiert.

 const bagger = 0,5 // verwendet in unserem sich wechselnden tween
const Boxes = gsap.utils.toarray ('. Box')
const Loop = gsap.timeline ({{
  Wiederholen: -1
})
  .add (getShift (), 0)
  .Add (getShift (), Boxen.Length * Stagger)
  .Add (getShift (), Boxen.Length * Stagger * 2)
Nach dem Login kopieren

Wenn wir unsere Zeitleiste aktualisieren, um sie zu wiederholen und zu sehen (während wir die Staffelung anpassen, um zu sehen, wie es sich auf die Dinge auswirkt)…

Sie werden feststellen, dass es in der Mitte ein Fenster gibt, das eine „nahtlose“ Schleife erzeugt. Erinnern Sie sich an diese Fähigkeiten von früher, wo wir Zeit manipuliert haben? Das müssen wir hier tun: Schleifen Sie das Zeitfenster, in dem die Schleife „nahtlos“ ist.

Wir konnten versuchen, die Gesamtzeit durch dieses Fenster der Schleife zu tweenten.

 const Loop = gsap.timeline ({{
  pausiert: wahr,
  Wiederholen: -1,
})
.add (getShift (), 0)
.Add (getShift (), Boxen.Length * Stagger)
.Add (getShift (), Boxen.Length * Stagger * 2)

gsap.fromto (Schleife, {
  Gesamtzeit: 4,75,
},
{
  TotalTime: '= 5',
  Dauer: 10,
  Leichtigkeit: 'keine',
  Wiederholen: -1,
})
Nach dem Login kopieren

Hier sagen wir, dass die Gesamtzeit von 4,75 und die Länge eines Zyklus hinzugefügt werden. Die Länge eines Zyklus beträgt 5. Und das ist das mittlere Fenster der Zeitleiste. Wir können GSAP's Nifty = das tun, um das zu tun, was uns Folgendes gibt:

Nehmen Sie sich einen Moment Zeit, um zu verdauen, was dort passiert. Dies könnte der schwierigste Teil sein, um Ihren Kopf herumzuwickeln. Wir berechnen Zeitfenster der Zeit in unserer Zeitleiste. Es ist irgendwie schwer zu visualisieren, aber ich habe es versucht.

Dies ist eine Demo einer Uhr, die 12 Sekunden dauert, bis die Hände einmal herumgehen. Es ist unendlich mit Wiederholung geschlungen: -1 und dann verwenden wir ein bestimmtes Zeitfenster mit einer bestimmten Dauer. Wenn Sie das Zeitfenster reduzieren, um 2 und 6 zu sagen, ändern Sie die Dauer auf 1, die Hände werden bei Wiederholung von 2 Uhr auf 6 Uhr. Aber wir haben die zugrunde liegende Animation nie geändert.

Konfigurieren Sie die Werte, um zu sehen, wie sich dies auswirkt.

An diesem Punkt ist es eine gute Idee, eine Formel für unsere Fensterposition zusammenzustellen. Wir könnten auch eine Variable für die Dauer verwenden, die für jede Box zum Übergang erforderlich ist.

 const dauer = 1
const cycle_duration = Boxen.Length * Stagger
const start_time = cycle_duration (Dauer * 0,5)
const end_time = start_time cycle_duration
Nach dem Login kopieren

Anstatt drei gestapelte Zeitpläne zu verwenden, konnten wir dreimal über unsere Elemente schauen, wo wir den Vorteil haben, dass wir die Positionen nicht berechnen müssen. Das Visualisieren dieser drei gestapelten Zeitpläne ist jedoch eine gute Möglichkeit, das Konzept zu grokieren, und eine gute Möglichkeit, die Hauptidee zu verstehen.

Ändern wir unsere Implementierung, um von Anfang an eine große Zeitleiste zu erstellen.

 const bagger = 0,5
const Boxes = gsap.utils.toarray ('. Box')

const Loop = gsap.timeline ({{
  pausiert: wahr,
  Wiederholen: -1,
})

const verschiebe = [... Kästchen, ... Kästchen, ... Boxen]

Shifts.foreach ((Box, Index) => {
  Loop.fromto (Box, {
    Xpercent: 100
  }, {
    Xpercent: -200,
    Dauer: 1,
    Leichtigkeit: 'keine',
  }, Index * Stagger)
})
Nach dem Login kopieren

Dies ist einfacher zusammenzustellen und gibt uns das gleiche Fenster. Aber wir müssen nicht über Mathematik nachdenken. Jetzt schalten wir drei Sätze der Boxen durch und positionieren jede Animation gemäß der Staffelung.

Wie könnte das aussehen, wenn wir die Staffelung anpassen? Es wird die Kisten näher zusammenquetschen.

Aber es ist das Fenster gebrochen, weil jetzt die Gesamtzeit nicht mehr ausfällt. Wir müssen das Fenster neu berechnen. Jetzt ist ein guter Zeitpunkt, um die zuvor berechnete Formel einzuschließen.

 const dauer = 1
const cycle_duration = Stagger * Boxen.Length
const start_time = cycle_duration (Dauer * 0,5)
const end_time = start_time cycle_duration

gsap.fromto (Schleife, {
  TotalTime: start_time,
},
{
  TotalTime: end_time,
  Dauer: 10,
  Leichtigkeit: 'keine',
  Wiederholen: -1,
})
Nach dem Login kopieren

Behoben!

Wir könnten sogar einen „Offset“ einführen, wenn wir die Startposition ändern wollten.

 const bagger = 0,5
const offset = 5 * Staffelung
const start_time = (cycle_duration (Stagger * 0,5)) Offset
Nach dem Login kopieren

Jetzt beginnt unser Fenster in einer anderen Position.

Trotzdem ist das nicht großartig, da es uns an jedem Ende diese unangenehmen Stapel gibt. Um diesen Effekt loszuwerden, müssen wir über ein „physisches“ Fenster für unsere Boxen nachdenken. Oder denken Sie darüber nach, wie sie die Szene betreten und verlassen.

Wir werden Dokument für unser Beispiel als Fenster verwenden. Aktualisieren wir die Box Tweens, um individuelle Zeitpläne zu sein, bei denen die Kästchen beim Eingabeglieren und unten beim Ausgang skalieren. Wir können Yoyo und wiederholen: 1, um einzugeben und zu beenden.

 Shifts.foreach ((Box, Index) => {
  const box_tl = gsap
    .Timeline ()
    .Fromto (
      KASTEN,
      {
        Xpercent: 100,,
      },
      {
        Xpercent: -200,
        Dauer: 1,
        Leichtigkeit: 'keine',
      }, 0
    )
    .Fromto (
      KASTEN,
      {
        Skala: 0,
      },
      {
        Skala: 1,
        Wiederholen: 1,,
        Yoyo: wahr,
        Leichtigkeit: 'keine',
        Dauer: 0,5,
      },
      0
    )
  Loop.Add (box_tl, Index * Stagger)
})
Nach dem Login kopieren

Warum verwenden wir eine Zeitleistedauer von 1? Es erleichtert die Befolgung der Dinge. Wir wissen, dass die Zeit 0,5 beträgt, wenn sich die Box im Mittelpunkt befindet. Es ist erwähnenswert, dass die Lockerung nicht den Effekt haben wird, an den wir normalerweise hier denken. In der Tat wird die Lockerung tatsächlich eine Rolle dazu spielen, wie sich die Boxen positionieren. Zum Beispiel würde ein Leichtigkeit die Boxen rechts einbinden, bevor sie sich bewegen.

Der obige Code gibt uns dies.

Fast. Aber unsere Kisten verschwinden eine Zeit lang in der Mitte. Um dies zu beheben, führen wir das unmittelbare Eigentum vor. Es wirkt wie Animations-Fill-Mode: Keine in CSS. Wir sagen GSAP, dass wir keine Stile, die auf einer Box festgelegt werden, behalten oder vorab.

 Shifts.foreach ((Box, Index) => {
  const box_tl = gsap
    .Timeline ()
    .Fromto (
      KASTEN,
      {
        Xpercent: 100,,
      },
      {
        Xpercent: -200,
        Dauer: 1,
        Leichtigkeit: 'keine',
        unmittelbarer: falsch,
      }, 0
    )
    .Fromto (
      KASTEN,
      {
        Skala: 0,
      },
      {
        Skala: 1,
        Wiederholen: 1,,
        Zindex: Boxen.Length 1,,
        Yoyo: wahr,
        Leichtigkeit: 'keine',
        Dauer: 0,5,
        unmittelbarer: falsch,
      },
      0
    )
  Loop.Add (box_tl, Index * Stagger)
})
Nach dem Login kopieren

Diese kleine Veränderung repariert Dinge für uns! Beachten Sie, wie wir auch Z-Index: Boxes.Length enthalten haben. Das sollte uns gegen Z-Index-Probleme schützen.

Dort haben wir es! Unsere erste unendliche nahtlose Schleife. Keine doppelten Elemente und perfekte Fortsetzung. Wir biegen Zeit! Klopfen Sie sich auf den Rücken, wenn Sie so weit gekommen sind! ?

Wenn wir mehr Kisten gleichzeitig sehen möchten, können wir an Timing, Staffelung und Leichtigkeit basteln. Hier haben wir eine Staffel von 0,2 und haben auch die Opazität in den Mix eingeführt.

Der wichtigste Teil hier ist, dass wir Repeatdelay verwenden können, damit der Übergang der Opazität schneller ist als die Skala. Verblassen Sie in über 0,25 Sekunden. Warten Sie 0,5 Sekunden. Über 0,25 Sekunden zurückblicken.

 .Fromto (
  KASTEN, {
    Deckkraft: 0,
  }, {
    Deckkraft: 1,
    Dauer: 0,25,
    Wiederholen: 1,,
    RepeatDelay: 0,5,
    unmittelbarer: falsch,
    Leichtigkeit: 'keine',
    Yoyo: wahr,
  }, 0)
Nach dem Login kopieren

Cool! Wir konnten mit denen in und aus Übergängen tun, was wir wollen. Die Hauptsache hier ist, dass wir unser Zeitfenster haben, das uns die unendliche Schleife gibt.

Haken Sie dies auf, um zu scrollen

Jetzt, da wir eine nahtlose Schleife haben, befestigen wir sie an Scrollen. Dazu können wir den Scrolltrigger von GSAP verwenden. Dies erfordert ein zusätzliches Tween, um unser Schleifenfenster zu schrubben. Beachten Sie, wie wir die Schleife auch so eingestellt haben, dass sie jetzt innehalten werden.

 const Loop_head = gsap.fromto (Loop, {
  TotalTime: start_time,
},
{
  TotalTime: end_time,
  Dauer: 10,
  Leichtigkeit: 'keine',
  Wiederholen: -1,
  pausiert: wahr,
})

const scrub = gsap.to (Loop_head, {
  Gesamtzeit: 0,
  pausiert: wahr,
  Dauer: 1,
  Leichtigkeit: 'keine',
})
Nach dem Login kopieren

Der Trick hier besteht darin, Scrolltrigger zu verwenden, um den Spielkopf der Schleife zu schrubben, indem die Gesamtzeit von Peeling aktualisiert wird. Es gibt verschiedene Möglichkeiten, wie wir diese Schriftrolle einrichten könnten. Wir könnten es horizontal oder an einen Behälter gebunden haben. Aber wir werden unsere Boxen in ein .boxes -Element einwickeln und das an das Ansichtsfenster anpassen. (Dies behebt seine Position im Ansichtsfenster.) Wir bleiben auch bei vertikalem Scrollen. Überprüfen Sie die Demo, um das Styling für .boxen zu sehen, die die Dinge auf die Größe des Ansichtsfensters festlegen.

 Importieren Sie Scrolltrigger aus 'https://cdn.skypack.dev/gsap/scrolltrigger'
gsap.registerplugin (Scrolltrigger)

Scrolltrigger.create ({{
  Start: 0,
  Ende: '= 2000',
  horizontal: falsch,
  Pin: '.boxen',
  Onupdate: self => {
    Scrub.vars.totaltime = loop_head.duration () * self.progress
    Scrub.invalidate (). Restart ())
  }
})
Nach dem Login kopieren

Der wichtige Teil ist im In -Update. Hier setzen wir die Gesamtzeit des Tween basierend auf dem Scroll -Fortschritt. Der ungültig erklärt Call wird alle intern aufgezeichneten Positionen für das Peeling spülen. Der Neustart setzt dann die Position auf die neue Gesamtzeit, die wir festgelegt haben.

Probieren Sie es aus! Wir können in der Zeitleiste hin und her gehen und die Position aktualisieren.

Wie cool ist das? Wir können eine Zeitleiste schrubben, die eine Zeitleiste schrubbt, die ein Fenster einer Zeitleiste ist. Verdaue das für eine Sekunde, weil das hier passiert.

Zeitreisen für unendliche Scrollen

Bisher haben wir Zeit manipuliert. Jetzt gehen wir zur Zeitreisen!

Dazu verwenden wir einige andere GSAP -Dienstprogramme und werden die Gesamtzeit von Loop_head nicht mehr schrubben. Stattdessen werden wir es über Proxy aktualisieren. Dies ist ein weiteres großartiges Beispiel für das „Meta“ -Meta -GSAP.

Beginnen wir mit einem Proxy -Objekt, das die Playhead -Position markiert.

 const playhead = {Position: 0}
Nach dem Login kopieren

Jetzt können wir unser Peeling aktualisieren, um die Position zu aktualisieren. Gleichzeitig können wir das Wrap -Dienstprogramm von GSAP verwenden, wodurch der Positionswert um die Dauer der Loop_head umschließt. Wenn die Dauer beispielsweise 10 beträgt und wir den Wert 11 angeben, erhalten wir zurück 1.

 const position_wrap = gsap.utils.wrap (0, Loop_head.duration ())

const scrub = gsap.to (playhead, {
  Position: 0,
  Onupdate: () => {
    Loop_head.TotAltime (Position_Wrap (Playhead.Position))
  },
  pausiert: wahr,
  Dauer: 1,
  Leichtigkeit: 'keine',
})
Nach dem Login kopieren

Zu guter Letzt müssen wir Scrolltrigger überarbeiten, damit die richtige Variable auf dem Peeling aktualisiert wird. Das ist Position anstelle von totaler Zeit.

 Scrolltrigger.create ({{
  Start: 0,
  Ende: '= 2000',
  horizontal: falsch,
  Pin: '.boxen',
  Onupdate: self => {
    Scrub.vars.position = Loop_head.duration () * self.Progress
    Scrub.invalidate (). Restart ())
  }
})
Nach dem Login kopieren

Zu diesem Zeitpunkt haben wir zu einem Proxy gewechselt und werden keine Änderungen sehen.

Wir wollen eine unendliche Schleife, wenn wir scrollen. Unser erster Gedanke könnte es sein, zum Start zu scrollen, wenn wir den Fortschritt des Scrolls beenden. Und genau das würde genau das tun, zurück -zurück. Obwohl wir das tun wollen, wollen wir nicht, dass der Playhead rückwärts schrubbt. Hier kommt TotalTime ins Spiel. Erinnerst du dich? Es erhält oder legt die Position des Playheads gemäß der Gesamtdauer, die Wiederholungen und Wiederholungsverzögerungen enthält .

Zum Beispiel, sagen wir, die Dauer des Schleifenkopfes betrug 5 und wir kamen dort an, wir werden nicht auf 0 zurückgeschrubbt. Stattdessen werden wir den Schleifenkopf auf 10 weiter schrubben. Wenn wir weitermachen, wird es auf 15 und so weiter dauern. In der Zwischenzeit werden wir eine Iterationsvariable im Auge behalten, da uns das sagt, wo wir uns im Peeling befinden. Wir werden auch sicherstellen, dass wir nur die Iteration aktualisieren, wenn wir die Fortschrittsschwellenwerte treffen.

Beginnen wir mit einer Iterationsvariablen:

 lass es Iteration = 0
Nach dem Login kopieren

Lassen Sie uns nun unsere Scrolltrigger -Implementierung aktualisieren:

 const trigger = scrolltrigger.create ({{
  Start: 0,
  Ende: '= 2000',
  horizontal: falsch,
  Pin: '.boxen',
  Onupdate: self => {
    const scroll = self.scroll ()
    if (scrollen> self.end - 1) {
      // rechtzeitig vorwärts gehen
      Wrap (1, 1)
    } else if (scrollen <p>Beachten Sie, wie wir die Iteration jetzt in die Positionsberechnung berücksichtigen. Denken Sie daran, dass dies mit dem Schrubber eingewickelt wird. Wir erkennen auch, wenn wir die Grenzen unserer Schriftrolle erreichen, und das ist der Punkt, an dem wir einwickeln. Diese Funktion legt den entsprechenden Iterationswert fest und legt die neue Bildlaufposition fest.</p><pre rel="JavaScript" data-line=""> const Wrap = (itererationDelta, scrollto) => {
  Iteration = IterationDelta
  Trigger.Scroll (Scrollto)
  Trigger.Update ()
}
Nach dem Login kopieren

Wir haben unendlich Scrollen! Wenn Sie eine dieser schicken Mäuse mit dem Bildlaufrad haben, das Sie loslassen können, probieren Sie es aus! Es macht Spaß!

Hier ist eine Demo, die die aktuelle Iteration und den Fortschritt zeigt:

Scrollenschnappen

Wir sind da. Aber es gibt immer "nett zu haves", wenn sie an einer solchen Funktion arbeiten. Beginnen wir mit dem Scroll -Schnappen. GSAP macht dies einfach, da wir gsap.utils.snap ohne andere Abhängigkeiten verwenden können. Das schnappt sich zu einer Zeit, in der wir die Punkte angeben. Wir deklarieren den Schritt zwischen 0 und 1 und haben 10 Boxen in unserem Beispiel. Das bedeutet, dass ein Schnappschuss von 0,1 für uns funktionieren würde.

 const snap = gsap.utils.snap (1 / Boxen.Length)
Nach dem Login kopieren

Und das gibt eine Funktion zurück, mit der wir unseren Positionswert erreichen können.

Wir wollen nur dann schnappen, sobald die Schriftrolle beendet ist. Dafür können wir einen Event -Listener auf Scrolltrigger verwenden. Wenn die Bildlauf endet, werden wir zu einer bestimmten Position scrollen.

 Scrolltrigger.addeventListener ('scrollend', () => {
  Scrolltoposition (Scrub.vars.Position)
})
Nach dem Login kopieren

Und hier ist Scrolltoposition:

 const scrolltoposition = Position => {
  const snap_pos = snap (Position)
  const progress =
    (Snap_Pos - Loop_head.duration () * Iteration) / Loop_head.duration ()
  const scroll = progreshtoscroll (Fortschritt)
  Trigger.Scroll (Scrollen)
}
Nach dem Login kopieren

Was machen wir hier?

  1. Berechnung des Zeitpunkts zum Einschalten nach
  2. Berechnung des aktuellen Fortschritts. Nehmen wir an, der Loop_head.duration () ist 1 und wir haben auf 2.5 geschnappt. Das gibt uns einen Fortschritt von 0,5, was zu einer Iteration von 2 führt, wobei 2,5 - 1 * 2 /1 === 0,5. Wir berechnen den Fortschritt so, dass es immer zwischen 1 und 0 liegt.
  3. Berechnung des Bildlaufziels. Dies ist ein Bruchteil der Entfernung, die unser Scrolltrigger abdecken kann. In unserem Beispiel haben wir einen Abstand von 2000 festgelegt und wollen einen Bruchteil davon. Wir erstellen eine neue Funktion ProgressToscroll, um sie zu berechnen.
 const progreshtoscroll = progress =>
  gsap.utils.clamp (1, Trigger.end - 1, gsap.utils.wrap (0, 1, Fortschritt) * Trigger.end)
Nach dem Login kopieren

Diese Funktion nimmt den Fortschrittswert und ordnet ihn auf die größte Scroll -Distanz ab. Wir verwenden jedoch eine Klemme, um sicherzustellen, dass der Wert niemals 0 oder 2000 sein kann. Dies ist wichtig. Wir schützen uns vor dem Schnappen auf diese Werte, wie es uns in eine unendliche Schleife versetzen würde.

Dort gibt es ein bisschen zu sehen. Schauen Sie sich diese Demo an, die die aktualisierten Werte für jeden Snap anzeigt.

Warum sind die Dinge viel knapper? Die Schrubbendauer und Leichtigkeit wurden verändert. Eine geringere Dauer und eine druckigere Leichtigkeit verleihen uns den Schnappschuss.

 const scrub = gsap.to (playhead, {
  Position: 0,
  Onupdate: () => {
    Loop_head.TotAltime (Position_Wrap (Playhead.Position))
  },
  pausiert: wahr,
  Dauer: 0,25,
  Leichtigkeit: 'Power3',
})
Nach dem Login kopieren

Wenn Sie jedoch mit dieser Demo gespielt haben, werden Sie feststellen, dass es ein Problem gibt. Manchmal springt der Playhead, wenn wir uns im Snap wickeln, herum. Wir müssen dies berücksichtigen, indem wir sicherstellen, dass wir beim Schnappen einwickeln - aber nur, wenn es notwendig ist.

 const scrolltoposition = Position => {
  const snap_pos = snap (Position)
  const progress =
    (Snap_Pos - Loop_head.duration () * Iteration) / Loop_head.duration ()
  const scroll = progreshtoscroll (Fortschritt)
  if (progresh> = 1 || progress <p> Und jetzt haben wir unendlich scrollen mit Schnappern!</p><h3> Was als nächstes?</h3><p> Wir haben die Grundlagen für einen soliden unendlichen Scroller abgeschlossen. Wir können das nutzen, um Dinge wie Steuerelemente oder Tastaturfunktionen hinzuzufügen. Dies könnte beispielsweise eine Möglichkeit sein, "Weiter" und "vorherige" Tasten und Tastatursteuerungen anzuschließen. Alles, was wir tun müssen, ist die Zeit zu manipulieren, oder?</p><pre rel="JavaScript" data-line=""> const next = () => scrulToposition (Scrub.vars.Position - (1 / Boxen.Length)))
const prev = () => scrulToposition (Scrub.vars.Position (1 / Boxen.Length)))

// linker und rechter Pfeil plus A und D.
document.addeventListener ('keydown', event => {
  if (Event.KeyCode === 37 || event.KeyCode === 65) Weiter ())
  if (Event.KeyCode === 39 || Ereignis.KeyCode === 68) prev ()
})

Document.querySelector ('. Next'). AddEventListener ('Click', Nächstes)
Document.querySelector ('. Prev'). AddEventListener ('Click', Prev)
Nach dem Login kopieren

Das könnte uns so etwas geben.

Wir können unsere Scrolltoposition -Funktion nutzen und den Wert so steigern, wie wir es brauchen.

Das war's!

Das sehen? GSAP kann mehr als Elemente animieren! Hier haben wir Zeit gebogen und manipuliert, um einen fast perfekten unendlichen Schieberegler zu schaffen. Keine doppelten Elemente, kein Durcheinander und keine gute Flexibilität.

Lassen Sie uns das zusammenfassen, was wir behandelt haben:

  • Wir können eine Animation animieren. ?
  • Wir können das Timing als Positionierungswerkzeuge betrachten, wenn wir die Zeit manipulieren.
  • So verwenden Sie Scrolltrigger, um eine Animation über Proxy zu schrubben.
  • So verwenden Sie einige der großartigen Dienstprogramme von GSAP, um für uns Logik zu bewältigen.

Sie können jetzt die Zeit manipulieren! ?

Dieses Konzept, "Meta" -GSAP zu gehen, eröffnet eine Vielzahl von Möglichkeiten. Was könnten Sie sonst noch animieren? Audio? Video? Was die Demo "Cover Flow" betrifft, so ging das hier!

Das obige ist der detaillierte Inhalt vonGehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage