fossula

CHOI-syΒ·2024λ…„ 1μ›” 11일
0

ν”„λ‘œμ νŠΈ

λͺ©λ‘ 보기
4/5
post-thumbnail

πŸ’» fossula

  • μ‚¬μ΄νŠΈλͺ…: fossula
  • μ‚¬μš©μ–Έμ–΄: HTML, CSS, JavaScript
  • 라이브러리: jQuery, GSAP, ScrollTrigger, Lenis
  • μœ ν˜•: λ°˜μ‘ν˜•
  • πŸ“° https://hallowmang.github.io/fossula/

βœ… Check Point

βœ” header κΈ€μžμƒ‰ λ³€κ²½
βœ” GSAP의 gsap.utils.toArray
βœ” GSAP의 .fromTo()


1.header κΈ€μžμƒ‰ λ³€κ²½

$(window).scroll(function() {
    // ν˜„μž¬ 슀크둀 μœ„μΉ˜ κ°€μ Έμ˜€κΈ°
    let scrollPosition = $(window).scrollTop();
    // 슀크둀 μž„κ³„κ°’ μ„€μ • (색상 λ³€κ²½ 지점)
    let scrollThreshold = 100; // ν•„μš”μ— 따라 이 값을 μ‘°μ •

    // 슀크둀 μœ„μΉ˜κ°€ μž„κ³„κ°’μ„ λ„˜μ—ˆλŠ”μ§€ 확인
    if (scrollPosition > scrollThreshold) {
      // `fill` 속성을 black으둜 λ³€κ²½
      $("path").css("fill", "black");
      // `<a>` νƒœκ·Έμ˜ `color` 속성을 black으둜 λ³€κ²½
      $(".header a").css("color", "black");
    } else {
      // `fill` 속성을 λ‹€μ‹œ white둜 λ³€κ²½
      $("path").css("fill", "white");
      // `<a>` νƒœκ·Έμ˜ `color` 속성을 λ‹€μ‹œ white둜 λ³€κ²½
      $(".header a").css("color", "white");
    }
  });

2. gsap.utils.toArray⭐⭐⭐⭐⭐

같은 클래슀λ₯Ό 가지고 μžˆλŠ” μš”μ†Œλ“€μ„ λ™μΌν•œ μ• λ‹ˆλ©”μ΄μ…˜μœΌλ‘œ μ μš©ν•˜κ³  μ‹Άμ–΄μ„œ μ•Œμ•„λ΄€λŠ”λ° GSAPμ—μ„œ 보톡 toArray()λ₯Ό μ‚¬μš©ν•˜λŠ” 것
κ°™μ•˜λ‹€.

toArray()λŠ” GSAP λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ œκ³΅λ˜λŠ” μœ ν‹Έλ¦¬ν‹° λ©”μ†Œλ“œ 쀑 ν•˜λ‚˜μ΄λ‹€.

같은 클래슀λ₯Ό 가진 μ—¬λŸ¬ μš”μ†Œλ“€μ„ μ„ νƒν•˜μ—¬ λ°°μ—΄λ‘œ λ³€ν™˜ν•˜κ³  κ·Έ 배열에 λŒ€ν•΄ μΌκ΄„μ μœΌλ‘œ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ μš©ν•  수 μžˆλ‹€. 이것은 μ½”λ“œλ₯Ό 더 κ°„κ²°ν•˜κ²Œ λ§Œλ“€μ–΄μ£Όκ³ , μ—¬λŸ¬ μš”μ†Œμ— λŒ€ν•΄ μΌκ΄„μ μœΌλ‘œ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ‘°μž‘ν•˜κ±°λ‚˜ μ μš©ν•˜λŠ” 데 νš¨μœ¨μ μ΄λ‹€. πŸ‘

πŸ”μ‚¬μ΄νŠΈ - https://gsap.com/docs/v3/GSAP/UtilityMethods

κΈ°λ³Έ μ‚¬μš©λ²•μ€ ❔❔❔

const elements = gsap.utils.toArray(".myElements");

gsap.to(elements, {
  opacity: 1,
  duration: 1,
  stagger: 0.2, // μš”μ†Œλ“€ κ°„μ˜ 간격 μ„€μ •
});

이런 μ‹μœΌλ‘œ μž‘μ„±ν•˜λ©΄ λœλ‹€.

ν•˜μ§€λ§Œ, 보톡 λ‹¨λ…μ μœΌλ‘œ μ‚¬μš©ν•˜κΈ° λ³΄λ‹€λŠ” λ°°μ—΄ λ©”μ†Œλ“œμ™€ 같이 μ μš©ν•΄μ„œ μ‚¬μš©ν•˜λŠ”κ²ƒ κ°™λ‹€.

λ°°μ—΄ λ©”μ†Œλ“œ - forEach⭐, map, filter, reduce λ“±...

πŸ“— GSAP

gsap.utils.toArray('.section-img-box img').forEach((img)=>{
  gsap.set(img,{
    scale:1.2,
    yPercent:-5,
  }),
  gsap.to(img,{
    scrollTrigger:{
      trigger:img.closest(".section-img-box"),
      start:"0% 100%",
      end:"100% 0%",
      scrub:true,
    },
    scale:1,
    yPercent:0,
  });
});

forEachλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“  .section-img-box img에 μ• λ‹ˆλ©”μ΄μ…˜ μ μš©ν•˜λ©΄μ„œ, .section-img-box img 클래슀λ₯Ό 가진 λͺ¨λ“  μš”μ†Œλ₯Ό λ°˜λ³΅ν•˜κ³  각 μš”μ†Œμ— λŒ€ν•΄ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ„€μ •ν•˜μ˜€λ‹€.

λ¬Έμ œλ°œμƒβ— triggerλ₯Ό ".section-img-box"만 μ„€μ •ν–ˆλ”λ‹ˆ 전체가 적용이 μ•ˆλ˜μ—ˆλ‹€.
closest()λ₯Ό μ μš©ν–ˆλ”λ‹ˆ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆλ‹€.

closest()λŠ” DOM νŠΈλ¦¬μ—μ„œ νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜λŠ” κ°€μž₯ κ°€κΉŒμš΄ 쑰상 μš”μ†Œλ₯Ό μ°ΎλŠ” JavaScript의 λ©”μ„œλ“œμ΄λ‹€. 이 λ©”μ„œλ“œλŠ” νŠΉμ • μš”μ†Œμ˜ λΆ€λͺ¨ μš”μ†Œλ‚˜ κ·Έ μ΄μƒμ˜ μƒμœ„ μš”μ†Œλ“€μ„ 탐색할 λ•Œ μœ μš©ν•˜λ‹€.
closest()λ©”μ„œλ“œλŠ” 인자둜 주어진 μ„ νƒμžλ‚˜ 쑰건을 λ§Œμ‘±ν•˜λŠ” κ°€μž₯ κ°€κΉŒμš΄ μƒμœ„ μš”μ†Œλ₯Ό μ°Ύμ•„μ€λ‹ˆλ‹€. μ΄λ•Œ ν•΄λ‹Ή μš”μ†ŒλΆ€ν„° μƒμœ„ μš”μ†Œλ‘œ μ˜¬λΌκ°€λ©΄μ„œ 쑰건을 λ§Œμ‘±ν•˜λŠ” 첫 번째 μš”μ†Œλ₯Ό λ°˜ν™˜ν•˜κ³ , λ§Œμ•½ 쑰건을 λ§Œμ‘±ν•˜λŠ” μš”μ†Œκ°€ μ—†λ‹€λ©΄ null을 λ°˜ν™˜
주둜 closest()λŠ” 이벀트 μ²˜λ¦¬λ‚˜ νŠΉμ • μš”μ†Œλ₯Ό μ°Ύμ•„ 그에 λ”°λ₯Έ λ™μž‘μ„ μˆ˜ν–‰ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. νŠΉμ • μš”μ†Œμ˜ λΆ€λͺ¨ μš”μ†Œ μ€‘μ—μ„œ κ°€μž₯ κ°€κΉŒμš΄ νŠΉμ • 클래슀λͺ…을 가진 μš”μ†Œλ‚˜ νŠΉμ • νƒœκ·Έλ₯Ό 가진 μš”μ†Œλ₯Ό μ°ΎλŠ” 데 μœ μš©ν•˜κ²Œ ν™œμš©


3. fromTo, autoAlpha

이번 ν”„λ‘œμ νŠΈμ—μ„œλŠ” fromToλ₯Ό μ‚¬μš©ν•˜μ—¬ νŽ˜μ΄λ“œμΈ νŽ˜μ΄λ“œμ•„μ›ƒνš¨κ³Όλ₯Ό μ‚¬μš©ν•΄λ³΄μ•˜λ‹€.

fromTo

gsap.utils.toArray('.section-inner').forEach(text=>{
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: text,
      start: "0 80%",
      end: "70% center",
      scrub: 1,
    }
  });

  // 각 μš”μ†Œλ₯Ό μ›ν•˜λŠ” μˆœμ„œλŒ€λ‘œ λ‚˜νƒ€λ‚˜κ²Œ μ„€μ •
  tl.fromTo(text.querySelector('.title'), { autoAlpha: 0, y: 10 }, { autoAlpha: 1, y: 0, duration:0.5,  ease: "none" })
    .fromTo(text.querySelector('.subtitle'), { autoAlpha: 0, y: 10 }, { autoAlpha: 1, y: 0, duration:0.5,  ease: "none" })
    .fromTo(text.querySelector('.description'), { autoAlpha: 0, y: 10 }, { autoAlpha: 1, y: 0, duration:0.5,  ease: "none" })
    .fromTo(text.querySelector('.amount-price-group'), { autoAlpha: 0, y: 10 }, { autoAlpha: 1, y: 0, duration:0.5,  ease: "none" });
});

λ¨Όμ €, gsap.timeline을 λ³€μˆ˜ tl둜 μ €μž₯
κ·Έ λ’€ .section-inner의 μžμ‹ ν΄λž˜μŠ€λ“€ .title, .subtitle, .description, .amount-price-group에
gsap.from에 ν•΄λ‹Ήν•˜λŠ” μ• λ‹ˆλ©”μ΄μ…˜μ„ λ¨Όμ € μž‘μ„± ν•œ λ’€{ autoAlpha: 0, y: 10 }
gsap.to의 { autoAlpha: 1, y: 0, duration:0.5, ease: "none" })λ₯Ό μž‘μ„±ν•΄ 쀬닀.

πŸ€”autoAlpha??

autoAlphaλŠ” CSS의 opacity와 같이 μš”μ†Œμ˜ 투λͺ…도λ₯Ό μ œμ–΄ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” 속성이닀.
그럼, 뭐가 λ‹€λ₯ΌκΉŒ???πŸ€”πŸ€”πŸ€”

autoAlphaλŠ” GSAPμ—μ„œλ§Œ μ œκ³΅ν•˜λŠ” μ†μ„±μœΌλ‘œ, μš”μ†Œμ˜ 투λͺ…도λ₯Ό μ‘°μ ˆν•˜λ©΄μ„œ λ™μ‹œμ— μš”μ†Œλ₯Ό λ³΄μ΄κ±°λ‚˜ 숨길 수 μžˆλ‹€.
autoAlphaλ₯Ό μ‚¬μš©ν•˜λ©΄ μš”μ†Œλ₯Ό 투λͺ…ν•˜κ²Œ λ§Œλ“€λ©΄μ„œ CSS의 visibility 속성을 μ‘°μ ˆν•˜μ—¬ μš”μ†Œλ₯Ό ν™”λ©΄μ—μ„œ 숨길 수 μžˆμŠ΅λ‹ˆλ‹€. 투λͺ…도가 0이면 μš”μ†ŒλŠ” ν™”λ©΄μ—μ„œ 보이지 μ•Šμ§€λ§Œ, visibility: hidden 속성이 μ μš©λ˜μ–΄ λ ˆμ΄μ•„μ›ƒμ—μ„œ 곡간을 μ°¨μ§€ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 뜻

상황에 따라 λ‹€λ₯΄κ² μ§€λ§Œ,
λ²„νŠΌ(buttonνƒœκ·Έ)μ΄λ‚˜ 링크(aνƒœκ·Έ)처럼 μ‚¬μš©μžμ™€μ˜ μƒν˜Έμž‘μš©μ΄ μžˆλŠ” μš”μ†Œμ— λŒ€ν•΄μ„œλŠ” autoAlphaλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 쒋을 것 κ°™λ‹€.
λ˜ν•œ, λ ˆμ΄μ•„μ›ƒμ—μ„œ 곡간을 μ°¨μ§€ν•˜λ©΄ μ•ˆλ˜λŠ” 뢀뢄은 autoAlphaλ₯Ό 써주자~

profile
μ•ˆλ…•ν•˜μ„Έμš”.

0개의 λŒ“κΈ€