Rumah >hujung hadapan web >tutorial css >Pergi 'Meta GSAP': Pencarian untuk Menatal 'Sempurna' Infinite

Pergi 'Meta GSAP': Pencarian untuk Menatal 'Sempurna' Infinite

Joseph Gordon-Levitt
Joseph Gordon-Levittasal
2025-03-25 10:23:10224semak imbas

Pergi

Saya tidak pasti bagaimana ini berlaku. Tetapi, cerita itu. Artikel ini lebih lanjut mengenai merumuskan konsep, yang akan membantu anda memikirkan animasi anda dengan cara yang berbeza. Begitu juga bahawa contoh khusus ini mempunyai skrol tak terhingga - khususnya tatal "sempurna" tak terhingga untuk dek kad tanpa menduplikasi mana -mana.

Kenapa saya di sini? Nah, ini semua bermula dari tweet. Tweet yang membuat saya berfikir tentang susun atur dan kandungan sampingan.

Saya mengambil konsep itu dan menggunakannya di laman web saya. Dan ia masih ada dalam tindakan pada masa penulisan.

Kemudian saya dapat memikirkan lebih lanjut mengenai pandangan galeri dan konsep sampingan. Kami melompat ke atas livestream dan memutuskan untuk mencuba dan membuat sesuatu seperti corak "aliran penutup" epal lama. Ingatlah?

Pemikiran pertama saya untuk membuat ini diandaikan saya akan membuat ini supaya ia berfungsi tanpa JavaScript, seperti yang berlaku dalam demo di atas, dengan cara yang menggunakan "peningkatan progresif." Saya meraih Greensock dan Scrolltrigger, dan kami pergi. Saya datang dari kerja itu sangat kecewa. Saya mempunyai sesuatu tetapi tidak dapat menatal tak terhingga untuk berfungsi bagaimana cara saya mahu. Butang "Seterusnya" dan "Sebelumnya" tidak mahu bermain bola. Anda boleh melihatnya di sini, dan ia memerlukan menatal mendatar.

Jadi saya membuka benang baru di forum Greensock. Sedikit yang saya tahu saya akan membuka diri saya sehingga beberapa pembelajaran yang serius! Kami menyelesaikan masalah dengan butang. Tetapi, sebagai saya, saya terpaksa bertanya sama ada sesuatu yang lain mungkin. Adakah terdapat cara "bersih" untuk melakukan tatal tak terhingga? Saya telah mencuba sesuatu di aliran tetapi tidak mempunyai nasib. Saya ingin tahu. Saya telah mencuba teknik seperti yang digunakan dalam pen ini yang saya buat untuk pelepasan scrolltrigger.

Jawapan awal adalah bahawa ia agak sukar untuk dilakukan:

Bahagian yang sukar mengenai perkara yang tidak terhingga pada tatal adalah bahawa bar skrol adalah terhad manakala kesan yang anda inginkan tidak. Oleh itu, anda perlu sama ada gelung kedudukan tatal seperti demo ini (terdapat di bahagian Demos Scrolltrigger) atau cangkuk terus ke dalam peristiwa navigasi yang berkaitan dengan tatal (seperti peristiwa roda) dan bukannya menggunakan kedudukan skrol sebenar.

Saya fikir itu berlaku dan gembira untuk meninggalkannya "as-is." Beberapa hari berlalu dan Jack menjatuhkan jawapan yang agak meniup fikiran saya ketika saya mula menggali ke dalamnya. Dan sekarang, selepas sekumpulan pergi, saya di sini untuk berkongsi teknik dengan anda.

Animasi apa sahaja

Satu perkara yang sering diabaikan dengan GSAP, ialah anda boleh menghidupkan hampir apa sahaja dengannya. Ini selalunya kerana perkara -perkara visual adalah apa yang difikirkan oleh musim bunga ketika memikirkan animasi - pergerakan fizikal sebenar sesuatu. Pemikiran pertama kami bukan tentang mengambil proses itu ke tahap meta dan menghidupkan dari langkah mundur.

Tetapi, fikirkan tentang kerja animasi pada skala yang lebih besar dan kemudian memecahkannya ke dalam lapisan. Sebagai contoh, anda bermain kartun. Kartun adalah koleksi komposisi. Setiap komposisi adalah adegan. Dan kemudian anda mempunyai kuasa untuk menggosok melalui koleksi komposisi dengan jarak jauh, sama ada di YouTube, menggunakan jauh TV anda, atau apa sahaja. Terdapat hampir tiga tahap untuk apa yang sedang berlaku.

Dan ini adalah helah yang kita perlukan untuk mencipta pelbagai jenis gelung tak terhingga . Ini adalah konsep utama di sini. Kami menghidupkan kedudukan kepala bermain garis masa dengan garis masa. Dan kemudian kita boleh menggosok garis masa itu dengan kedudukan tatal kami.

Jangan risau jika bunyi itu membingungkan. Kami akan memecahkannya.

Pergi "meta"

Mari kita mulakan dengan contoh. Kami akan membuat tween yang menggerakkan beberapa kotak dari kiri ke kanan. Di sini.

Sepuluh kotak yang terus pergi ke kanan. Itu agak mudah dengan Greensock. Di sini, kami menggunakan dari ke atas dan ulangi untuk mengekalkan animasi. Tetapi, kami mempunyai jurang pada permulaan setiap lelaran. Kami juga menggunakan Stagger untuk mengosongkan pergerakan dan itu sesuatu yang akan memainkan peranan penting seperti yang kita teruskan.

 gsap.fromto ('. box', {
  Xpercent: 100
}, {
  Xpercent: -200,
  terhuyung -huyung: 0.5,
  Tempoh: 1,
  Ulang: -1,
  Kemudahan: 'Tiada',
})

Sekarang datang bahagian yang menyeronokkan. Mari jeda tween dan berikannya kepada pemboleh ubah. Kemudian mari buat tween yang memainkannya. Kita boleh melakukan ini dengan tweening totaltime tween, yang membolehkan kita mendapatkan atau menetapkan Tween Tween Tween, sambil mempertimbangkan mengulangi dan mengulangi kelewatan.

 const shift = gsap.fromto ('. box', {
  Xpercent: 100
}, {
  Jeda: Benar,
  Xpercent: -200,
  terhuyung -huyung: 0.5,
  Tempoh: 1,
  Ulang: -1,
  Kemudahan: 'Tiada',
})

const duration = shift.duration ()

gsap.to (shift, {
  Jumlah masa: Tempoh,
  Ulang: -1,
  Tempoh: Tempoh,
  Kemudahan: 'Tiada',
})

Ini adalah tween "meta" pertama kami. Ia kelihatan sama tetapi kami menambah tahap kawalan yang lain. Kita boleh mengubah perkara di lapisan ini tanpa menjejaskan lapisan asal. Sebagai contoh, kita boleh menukar kemudahan tween ke power4.in. Ini benar -benar mengubah animasi tetapi tanpa menjejaskan animasi yang mendasari. Kami agak melindungi diri kita dengan sandaran.

Bukan itu sahaja, kita mungkin memilih untuk mengulangi hanya sebahagian daripada garis masa. Kita boleh melakukannya dengan yang lain, seperti ini:

Kod untuk itu akan menjadi sesuatu seperti ini.

 gsap.fromto (shift, {
  Jumlah masa: 2,
}, {
  Jumlah masa: Tempoh - 1,
  Ulang: -1,
  Tempoh: Tempoh,
  Kemudahan: 'Tiada'
})

Adakah anda melihat ke mana ini berlaku? Tonton tween itu. Walaupun ia menyimpan gelung, nombor flip pada setiap ulangan. Tetapi, kotak berada dalam kedudukan yang betul.

Mencapai gelung "sempurna"

Jika kita kembali kepada contoh asal kita, terdapat jurang yang ketara antara setiap pengulangan.

Di sini datang silap mata. Bahagian yang membuka kunci segalanya. Kita perlu membina gelung yang sempurna.

Mari kita mulakan dengan mengulangi peralihan tiga kali. Ia sama dengan menggunakan ulang: 3. Perhatikan bagaimana kami telah mengeluarkan ulangi: -1 dari tween.

 const getShift = () => gsap.fromto ('. box', {
  Xpercent: 100
}, {
  Xpercent: -200,
  terhuyung -huyung: 0.5,
  Tempoh: 1,
  Kemudahan: 'Tiada',
})

gelung const = gsap.timeline ()
  .Add (getShift ())
  .Add (getShift ())
  .Add (getShift ())

Kami telah menghidupkan tween awal ke dalam fungsi yang mengembalikan tween dan kami menambahkannya ke garis masa baru tiga kali. Dan ini memberi kita perkara berikut.

Ok. Tetapi, masih ada jurang. Sekarang kita boleh membawa parameter kedudukan untuk menambah dan meletakkan tweens tersebut. Kami mahu ia menjadi lancar. Ini bermakna memasukkan setiap set tweens sebelum yang sebelumnya berakhir. Itulah nilai berdasarkan stagger dan jumlah elemen.

 const stagger = 0.5 // digunakan dalam tween peralihan kami
Kotak const = gsap.utils.toarray ('. box')
const loop = gsap.timeline ({
  Ulang: -1
})
  .Add (getShift (), 0)
  .Add (getShift (), boxes.length * stagger)
  .Add (getShift (), boxes.length * stagger * 2)

Sekiranya kita mengemas kini garis masa kami untuk mengulangi dan menontonnya (sambil menyesuaikan diri dengan kebencian untuk melihat bagaimana ia mempengaruhi perkara) ...

Anda akan melihat bahawa terdapat tetingkap di tengah -tengah di sana yang mencipta gelung "lancar". Ingat kemahiran dari sebelumnya di mana kita memanipulasi masa? Itulah yang perlu kita lakukan di sini: gelung tetingkap masa di mana gelung itu "lancar."

Kami boleh mencuba tweening totaltime melalui tetingkap gelung itu.

 const loop = gsap.timeline ({
  Jeda: Benar,
  Ulang: -1,
})
.Add (getShift (), 0)
.Add (getShift (), boxes.length * stagger)
.Add (getShift (), boxes.length * stagger * 2)

gsap.fromto (gelung, {
  Jumlah masa: 4.75,
},
{
  Jumlah masa: '= 5',
  Tempoh: 10,
  Kemudahan: 'Tiada',
  Ulang: -1,
})

Di sini, kami mengatakan Tween totaltime dari 4.75 dan tambah panjang kitaran untuk itu. Panjang kitaran adalah 5. Dan itulah tingkap tengah garis masa. Kita boleh menggunakan GSAP's Nifty = untuk melakukan itu, yang memberi kita ini:

Luangkan masa untuk mencerna apa yang berlaku di sana. Ini boleh menjadi bahagian yang paling rumit untuk membungkus kepala anda. Kami mengira tingkap masa dalam garis masa kami. Sukar untuk memvisualisasikan tetapi saya telah pergi.

Ini adalah demo jam tangan yang mengambil masa 12 saat untuk tangan pergi sekali. Ia dilengkapkan tak terhingga dengan ulangi: -1 dan kemudian kami menggunakan dari untuk menghidupkan tetingkap masa tertentu dengan tempoh tertentu. Jika anda, kurangkan tetingkap masa untuk mengatakan 2 dan 6, kemudian ubah tempoh ke 1, tangan akan pergi dari jam 2 hingga 6 jam diulang. Tetapi, kami tidak pernah mengubah animasi yang mendasari.

Cuba konfigurasikan nilai untuk melihat bagaimana ia mempengaruhi perkara.

Pada ketika ini, adalah idea yang baik untuk menyatukan formula untuk kedudukan tetingkap kami. Kami juga boleh menggunakan pembolehubah untuk tempoh yang diperlukan untuk setiap kotak untuk peralihan.

 tempoh const = 1
const cycle_duration = boxes.length * stagger
const start_time = cycle_duration (durasi * 0.5)
const end_time = start_time cycle_duration

Daripada menggunakan tiga garis masa yang disusun, kami boleh melengkapkan elemen kami tiga kali di mana kami mendapat faedah tidak perlu mengira kedudukan. Menggambarkan ini sebagai tiga garis masa yang disusun adalah cara yang kemas untuk menggabungkan konsep, walaupun, dan cara yang baik untuk membantu memahami idea utama.

Mari kita ubah pelaksanaan kami untuk mencipta satu garis masa yang besar dari awal.

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

const loop = gsap.timeline ({
  Jeda: Benar,
  Ulang: -1,
})

const shift = [... kotak, ... kotak, ... kotak]

Shifts.foreach ((kotak, indeks) => {
  Loop.fromto (kotak, {
    Xpercent: 100
  }, {
    Xpercent: -200,
    Tempoh: 1,
    Kemudahan: 'Tiada',
  }, indeks * terhuyung -huyung)
})

Ini lebih mudah untuk disatukan dan memberi kita tetingkap yang sama. Tetapi, kita tidak perlu berfikir tentang matematik. Sekarang kita gelung melalui tiga set kotak dan meletakkan setiap animasi mengikut Stagger.

Bagaimanakah kelihatannya jika kita menyesuaikan diri? Ia akan menyapu kotak lebih dekat.

Tetapi, ia telah memecahkan tingkap kerana sekarang jumlah masa keluar. Kita perlu mengira semula tetingkap. Sekarang adalah masa yang tepat untuk memasangkan formula yang kami hitung lebih awal.

 tempoh const = 1
const cycle_duration = stagger * boxes.length
const start_time = cycle_duration (durasi * 0.5)
const end_time = start_time cycle_duration

gsap.fromto (gelung, {
  Jumlah masa: start_time,
},
{
  Jumlah masa: end_time,
  Tempoh: 10,
  Kemudahan: 'Tiada',
  Ulang: -1,
})

Tetap!

Kami juga boleh memperkenalkan "mengimbangi" jika kami mahu mengubah kedudukan permulaan.

 const stagger = 0.5
const offset = 5 * Stagger
const start_time = (cycle_duration (stagger * 0.5)) mengimbangi

Sekarang tetingkap kami bermula dari kedudukan yang berbeza.

Tetapi masih, ini tidak bagus kerana ia memberi kita susunan yang janggal di setiap hujungnya. Untuk menghilangkan kesan itu, kita perlu memikirkan tetingkap "fizikal" untuk kotak kami. Atau fikirkan bagaimana mereka masuk dan keluar dari tempat kejadian.

Kami akan menggunakan Document.body sebagai tetingkap untuk contoh kami. Mari kita mengemas kini kotak Tweens untuk menjadi garis masa individu di mana kotak -kotak skala naik dan turun di keluar. Kita boleh menggunakan yoyo dan ulangi: 1 untuk mencapai masuk dan keluar.

 Shifts.foreach ((kotak, indeks) => {
  const box_tl = gsap
    .Timeline ()
    .Fromto (
      Kotak,
      {
        Xpercent: 100,
      },
      {
        Xpercent: -200,
        Tempoh: 1,
        Kemudahan: 'Tiada',
      }, 0
    )
    .Fromto (
      Kotak,
      {
        Skala: 0,
      },
      {
        Skala: 1,
        Ulangi: 1,
        Yoyo: Benar,
        Kemudahan: 'Tiada',
        Tempoh: 0.5,
      },
      0
    )
  Loop.add (box_tl, index * stagger)
})

Mengapa kita menggunakan tempoh garis masa 1? Ia menjadikan perkara lebih mudah untuk diikuti. Kami tahu masa adalah 0.5 apabila kotak berada di titik tengah. Perlu diingat bahawa pelonggaran tidak akan memberi kesan yang biasanya kita fikirkan di sini. Malah, pelonggaran sebenarnya akan memainkan peranan dalam bagaimana kotak meletakkan diri mereka sendiri. Sebagai contoh, kemudahan akan mengumpulkan kotak di sebelah kanan sebelum mereka bergerak.

Kod di atas memberi kita ini.

Hampir. Tetapi, kotak kami hilang untuk satu masa di tengah. Untuk membetulkannya, mari memperkenalkan harta tanah. Ia bertindak seperti animasi-fill-mod: tidak ada di CSS. Kami memberitahu GSAP bahawa kami tidak mahu mengekalkan atau merekodkan sebarang gaya yang ditetapkan di dalam kotak.

 Shifts.foreach ((kotak, indeks) => {
  const box_tl = gsap
    .Timeline ()
    .Fromto (
      Kotak,
      {
        Xpercent: 100,
      },
      {
        Xpercent: -200,
        Tempoh: 1,
        Kemudahan: 'Tiada',
        Secara mendalam: palsu,
      }, 0
    )
    .Fromto (
      Kotak,
      {
        Skala: 0,
      },
      {
        Skala: 1,
        Ulangi: 1,
        Zindex: kotak.length 1,
        Yoyo: Benar,
        Kemudahan: 'Tiada',
        Tempoh: 0.5,
        Secara mendalam: palsu,
      },
      0
    )
  Loop.add (box_tl, index * stagger)
})

Perubahan kecil itu membetulkan perkara untuk kita! Perhatikan bagaimana kami juga termasuk z-index: boxes.length. Itu harus melindungi kita terhadap sebarang isu Z-indeks.

Di sana kita ada! Gelung lancar pertama kami. Tiada unsur pendua dan kesinambungan sempurna. Kami membongkok masa! Pat sendiri di belakang jika anda telah mendapat sejauh ini! ?

Jika kita mahu melihat lebih banyak kotak sekaligus, kita boleh mengikat dengan masa, terhuyung -huyung, dan kemudahan. Di sini, kami mengalami kecederaan 0.2 dan kami juga memperkenalkan kelegapan ke dalam campuran.

Bahagian utama di sini ialah kita boleh menggunakan RepeatDelay supaya peralihan kelegapan lebih cepat daripada skala. Pudar lebih dari 0.25 saat. Tunggu 0.5 saat. Pudar kembali lebih dari 0.25 saat.

 .Fromto (
  Kotak, {
    Kelegapan: 0,
  }, {
    Kelegapan: 1,
    Tempoh: 0.25,
    Ulangi: 1,
    RepeatDelay: 0.5,
    Secara mendalam: palsu,
    Kemudahan: 'Tiada',
    Yoyo: Benar,
  }, 0)

Sejuk! Kita boleh melakukan apa sahaja yang kita mahu dengan peralihan masuk dan keluar. Perkara utama di sini adalah bahawa kita mempunyai tetingkap masa yang memberi kita gelung tak terhingga.

Mengaitkan ini untuk menatal

Sekarang kita mempunyai gelung lancar, mari kita melampirkannya. Untuk ini kita boleh menggunakan Scrolltrigger GSAP. Ini memerlukan tween tambahan untuk menggosok tetingkap gelung kami. Perhatikan bagaimana kami telah menetapkan gelung untuk dijeda sekarang juga.

 const loop_head = gsap.fromto (gelung, {
  Jumlah masa: start_time,
},
{
  Jumlah masa: end_time,
  Tempoh: 10,
  Kemudahan: 'Tiada',
  Ulang: -1,
  Jeda: Benar,
})

scrub const = gsap.to (loop_head, {
  Jumlah masa: 0,
  Jeda: Benar,
  Tempoh: 1,
  Kemudahan: 'Tiada',
})

Caranya di sini adalah menggunakan ScrollTrigger untuk menggosok kepala bermain gelung dengan mengemas kini jumlah scrub. Terdapat pelbagai cara yang dapat kita tetapkan tatal ini. Kita boleh mendatar atau terikat pada bekas. Tetapi, apa yang akan kita lakukan ialah membungkus kotak kami dalam elemen. Kotak dan pin ke Viewport. (Ini membetulkan kedudukannya dalam viewport.) Kami juga akan melekat dengan menatal menegak. Semak demo untuk melihat gaya untuk kotak. Yang menetapkan perkara -perkara kepada saiz viewport.

 Import Scrolltrigger dari 'https://cdn.skypack.dev/gsap/scrolltrigger'
gsap.registerplugin (scrolltrigger)

Scrolltrigger.create ({
  Mula: 0,
  akhir: '= 2000',
  mendatar: palsu,
  pin: '.boxes',
  onupdate: self => {
    Scrub.vars.totaltime = loop_head.duration () * self.progress
    Scrub.Invalidate (). Restart ()
  }
})

Bahagian penting adalah di dalam onupdate. Di sinilah kami menetapkan jumlah tween berdasarkan kemajuan tatal. Panggilan yang tidak sah memancarkan mana -mana kedudukan yang direkodkan secara dalaman untuk scrub. Restart kemudian menetapkan kedudukan ke totaltime baru yang kami tetapkan.

Cubalah! Kita boleh berulang -alik dalam garis masa dan mengemas kini kedudukan.

Betapa sejuknya itu? Kami boleh menatal untuk menggosok garis masa yang menggosok garis masa yang merupakan tetingkap garis masa. Mencerna yang sekejap kerana itulah yang berlaku di sini.

Perjalanan masa untuk menatal tak terhingga

Sampai sekarang, kami telah memanipulasi masa. Sekarang kita akan perjalanan masa!

Untuk melakukan ini, kami akan menggunakan beberapa utiliti GSAP yang lain dan kami tidak lagi akan menggosok jumlah masa loop_head. Sebaliknya, kita akan mengemas kini melalui proksi. Ini adalah satu lagi contoh hebat untuk pergi "meta" GSAP.

Mari kita mulakan dengan objek proksi yang menandakan kedudukan playhead.

 const playhead = {kedudukan: 0}

Sekarang kita boleh mengemas kini scrub kami untuk mengemas kini kedudukan. Pada masa yang sama, kita boleh menggunakan utiliti bungkus GSAP, yang membungkus nilai kedudukan di sekitar tempoh loop_head. Sebagai contoh, jika tempoh adalah 10 dan kami memberikan nilai 11, kami akan mendapat kembali 1.

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

scrub const = gsap.to (playhead, {
  Kedudukan: 0,
  onupdate: () => {
    Loop_head.totalTime (position_wrap (playhead.position))
  },
  Jeda: Benar,
  Tempoh: 1,
  Kemudahan: 'Tiada',
})

Akhir sekali, tetapi tidak, kita perlu menyemak semula ScrollTrigger supaya ia mengemas kini pembolehubah yang betul pada scrub. Itu kedudukan, bukannya totaltime.

 Scrolltrigger.create ({
  Mula: 0,
  akhir: '= 2000',
  mendatar: palsu,
  pin: '.boxes',
  onupdate: self => {
    Scrub.vars.position = loop_head.duration () * self.progress
    Scrub.Invalidate (). Restart ()
  }
})

Pada ketika ini kami telah beralih kepada proksi dan kami tidak akan melihat sebarang perubahan.

Kami mahukan gelung tak terhingga apabila kami menatal. Pemikiran pertama kami mungkin menatal ke permulaan apabila kami melengkapkan kemajuan tatal. Dan ia akan melakukannya dengan tepat, tatal ke belakang. Walaupun itulah yang kita mahu lakukan, kita tidak mahu playhead menggosok ke belakang. Di sinilah TotalTime masuk. Ingat? Ia mendapat atau menetapkan kedudukan playhead mengikut jumlah yang termasuk apa -apa pengulangan dan kelewatan mengulangi.

Sebagai contoh, katakan tempoh kepala gelung adalah 5 dan kami sampai di sana, kami tidak akan menggosok kembali ke 0. Sebaliknya, kami akan terus menggosok kepala gelung ke 10. Jika kami terus berjalan, ia akan pergi ke 15, dan sebagainya. Sementara itu, kami akan menjejaki pemboleh ubah lelaran kerana itu memberitahu kami di mana kami berada di scrub. Kami juga akan memastikan bahawa kami hanya mengemas kini lelaran apabila kami memukul ambang kemajuan.

Mari kita mulakan dengan pemboleh ubah lelaran:

 Biarkan lelaran = 0

Sekarang mari kita mengemas kini pelaksanaan ScrollTrigger kami:

 const trigger = scrolltrigger.create ({
  Mula: 0,
  akhir: '= 2000',
  mendatar: palsu,
  pin: '.boxes',
  onupdate: self => {
    const tatal = self.scroll ()
    jika (tatal> self.end - 1) {
      // pergi ke hadapan dalam masa
      Balut (1, 1)
    } else if (tatal <p>Perhatikan bagaimana kita kini memfaktorkan lelaran ke dalam pengiraan kedudukan. Ingat bahawa ini akan dibalut dengan scrubber. Kami juga mengesan apabila kami memukul had tatal kami, dan itulah titik di mana kami membungkus. Fungsi ini menetapkan nilai lelaran yang sesuai dan menetapkan kedudukan skrol baru.</p><pre rel="JavaScript" data-line=""> const wrap = (iterationDelta, scrollto) => {
  iteration = iterationDelta
  Trigger.scroll (scrollTo)
  Pencetus.update ()
}

Kami mempunyai tatal tak terhingga! Sekiranya anda mempunyai salah satu tikus mewah dengan roda skrol yang boleh anda lepaskan, berikannya! Ia menyeronokkan!

Inilah demo yang memaparkan lelaran dan kemajuan semasa:

Tatal Snapping

Kami ada. Tetapi, selalu ada "bagus untuk menghidap" ketika mengerjakan ciri seperti ini. Mari mulakan dengan tatal snapping. GSAP membuat ini mudah, kerana kita boleh menggunakan gsap.utils.snap tanpa sebarang kebergantungan lain. Itu mengendalikan snapping ke masa ketika kami memberikan mata. Kami mengisytiharkan langkah antara 0 dan 1 dan kami mempunyai 10 kotak dalam contoh kami. Ini bermakna snap 0.1 akan berfungsi untuk kita.

 const snap = gsap.utils.snap (1 / boxes.length)

Dan yang mengembalikan fungsi yang boleh kita gunakan untuk merapatkan nilai kedudukan kita.

Kami hanya mahu snap sebaik sahaja tatal telah berakhir. Untuk itu, kita boleh menggunakan pendengar acara di Scrolltrigger. Apabila tatal berakhir, kami akan menatal ke kedudukan tertentu.

 Scrolltrigger.addeventListener ('scrollend', () => {
  scrollToposition (scrub.vars.position)
})

Dan inilah scrolltoposition:

 const scrollToposition = position => {
  const snap_pos = snap (kedudukan)
  Kemajuan const =
    (Snap_pos - loop_head.duration () * iteration) / loop_head.duration ()
  Const Scroll = ProgressToScroll (Kemajuan)
  Trigger.scroll (tatal)
}

Apa yang kita buat di sini?

  1. Mengira titik dalam masa untuk merapatkan diri
  2. Mengira kemajuan semasa. Katakan loop_head.duration () adalah 1 dan kami telah terputus ke 2.5. Itu memberi kita kemajuan 0.5 yang mengakibatkan lelaran 2, di mana 2.5 - 1 * 2/1 === 0.5. Kami mengira kemajuan supaya ia sentiasa antara 1 dan 0.
  3. Mengira destinasi tatal. Ini adalah sebahagian kecil daripada jarak scrolltrigger kami yang boleh ditutup. Dalam contoh kami, kami telah menetapkan jarak 2000 dan kami mahu sebahagian kecil daripada itu. Kami membuat fungsi baru ProgressToScroll untuk mengiranya.
 const progressToscroll = kemajuan =>
  gsap.utils.clamp (1, trigger.end - 1, gsap.utils.wrap (0, 1, kemajuan) * trigger.end)

Fungsi ini mengambil nilai kemajuan dan memetakannya ke jarak tatal terbesar. Tetapi kami menggunakan pengapit untuk memastikan nilai tidak boleh menjadi 0 atau 2000. Ini penting. Kami melindungi terhadap nilai -nilai ini kerana ia akan meletakkan kami dalam gelung tak terhingga.

Terdapat sedikit yang perlu dibawa ke sana. Lihat demo ini yang menunjukkan nilai yang dikemas kini pada setiap snap.

Mengapa perkara banyak sombong? Tempoh dan kemudahan menggosok telah diubah. Tempoh yang lebih kecil dan kemudahan punchier memberi kami snap.

 scrub const = gsap.to (playhead, {
  Kedudukan: 0,
  onupdate: () => {
    Loop_head.totalTime (position_wrap (playhead.position))
  },
  Jeda: Benar,
  Tempoh: 0.25,
  kemudahan: 'power3',
})

Tetapi, jika anda bermain dengan demo itu, anda akan melihat ada masalah. Kadang -kadang apabila kita membungkus di dalam snap, playhead melompat. Kita perlu mengambil kira itu dengan memastikan kita membungkus apabila kita snap - tetapi, hanya apabila perlu.

 const scrollToposition = position => {
  const snap_pos = snap (kedudukan)
  Kemajuan const =
    (Snap_pos - loop_head.duration () * iteration) / loop_head.duration ()
  Const Scroll = ProgressToScroll (Kemajuan)
  jika (kemajuan> = 1 || kemajuan <p> Dan sekarang kita mempunyai tatal tak terhingga dengan mengetuk!</p><h3> Apa yang akan datang?</h3><p> Kami telah melengkapkan asas untuk Scroller Infinite yang kukuh. Kita boleh memanfaatkannya untuk menambah perkara, seperti kawalan atau fungsi papan kekunci. Sebagai contoh, ini boleh menjadi satu cara untuk menyambung butang "Seterusnya" dan "Sebelumnya" dan kawalan keyboard. Apa yang perlu kita lakukan ialah memanipulasi masa, bukan?</p><pre rel="JavaScript" data-line=""> const next = () => scrollToposition (scrub.vars.position - (1 / boxes.length))
const prev = () => scrollToposition (scrub.vars.position (1 / boxes.length))

// anak panah kiri dan kanan ditambah A dan D
document.addeventListener ('keydown', event => {
  jika (event.keycode === 37 || event.keycode === 65) Seterusnya ()
  jika (event.keycode === 39 || event.keycode === 68) prev ()
})

Document.QuerySelector ('. Seterusnya'). AddEventListener ('klik', seterusnya)
Document.QuerySelector ('.

Itu boleh memberi kita sesuatu seperti ini.

Kita boleh memanfaatkan fungsi scrolltoposition kita dan membongkarkan nilai seperti yang kita perlukan.

Itu sahaja!

Lihat itu? GSAP boleh menghidupkan lebih banyak daripada elemen! Di sini, kami membongkok dan memanipulasi masa untuk mencipta gelangsar tak terhingga yang hampir sempurna. Tiada unsur pendua, tidak ada kekacauan, dan fleksibiliti yang baik.

Mari rekap apa yang kita tutup:

  • Kita boleh menghidupkan animasi. ?
  • Kita boleh berfikir tentang masa sebagai alat kedudukan apabila kita memanipulasi masa.
  • Cara menggunakan ScrollTrigger untuk menggosok animasi melalui proksi.
  • Cara menggunakan beberapa utiliti hebat GSAP untuk mengendalikan logik untuk kami.

Anda kini boleh memanipulasi masa! ?

Konsep itu pergi "meta" GSAP membuka pelbagai kemungkinan. Apa lagi yang boleh anda bernyawa? Audio? Video? Bagi demo "aliran penutup", di sinilah ia pergi!

Atas ialah kandungan terperinci Pergi 'Meta GSAP': Pencarian untuk Menatal 'Sempurna' Infinite. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Peralihan elemen bersamaArtikel seterusnya:Peralihan elemen bersama