<div class="img-roll"> <img src="./assets/images/roll1.jpg" alt=""> <img src="./assets/images/roll2.jpg" alt=""> ... </div>
img{ position: absolute; top: 0;left: 0; width: 100%; height: 100%; object-fit: cover; visibility: hidden; }
gsap.to('.sc-header .group-images .img-roll img',{ visibility:'visible', stagger:{ each: 0.1, } });
κ° μ΄λ―Έμ§μ CSS
μ visiblity: hidden
μ²λ¦¬ νκΈ°
gsap.to
λ₯Ό μ¬μ©νμ¬ img
μ κ²½λ‘λ₯Ό λΆλ¬μ¨ ν μ΄λ―Έμ§λ€μ΄ 보μΌμ μκ² visiblity:'visible'
μμ±νκΈ°
gsap
μ stagger / each
λ₯Ό νμ©νμ¬ κ° μ΄λ―Έμ§λ€μ΄ 0.1μ΄ λ€μ μμ°¨μ μΌλ‘ 보μΌμ μκ² νκΈ°
stagger
λ μΌλ ¨μ μμλ€μ μ§μ λ μκ° κ°κ²©μΌλ‘ μμ°¨μ μΌλ‘ μ λλ©μ΄μ ννλ λ° μ¬μ©λλ©°each
λ κ° μμλ€μ μμ μκ° κ°κ²©μ λνλ λλ€.
clamp(min, val, max);
clamp()
ν¨μλ CSS
μ κ° λ²μλ₯Ό μ μνλ λ° μ¬μ©λλ ν¨μλ‘ μ΅μ, μ΅λ, λ° νμ¬ κ°μΌλ‘ μ΄λ£¨μ΄μ§ μΈ κ°μ§ 맀κ°λ³μλ₯Ό κ°μ§λλ€.
width: clamp(36px,4.5vw,64px);
width
μ μ΅μ κ°=36px
, νμ¬ κ°=4.5vw
, μ΅λ κ°=64px
μ¬κΈ°μwidth
λ νμ¬ κ° 4.5vw
λ 36px
λ³΄λ€ μμμ§ μ μμΌλ©° 64px
λ³΄λ€ μ»€μ§ μ μμ΅λλ€.
*λ°μν μΉμ¬μ΄νΈμμ μ μ©νκ² μ¬μ©ν μ μμ΅λλ€.
λ‘κ³ μ λλ©μ΄μ μμ μ¬μ©ν
stroke-dashoffset
μμ±μSVG
μμ μ μ ν¨ν΄μ μ μ΄ν λ νμ©λλ μμ± μ€ νλλ‘ μ£Όλ‘ μ μ΄λ κ²½λ‘κ° κ·Έλ €μ§λ μ λλ©μ΄μ μ λ§λ€ λ μ¬μ©ν©λλ€.
λ‘κ³ μμ ν¬ν¨λ μ μ κΈΈμ΄ μ°ΎκΈ° (λ³΄ν΅ μ¬λ¬ κ°μ μ
λ ₯ν΄λ³΄λ©° μ°ΎμμΌ ν¨)
*μ μμμ κ²½μ°μλ 20
μ΄μμ΅λλ€.
stroke-dashoffset
κ³Ό stroke-dasharray
μ κ°μ κ°κ² μ£Όμ΄ νλ©΄ μμμ 보μ΄μ§ μκ² νκΈ°
μ λλ©μ΄μ
μ΄ μμν λ°©ν₯μ stroke-dashoffset
μ κ°μ λ°κΏλ³΄λ©΄μ μ νκΈ°
*μ μμμ κ²½μ°μλ 20
μμ 0
μΌλ‘ κ°λ©΄ μ€λ₯Έμͺ½ λ°©ν₯, 20
μμ 40
μΌλ‘ κ°λ©΄ μΌμͺ½ λ°©ν₯μΌλ‘ μ λλ©μ΄μ
μ΄ μ μ©λ©λλ€.
μμμ μ°Ύμ κ°λ€μ λ°νμΌλ‘stroke-dashoffset
μ @keyframes
μ μνκΈ°
*μ μμμμλ μμ μ κ³Ό μλ μ μ΄ λ°λλ‘ κ·Έλ €μ§λ λλμ μ£ΌκΈ° μν΄ κ°κ° λ€λ₯Έ κ°μ μ£Όμμ΅λλ€.
κ° μ μ animation
μΆκ°νκΈ°
grid-column: 1/-1; grid-row: 1/-1;
μ 그리λ μμ΄ν μ΄ κ·Έλ¦¬λ 컨ν μ΄λμμ 첫 λ²μ§Έ μ΄(1)λΆν° λ§μ§λ§ μ΄(-1)κΉμ§, 그리λ 컨ν μ΄λμ 첫 λ²μ§Έ νλΆν° λ§μ§λ§ νκΉμ§ νμ₯λλλ‘ λ§λ€μ΄ μ€λλ€. μμ μμλ₯Ό 보면 λΆλͺ¨ ν΄λμ€μ λλΉμ λμ΄λ₯Ό 100%μ© μ£Όκ³ κ·Έλ¦¬λλ₯Ό λ§λ€λ©΄ λ§μΉabsolute
ν¬μ§μ μ μ΄ κ²μ²λΌ 그리λ μμ΄ν λ€μ΄ ν¬κ°μ§ κ²μ λ³Ό μ μμΌλ©° μ΄λ μ΄λ―Έμ§λ μ¬λ¬ μμλ₯Ό ν 곡κ°μ κ²Ήμ³λμ λ μ μ©νκ² μ¬μ©ν μ μμ΅λλ€.
dvh(Dynamic Viewport Height)
λ μ£Όμ νμμ€μ μ 무μ κ΄κ³ μμ΄ νμ¬ λ³΄μ¬μ§λ λ·°ν¬νΈ λμ΄λ₯Ό λμ μΌλ‘ κ°μ Έμ΅λλ€. μ€ν¬λ‘€ μ μ£Όμμ°½μ΄ μ¬λΌμ§λ λͺ¨λ°μΌ λΈλΌμ°μ μμλ (μ£Όλ‘Safari
μμ) λ¬Έμ μμ΄ νΉμ μμμ λμ΄λ₯Ό λΈλΌμ°μ μ νλ©΄ λμ΄μ λ§μΆ μ μμ΅λλ€.
Variable fonts
λ μ¬λ¬ κ°μ§ μ€νμΌκ³Ό λκ»μ μΆμ κ°μ§ λ¨μΌ ν°νΈ νμΌλ‘ ν°νΈμ μ€νμΌ, κ΅΅κΈ°, κΈ°μΈμ, λλΉ λ±μ μ μ°νκ² μ μ΄ν μ μμ΅λλ€.
@font-face { font-family: Indivisible; src: url('../fonts/IndivisibleVariable.f64f7f53.woff2') format('woff2'); font-weight: 100 1000; // 100λΆν° 1000κΉμ§ ν°νΈ κ΅΅κΈ°λ₯Ό μμ λ‘κ² μ‘°μ κ°λ₯ }
<h2 class="title"> <span>160λ </span> <span>μμ¬λ₯Ό</span> <span>μ§λ</span> <span>HUNTERλ</span> <span>ν΄λμν</span> <span>ν¨μ </span> <span>μμ΄ν μΌλ‘</span> <span>μ μΈκ³μ</span> <span>λ§μ</span> <span>μ΄λ€μ</span> <span>μ¬λμ</span> <span>λ°μ</span><span>μ€κ³ </span> <span>μμ΅λλ€.</span> <br><br> <span>ν€λ¦¬ν°μ§μ</span> <span>μΆ©μ€ν¨κ³Ό</span> <span>λμμ</span> <span>λμμλ</span> <span>λμμΈ</span> <span>νμ μ</span> <span>ν΅ν΄</span> <span>μ§ννκ³ </span> <span>μλ</span> <span>λΈλλ</span> <span>νν°λ₯Ό</span> <span>EQLμμ</span> <span>λ§λ보μΈμ.</span> </h2>
titleArr = $('.sc-hunter .group-hunter h2 span').toArray(); function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; }; }; shuffleArray(titleArr); ScrollTrigger.create({ trigger:'.sc-hunter', start: "0% 50%", onEnter:function(){ titleArr.forEach(function(el,i){ gsap.to(el,{ opacity: 1, duration: 1, delay: i * 0.12, }); }); }, });
λλ€ μ λλ©μ΄μ
μ μ μ©ν κΈμλ€μ λ°°μ΄λ‘ λ§λ€μ΄ λ³μ titleArr
μ μ μ₯νκΈ°
Fisher-Yates μκ³ λ¦¬μ¦μ κ·Όκ±°νμ¬ λ°°μ΄μ 무μμλ‘ λ§λλ ν¨μ shuffleArray
λ§λ€κΈ°
Fisher-Yates
μκ³ λ¦¬μ¦μ λ°°μ΄μ μμλ₯Ό μμμ μμλ‘ μλ λ° μ¬μ©λλ μκ³ λ¦¬μ¦μΌλ‘ κ° μΈλ±μ€μ κ·Έ μ΄νμ 무μμ μΈλ±μ€ μ€ νλλ₯Ό μ ννμ¬ λ μΈλ±μ€μ ν΄λΉνλ μμλ₯Ό κ΅νν©λλ€. μ΄λ₯Ό λ°°μ΄μ λκΉμ§ λ°λ³΅ν¨μΌλ‘μ¨ λ°°μ΄ μ 체λ₯Ό μμ μ μμ΅λλ€.function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { - λ°°μ΄μ λ§μ§λ§λΆν° μ²μκΉμ§ (i--) const j = Math.floor(Math.random() * (i + 1)); - Math.random ν¨μλ₯Ό μ¬μ©νμ¬ 0μμ iκΉμ§ 무μμμ μΈλ±μ€ μ ν [array[i], array[j]] = [array[j], array[i]]; - iλ²μ§Έ μμμ jλ²μ§Έ μμμ μμΉλ₯Ό λ°κΏ }; };
λ³μ titleArr
μ shuffleArray
ν¨μμ λ£κΈ°
ScrollTrigger
μ onEnter
ν¨μλ₯Ό μ¬μ©νμ¬ μλμ° 50%
μμΉμ νΈλ¦¬κ±° μμ μ§μ μ΄ λλ¬νμλ μ λλ©μ΄μ
μ΄ μ€νλ μ μλλ‘ λ§λ€κΈ°
titleArr
λ‘ forEach
λ°λ³΅λ¬Έ ν¨μ λ§λ€κΈ° (맀κ°λ³μ el
, i
)
gsap.to
λ₯Ό μ¬μ©νμ¬ κ° μ리먼νΈλ€μ delay
μ opacity
κ°μ μ£Όμ΄μ κ°κ° λλ μ΄λ₯Ό κ°μ§ μνλ‘ νλ©΄μ λ³΄μΌ μ μλλ‘ λ§λ€κΈ°
<section class="sc-openyy"> ... <svg class="shape-move" viewBox="" fill="currentColor" preserveAspectRatio="none" style=""> <rect x="0" y="0" width="75" height="504.5" class="shape-rect"></rect> <rect x="75" y="504.5" width="6" height="504.5" class="shape-rect"></rect> ... </svg> </section>
$('.sc-openyy').mousemove(function(e){ const mouseY = e.offsetY; const containerHeight = $(this).height(); const mouseY2 = containerHeight - e.offsetY; gsap.to('.sc-openyy .shape-move .shape-rect:nth-child(odd)',{ height: mouseY, duration: 0, }); gsap.to('.sc-openyy .shape-move .shape-rect:nth-child(even)',{ height: mouseY2, y:mouseY - 504.5, duration: 0, }); gsap.to('.sc-openyy .shape-move .shape-rect',{ width: 'random(1,90)', x: 'random(-90,90)', duration: 0.1, }); });
μ λλ©μ΄μ
μ νμ±ν ν 컨ν
μ΄λ .sc-openyy
μ mousemove
μ΄λ²€νΈ μΆκ°νκΈ° (맀κ°λ³μ e
)
λ§μ°μ€μ y
μ’νλ₯Ό λ³μ mouseY
μ μ μ₯
컨ν
μ΄λ .sc-openyy
μ λμ΄ κ°μ λ³μ containerHeight
μ μ μ₯
.sc-openyy
μ λμ΄ κ°μμ λ§μ°μ€μ y
μ’νλ₯Ό λΊ κ°μ λ³μ mouseY2
μ μ μ₯
svg
μμ μλ λ§λλ€μ :nth-child(odd)
νμ ν΄λμ€(μ λ§λλ€)μ gsap.to
λ₯Ό μ¬μ©νμ¬ mouseY
λ₯Ό λμ΄ κ°μΌλ‘ μ£ΌκΈ°
*λ§μ°μ€λ₯Ό yμΆ λ°©ν₯μΌλ‘ μμ§μΌ λ μ λ§λλ€μ΄ λ§μ°μ€ 컀μλ₯Ό λ°λΌμ€κ² λ©λλ€.
:nth-child(even)
μ§μ ν΄λμ€(μλ« λ§λλ€)μλ mouseY2
λ₯Ό λμ΄ κ°μΌλ‘ μ£ΌκΈ°
*mouseY2
λ μ 체 λμ΄μμ mouseY
μ¦ e.offsetY
λ₯Ό λΊ κ°μΌλ‘ λλ¨Έμ§ κ³΅κ°μ μ°¨μ§νκ² λ©λλ€.
mouseY
μμ 504.5
λ₯Ό λΊ κ°μ μ§μ ν΄λμ€μ y
κ°μΌλ‘ μ£Όμ΄ μ΄κΈ°ν μν€κΈ°
*504.5
λ μλ svg
μ μμλ y
κ°μ
λλ€.
gsap
μ λλ€ν¨μλ₯Ό μ¬μ©νμ¬ λ§μ°μ€λ₯Ό μμ§μΌ λ κ° λ§λμ width
μ x
μ’ν κ°μ λλ€νκ² μ£ΌκΈ°
*width
λ 1px
λΆν° 90px
κΉμ§, x
μ’ν κ°μ μλμ κ°μμ +-90