目次
何でもアニメーション化します
「メタ」に行く
「完璧な」ループを達成します
スクロールにこれを引っ掛けます
無限のスクロールのためのタイムトラベル
スナップをスクロールします
次は何ですか?
それでおしまい!
ホームページ ウェブフロントエンド CSSチュートリアル 「Meta GSAP」に行く:「完璧な」無限のスクロールの探求

「Meta GSAP」に行く:「完璧な」無限のスクロールの探求

Mar 25, 2025 am 10:23 AM

「Meta GSAP」に行く:「完璧な」無限のスクロールの探求

これがどうやって来たのかわかりません。しかし、それは物語です。この記事では、コンセプトを驚かせることについての詳細です。これは、アニメーションについて別の方法で考えるのに役立つでしょう。この特定の例は、無限のスクロール、特にそれらのいずれかを複製することなく、カードのデッキ用の「完璧な」無限のスクロールを備えていることがあります。

なぜ私はここにいるのですか?まあ、これはすべてツイートから始まりました。レイアウトとサイドスクロールコンテンツについて考えさせられたツイート。

私はそのコンセプトを取り、私のサイトでそれを使用しました。そして、それはまだ執筆時点で動作しています。

それから私はギャラリーの景色とサイドスクロールの概念についてもっと考えるようになりました。私たちはライブストリームに飛び乗り、古いリンゴの「カバーフロー」パターンのようなものを作ろうとすることにしました。覚えていますか?

これを作ることについての私の最初の考えは、これを作るので、上記のデモのように、「プログレッシブエンハンスメント」を使用する方法でJavaScriptなしで機能します。私はグリーンソックとスクロールトリガーをつかみました、そして私たちは行きました。私はその仕事からかなり失望しました。私は何かを持っていましたが、無限のスクロールを得ることができませんでした。 「次」と「前」のボタンはボールをプレーしたくありませんでした。ここで見ることができ、水平スクロールが必要です。

そこで、Greensockフォーラムに新しいスレッドを開きました。私は真剣な学習に自分自身を開放しようとしていたことをほとんど知りませんでした!ボタンで問題を解決しました。しかし、私であるため、私は何か他のものが可能かどうか尋ねなければなりませんでした。無限のスクロールを行う「きれいな」方法はありましたか?ストリームで何かを試しましたが、運はありませんでした。私は興味がありました。 Scrolltriggerリリース用に作成したこのペンで使用されたようなテクニックを試しました。

最初の答えは、やるのはちょっと難しいということでした:

スクロール上の無限のことについての難しい部分は、スクロールバーが制限されている一方で、あなたが望んでいる効果はそうではないことです。したがって、実際に実際のスクロール位置を使用する代わりに、このデモ(Scrolltigger Demosセクションにある)のようなスクロール位置をループするか、スクロール関連のナビゲーションイベント(ホイールイベントなど)に直接フックする必要があります。

私はそれが事実であると考え、それを「As-and」に残して喜んでいた。数日が経過し、ジャックは私がそれを掘り始めたときに私の心を吹き飛ばした返事を落としました。そして今、それを経験した後、私はあなたとテクニックを共有するためにここにいます。

何でもアニメーション化します

GSAPで見落とされることが多いことの1つは、ほとんど何でもアニメーション化できることです。これは、アニメーション、つまり何かの実際の物理的な動きについて考えるとき、視覚的なものが思い浮かぶものだからです。私たちの最初の考えは、そのプロセスをメタレベルに引き継いで、一歩後退からアニメーション化することではありません。

ただし、アニメーションが大規模に機能することを考えてから、レイヤーに分解します。たとえば、漫画を演奏します。漫画は作曲のコレクションです。各構成はシーンです。そして、YouTube上にあるかどうか、テレビのリモコンなどを使用するかどうかにかかわらず、リモコンを使用して、その構成のコレクションをスクラブする力があります。何が起こっているかにはほぼ3つのレベルがあります。

これは、さまざまな種類の無限ループを作成するために必要なトリックです。これがここでの主な概念です。タイムラインでタイムラインのプレイヘッド位置をアニメーション化します。そして、スクロール位置でそのタイムラインをスクラブすることができます。

それが混乱しているように聞こえても心配しないでください。私たちはそれを分解するつもりです。

「メタ」に行く

例から始めましょう。いくつかのボックスを左から右に移動するTweenを作成します。ここにあります。

左から右に進み続ける10個のボックス。 Greensockでは非常に簡単です。ここでは、アニメーションを維持するために繰り返して繰り返します。しかし、各反復の開始時にギャップがあります。また、Staggerを使用してムーブメントを展示しています。これは、私たちが続行するにつれて重要な役割を果たすものです。

 gsap.fromto('。box '、{
  Xpercent:100
}、{
  Xpercent:-200、
  よろめ:0.5、
  期間:1、
  繰り返し:-1、
  使いやすさ:「なし」、
})
ログイン後にコピー

今、楽しい部分が来ます。トゥイーンを一時停止し、変数に割り当てましょう。次に、それを再生するトゥイーンを作成しましょう。これを行うことができます。これにより、Tweenの合計時間をTweenで行うことができます。これにより、TweenのPlayhead Tweenを取得または設定することができます。

 const shift = gsap.fromto('。box '、{
  Xpercent:100
}、{
  一時停止:本当、
  Xpercent:-200、
  よろめ:0.5、
  期間:1、
  繰り返し:-1、
  使いやすさ:「なし」、
})

const duration = shift.duration()

gsap.to(shift、{
  合計時間:期間、
  繰り返し:-1、
  期間:期間、
  使いやすさ:「なし」、
})
ログイン後にコピー

これは私たちの最初の「メタ」トゥイーンです。まったく同じように見えますが、別のレベルのコントロールを追加しています。元のレイヤーに影響を与えることなく、このレイヤーの物事を変更できます。たとえば、Tweenの容易さをPower4.inに変更できます。これにより、アニメーションが完全に変わりますが、基礎となるアニメーションに影響することはありません。私たちはフォールバックで自分自身を保護しています。

それだけでなく、タイムラインの特定の部分のみを繰り返すことを選択する場合があります。このように、他の人と一緒にそれを行うことができました:

そのためのコードはこのようなものです。

 gsap.fromto(shift、{
  合計時間:2、
}、{
  合計時間:期間-1、
  繰り返し:-1、
  期間:期間、
  使いやすさ:「なし」
})
ログイン後にコピー

これがどこに向かっているのかわかりますか?そのトゥイーンを見てください。ループを続けていますが、数字は各繰り返しをひっくり返します。しかし、ボックスは正しい位置にあります。

「完璧な」ループを達成します

元の例に戻ると、各繰り返しの間に顕著なギャップがあります。

ここにトリックがあります。すべてを解き放つ部分。完璧なループを構築する必要があります。

シフトを3回繰り返すことから始めましょう。繰り返しを使用することに等しい:3。Tweenから繰り返し:-1を削除した方法に注意してください。

 const getshift =()=> gsap.fromto('。box '、{
  Xpercent:100
}、{
  Xpercent:-200、
  よろめ:0.5、
  期間:1、
  使いやすさ:「なし」、
})

const loop = gsap.timeline()
  .add(getshift())
  .add(getshift())
  .add(getshift())
ログイン後にコピー

最初のTweenをTweenを返す関数に変え、3回新しいタイムラインに追加しました。そして、これは私たちに以下を与えます。

わかりました。しかし、まだギャップがあります。これで、これらのトゥイーンを追加および配置するための位置パラメーターを持ち込むことができます。シームレスにしたい。それは、前のものが終了する前に各セットの各セットを挿入することを意味します。これは、ずらして要素の量に基づいた値です。

 const stagger = 0.5 //シフトのトゥイーンで使用されています
const boxes = gsap.utils.toarray('。box ')
const loop = gsap.timeline({
  繰り返し:-1
})
  .add(getshift()、0)
  .add(getshift()、boxes.length * stagger)
  .add(getshift()、boxes.length * stagger * 2)
ログイン後にコピー

タイムラインを更新して繰り返して視聴すると(それが物事にどのように影響するかを確認するためによろめきを調整しながら)…

真ん中に「シームレスな」ループを作成する窓があることに気付くでしょう。私たちが時間を操作した以前のスキルを思い出しますか?それがここで行う必要があることです。ループが「シームレス」である時間のウィンドウをループします。

ループのそのウィンドウを通して合計時間をトゥーイーンすることを試みることができます。

 const loop = gsap.timeline({
  一時停止:本当、
  繰り返し:-1、
})
.add(getshift()、0)
.add(getshift()、boxes.length * stagger)
.add(getshift()、boxes.length * stagger * 2)

gsap.fromto(loop、{
  合計時間:4.75、
}、
{
  TotalTime: '= 5'、
  期間:10、
  使いやすさ:「なし」、
  繰り返し:-1、
})
ログイン後にコピー

ここでは、合計時間を4.75からTweenと言って、サイクルの長さを追加しています。サイクルの長さは5です。それがタイムラインの中央の窓です。 GSAPのnifty =を使用してそれを行うことができます。

そこで何が起こっているのかを消化してください。これは、頭を包むのが最も難しい部分かもしれません。タイムラインで時間の窓を計算しています。視覚化するのはちょっと難しいですが、私は試しました。

これは、手に12秒かかる時計のデモです。それは繰り返しで無限にループされています:-1そして、私たちは特定の期間で特定の時間ウィンドウをアニメーション化するために使用します。時間ウィンドウを減らして2と6を言うと、持続時間を1に変更すると、手は2時から6時まで繰り返します。しかし、私たちは基礎となるアニメーションを決して変えませんでした。

値を構成して、それが物事にどのように影響するかを確認してください。

この時点で、ウィンドウの位置の式をまとめることをお勧めします。また、各ボックスが移行するためにかかる期間に変数を使用することもできます。

 const持続時間= 1
const Cycle_duration = boxes.length * stagger
const start_time = cycle_duration(duration * 0.5)
const end_time = start_time cycle_duration
ログイン後にコピー

3つの積み重ねられたタイムラインを使用する代わりに、位置を計算する必要がないという利点を得るために3回の要素をループすることができます。しかし、これを3つの積み重ねられたタイムラインとして視覚化することは、コンセプトを把握するためのきちんとした方法であり、主なアイデアを理解するのに役立つ良い方法です。

実装を変更して、最初から1つの大きなタイムラインを作成しましょう。

 const stagger = 0.5
const boxes = gsap.utils.toarray('。box ')

const loop = gsap.timeline({
  一時停止:本当、
  繰り返し:-1、
})

const shifts = [... boxes、... boxes、... boxes]

shifts.foreach((box、index)=> {
  loop.fromto(box、{
    Xpercent:100
  }、{
    Xpercent:-200、
    期間:1、
    使いやすさ:「なし」、
  }、index * stagger)
})
ログイン後にコピー

これは簡単にまとめられ、同じウィンドウを提供します。しかし、数学について考える必要はありません。次に、3セットのボックスをループして、スティガーに応じて各アニメーションを配置します。

私たちがよろめきを調整すれば、それはどのように見えますか?箱をより近くに押しつけます。

しかし、今では合計が出ているので、窓が壊れています。ウィンドウを再計算する必要があります。以前に計算した式をプラグインするのに良い時期です。

 const持続時間= 1
const Cycle_duration = stagger * boxes.length
const start_time = cycle_duration(duration * 0.5)
const end_time = start_time cycle_duration

gsap.fromto(loop、{
  TotalTime:start_time、
}、
{
  TotalTime:end_time、
  期間:10、
  使いやすさ:「なし」、
  繰り返し:-1、
})
ログイン後にコピー

修理済み!

開始位置を変更したい場合は、「オフセット」を導入することもできます。

 const stagger = 0.5
const offset = 5 * stagger
const start_time =(cycle_duration(stagger * 0.5))offset
ログイン後にコピー

今、私たちの窓は別の位置から始まります。

それでも、これは両端でこれらの厄介なスタックを提供するので、これは素晴らしいことではありません。その効果を取り除くには、ボックスの「物理的な」ウィンドウについて考える必要があります。または、それらがどのようにシーンを出入りするかを考えてください。

document.bodyを例のウィンドウとして使用します。ボックスのトゥイーンを更新して、ボックスが出口で入力して下降してスケールアップする個々のタイムラインにしましょう。ヨーヨーを使用して繰り返すことができます:1は、入場と出口を達成します。

 shifts.foreach((box、index)=> {
  const box_tl = gsap
    .timeline()
    .fromto(
      箱、
      {
        Xpercent:100、
      }、
      {
        Xpercent:-200、
        期間:1、
        使いやすさ:「なし」、
      }、0
    ))
    .fromto(
      箱、
      {
        スケール:0、
      }、
      {
        スケール:1、
        繰り返し:1、
        ヨーヨ:本当、
        使いやすさ:「なし」、
        期間:0.5、
      }、
      0
    ))
  loop.add(box_tl、index * stagger)
})
ログイン後にコピー

タイムライン期間を1のタイムライン期間を使用しているのはなぜですか?それは物事を追いかけやすくします。ボックスが中点にある時間は0.5であることがわかっています。緩和は私たちがここで普段考える効果がないことに注意する価値があります。実際、緩和は実際にボックスがどのように自分自身を配置するかに関与します。たとえば、簡単に移動する前に、箱を右に束ねます。

上記のコードはこれを与えてくれます。

ほとんど。しかし、私たちの箱は真ん中でしばらく消えます。これを修正するには、即時のプロパティを紹介しましょう。 Animation-Fill-Mode:Noneのように機能します。 GSAPに、ボックスに設定されているスタイルを保持または事前に記録したくないことを伝えています。

 shifts.foreach((box、index)=> {
  const box_tl = gsap
    .timeline()
    .fromto(
      箱、
      {
        Xpercent:100、
      }、
      {
        Xpercent:-200、
        期間:1、
        使いやすさ:「なし」、
        即時者:false、
      }、0
    ))
    .fromto(
      箱、
      {
        スケール:0、
      }、
      {
        スケール:1、
        繰り返し:1、
        Zindex:boxes.length 1、
        ヨーヨ:本当、
        使いやすさ:「なし」、
        期間:0.5、
        即時者:false、
      }、
      0
    ))
  loop.add(box_tl、index * stagger)
})
ログイン後にコピー

その小さな変更は私たちのために物事を修正します! z-index:boxes.lengthも含めた方法に注意してください。これにより、Z-Indexの問題に対して私たちを保護するはずです。

そこに私たちはそれを持っています!私たちの最初の無限のシームレスループ。重複する要素と完全な継続はありません。私たちは時間を曲げています!あなたがここまで来たら、背中を軽くたたいてください! ?

一度により多くの箱を見たい場合は、タイミング、よろめき、簡単にいじくり回すことができます。ここでは、0.2のよろめきで、ミックスに不透明度も導入しました。

ここでの重要な部分は、不透明な遷移がスケールよりも速くなるようにrepeatdelayを利用できることです。 0.25秒以上フェードします。 0.5秒待ちます。 0.25秒以上フェードアウトします。

 .fromto(
  箱、 {
    不透明度:0、
  }、{
    不透明度:1、
    期間:0.25、
    繰り返し:1、
    Repeatdelay:0.5、
    即時者:false、
    使いやすさ:「なし」、
    ヨーヨ:本当、
  }、0)
ログイン後にコピー

いいね!私たちは、それらの内外での移行を使用して、私たちが望むことは何でもできます。ここでの主なことは、無限のループを提供する時間の窓があるということです。

スクロールにこれを引っ掛けます

シームレスなループができたので、スクロールに添付しましょう。このためには、GSAPのScrolltriggerを使用できます。これには、ループウィンドウをスクラブするための余分なトゥイーンが必要です。ループを今一時停止するように設定した方法に注意してください。

 const loop_head = gsap.fromto(loop、{
  TotalTime:start_time、
}、
{
  TotalTime:end_time、
  期間:10、
  使いやすさ:「なし」、
  繰り返し:-1、
  一時停止:本当、
})

const scrub = gsap.to(loop_head、{
  合計時間:0、
  一時停止:本当、
  期間:1、
  使いやすさ:「なし」、
})
ログイン後にコピー

ここでのトリックは、スクラブの合計時間を更新して、スクロールトリガーを使用してループのプレイヘッドをスクラブすることです。このスクロールをセットアップできるさまざまな方法があります。容器に水平または縛られることができます。しかし、私たちがやろうとしていることは、ボックスを.boxes要素に包み、それをビューポートに固定することです。 (これにより、ビューポートでの位置が修正されます。)垂直スクロールにも固執します。デモをチェックして、ビューポートのサイズに物事を設定する.boxesのスタイリングを確認してください。

 'https://cdn.skypack.dev/gsap/scrolltriggerからscrolltriggerをインポート
gsap.registerplugin(scrolltrigger)

scrolltrigger.create({
  開始:0、
  終了: '= 2000'、
  水平:false、
  ピン: '.boxes'、
  onupdate:self => {
    scrub.vars.totaltime = loop_head.duration() * self.progress
    scrub.invalidate()。restart()
  }
})
ログイン後にコピー

重要な部分は、onupdate内です。そこで、スクロールの進行状況に基づいてTweenの合計時間を設定します。無効なコールは、スクラブの内部記録された位置をフラッシュします。再起動は、設定した新しい合計時間に位置を設定します。

試してみてください!タイムラインを行き来して、ポジションを更新できます。

それはどれほどクールですか?スクロールして、タイムラインのウィンドウであるタイムラインをスクラブするタイムラインをスクラブすることができます。それがここで起こっているので、それを一瞬消化します。

無限のスクロールのためのタイムトラベル

これまで、私たちは時間を操作してきました。今、私たちはタイムトラベルに行きます!

これを行うには、他のGSAPユーティリティを使用しますが、loop_headの合計時間をスクラブすることはもうありません。代わりに、プロキシを介して更新します。これは、「メタ」GSAPに移行するもう1つの素晴らしい例です。

Playheadの位置をマークするプロキシオブジェクトから始めましょう。

 const playhead = {position:0}
ログイン後にコピー

これで、スクラブを更新してポジションを更新できます。同時に、GSAPのラップユーティリティを使用して、loop_headの持続時間の周りに位置値をラップします。たとえば、期間が10であり、値11を提供する場合、1を取り戻します。

 const position_wrap = gsap.utils.wrap(0、loop_head.duration())

const scrub = gsap.to(playhead、{
  位置:0、
  onupdate:()=> {
    loop_head.totaltime(position_wrap(playhead.position))
  }、
  一時停止:本当、
  期間:1、
  使いやすさ:「なし」、
})
ログイン後にコピー

最後になりましたが、スクラブ上の正しい変数を更新するように、Scrolltriggerを修正する必要があります。 TotalTimeの代わりに、それが位置です。

 scrolltrigger.create({
  開始:0、
  終了: '= 2000'、
  水平:false、
  ピン: '.boxes'、
  onupdate:self => {
    scrub.vars.position = loop_head.duration() * self.progress
    scrub.invalidate()。restart()
  }
})
ログイン後にコピー

この時点で、プロキシに切り替えましたが、変更は見られません。

スクロールするときは、無限のループが必要です。私たちの最初の考えは、スクロールの進行状況を完了したときにスタートまでスクロールすることかもしれません。そして、それはまさにそれを行い、バックバックします。それは私たちがやりたいことですが、プレイヘッドが後方にスクラブしたくありません。これはTotalTimeが入るところです。覚えていますか?繰り返しや繰り返しの遅延を含む全体の総合に応じて、プレイヘッドの位置を取得または設定します。

たとえば、ループヘッドの持続時間が5で、そこに着いたと言って、私たちは0に戻りません。代わりに、ループヘッドを10にスクラブし続けます。その間、私たちはスクラブのどこにいるかを示すため、反復変数を追跡します。また、進行状況のしきい値に達したときにのみ反復を更新することを確認します。

反復変数から始めましょう:

イテレーション= 0とします
ログイン後にコピー

それでは、Scrolltriggerの実装を更新しましょう。

 const trigger = scrolltrigger.create({
  開始:0、
  終了: '= 2000'、
  水平:false、
  ピン: '.boxes'、
  onupdate:self => {
    const scroll = self.scroll()
    if(scroll> self.end -1){
      //時間内に進みます
      ラップ(1、1)
    } else if(scroll <p>現在、ポジションの計算に反復を考慮していることに注意してください。これはスクラバーで包まれることを忘れないでください。また、巻物の限界に達したときに検出します。それが私たちが包むポイントです。この関数は適切な反復値を設定し、新しいスクロール位置を設定します。</p><pre rel="JavaScript" data-line=""> const wrap =(iterationdelta、scrollto)=> {
  Iteration = IterationDelta
  trigger.scroll(scrollto)
  trigger.update()
}
ログイン後にコピー

無限のスクロールがあります!あなたが解き放つことができるスクロールホイールを備えたそれらの派手なマウスのいずれかを持っているなら、それを試してみてください!楽しい!

現在の反復と進捗を表示するデモは次のとおりです。

スナップをスクロールします

私たちはそこにいます。しかし、このような機能に取り組んでいるとき、常に「持っているのはいい」ことがあります。スクロールスナップから始めましょう。 GSAPは、他の依存関係なしでgsap.utils.snapを使用できるため、これを簡単にします。それは、ポイントを提供する時にスナップを処理します。 0〜1の間のステップを宣言し、例に10個のボックスがあります。つまり、0.1のスナップが私たちのために働くことを意味します。

 const snap = gsap.utils.snap(1 / box.length)
ログイン後にコピー

そして、それは私たちの位置値をスナップするために使用できる関数を返します。

巻物が終了したら、スナップしたいです。そのために、Scrolltriggerでイベントリスナーを使用できます。スクロールが終了すると、特定の位置にスクロールします。

 scrolltrigger.addeventlistener( 'scrollend'、()=> {
  Scrolltoposition(scrub.vars.position)
})
ログイン後にコピー

そして、ここに巻物視があります:

 const scrolltoposition = position => {
  const snap_pos = snap(position)
  Const Progress =
    (snap_pos -loop_head.duration() * iteration) / loop_head.duration()
  const scroll = progressToscroll(Progress)
  trigger.scroll(scroll)
}
ログイン後にコピー

ここで何をしているの?

  1. スナップの時点を計算します
  2. 現在の進捗状況を計算します。 loop_head.duration()が1であり、2.5にスナップしたとしましょう。これにより、0.5の進行が得られ、2が2.5-1 * 2 /1 === 0.5の反復が行われます。常に1〜0の間に進行状況を計算します。
  3. スクロール宛先の計算。これは、スクロールトリガーがカバーできる距離のほんの一部です。この例では、2000年の距離を設定しており、そのほんの一部が必要です。新しい関数ProgressToScrollを作成して計算します。
 const ProgressToScroll = Progress =>
  gsap.utils.clamp(1、trigger.end -1、gsap.utils.wrap(0、1、progress) * trigger.end)
ログイン後にコピー

この関数は、進行状況値を取得し、最大のスクロール距離にマッピングします。ただし、クランプを使用して、値が0または2000になることはないことを確認します。これは重要です。これらの値へのスナップを保護しています。これは、無限のループになります。

そこに少し取り入れる必要があります。各スナップに更新された値を表示するこのデモをご覧ください。

なぜ物事はずっと気味が悪いのですか?スクラブの期間と容易さが変更されました。期間が短く、パンチが容易になり、スナップが得られます。

 const scrub = gsap.to(playhead、{
  位置:0、
  onupdate:()=> {
    loop_head.totaltime(position_wrap(playhead.position))
  }、
  一時停止:本当、
  期間:0.25、
  使いやすさ: 'Power3'、
})
ログイン後にコピー

しかし、そのデモでプレイした場合、問題があることに気付くでしょう。時々、スナップの中で包むと、プレイヘッドが飛び回ります。スナップ時にラップすることを確認することで、それを説明する必要がありますが、それが必要なときだけです。

 const scrolltoposition = position => {
  const snap_pos = snap(position)
  Const Progress =
    (snap_pos -loop_head.duration() * iteration) / loop_head.duration()
  const scroll = progressToscroll(Progress)
  if(Progress> = 1 || Progress <p>そして今、私たちはスナップで無限のスクロールを持っています!</p><h3 id="次は何ですか">次は何ですか?</h3><p>固体の無限精基の基礎を完了しました。それを活用して、コントロールやキーボード機能などのものを追加できます。たとえば、これは「次の」ボタンと「以前の」ボタンとキーボードコントロールを接続する方法かもしれません。私たちがしなければならないのは、時間を操作することだけですよね?</p><pre rel="JavaScript" data-line=""> const next =()=> scrolltoposition(scrub.vars.position-(1 / boxes.length)))
const prev =()=> scrolltoposition(scrub.vars.position(1 / box.length)))

//左および右矢印とaおよびd
document.addeventlistener( 'keydown'、event => {
  if(event.keycode === 37 || event.keycode === 65)next()
  if(event.keycode === 39 || event.keycode === 68)prev()
})

document.QuerySelector('。NEXT ')。ADDEVENTLISTENER(' Click '、next)
document.queryselector( '。prev')。addeventlistener( 'click'、prev)
ログイン後にコピー

それは私たちにこのようなものを与えるかもしれません。

巻物視関数を活用し、必要に応じて値を上げることができます。

それでおしまい!

それを見ますか? GSAPは要素以上のアニメーション化できます!ここでは、ほぼ完璧な無限のスライダーを作成するために時間をかけて操作しました。重複する要素、混乱、柔軟性が良好ではありません。

私たちがカバーしたものを要約しましょう:

  • アニメーションをアニメーション化できます。 ?
  • 時間を操作するときに、タイミングをポジショニングツールとして考えることができます。
  • Scrolltriggerを使用してプロキシを介してアニメーションをスクラブする方法。
  • GSAPの素晴らしいユーティリティのいくつかを使用して、ロジックを処理する方法。

これで時間を操作できます! ?

「メタ」GSAPに進むという概念は、さまざまな可能性を開きます。他に何をアニメーションできますか?オーディオ?ビデオ? 「カバーフロー」デモに関しては、ここにありました!

以上が「Meta GSAP」に行く:「完璧な」無限のスクロールの探求の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Vue 3 Vue 3 Apr 02, 2025 pm 06:32 PM

それは&#039; Vueチームにそれを成し遂げてくれておめでとうございます。それは大規模な努力であり、長い時間がかかったことを知っています。すべての新しいドキュメントも同様です。

ブラウザから有効なCSSプロパティ値を取得できますか? ブラウザから有効なCSSプロパティ値を取得できますか? Apr 02, 2025 pm 06:17 PM

私はこの非常に正当な質問で誰かに書いてもらいました。 Leaは、ブラウザから有効なCSSプロパティ自体を取得する方法についてブログを書いています。それはこのようなものです。

CI/CDで少し CI/CDで少し Apr 02, 2025 pm 06:21 PM

「ウェブサイト」は「モバイルアプリ」よりも適していると言いますが、Max Lynchからのこのフレーミングが好きです。

粘着性のあるポジショニングとサスのダッシュを備えた積み重ねられたカード 粘着性のあるポジショニングとサスのダッシュを備えた積み重ねられたカード Apr 03, 2025 am 10:30 AM

先日、Corey Ginnivanのウェブサイトから、この特に素敵なビットを見つけました。そこでは、スクロール中にカードのコレクションが互いに積み重ねられていました。

WordPressブロックエディターでのマークダウンとローカリゼーションを使用します WordPressブロックエディターでのマークダウンとローカリゼーションを使用します Apr 02, 2025 am 04:27 AM

WordPressエディターでユーザーに直接ドキュメントを表示する必要がある場合、それを行うための最良の方法は何ですか?

レスポンシブデザインのブラウザを比較します レスポンシブデザインのブラウザを比較します Apr 02, 2025 pm 06:25 PM

これらのデスクトップアプリがいくつかあり、目標があなたのサイトをさまざまな次元ですべて同時に表示しています。たとえば、書くことができます

スティッキーヘッダーとフッターにCSSグリッドを使用する方法 スティッキーヘッダーとフッターにCSSグリッドを使用する方法 Apr 02, 2025 pm 06:29 PM

CSS Gridは、レイアウトをこれまで以上に簡単にするように設計されたプロパティのコレクションです。何でもするように、少し学習曲線がありますが、グリッドは

フレックスレイアウト内の紫色のスラッシュ領域が誤って「オーバーフロー空間」と見なされるのはなぜですか? フレックスレイアウト内の紫色のスラッシュ領域が誤って「オーバーフロー空間」と見なされるのはなぜですか? Apr 05, 2025 pm 05:51 PM

フレックスレイアウトの紫色のスラッシュ領域に関する質問フレックスレイアウトを使用すると、開発者ツールなどの混乱する現象に遭遇する可能性があります(D ...

See all articles