Design URBAN—ART

종근·2024년 7월 24일
0
post-thumbnail

URBAN—ART

사이트명 : 엔터프라이즈 블록체인
사용언어 : HTML, CSS, Jquery(GSAP)


POINT

  • 가로 스크롤
  • matchMedia 사용
  • 가로 스크롤 될때 따로 실행하는 트리거
  • ScrollToPlugin 사용

Intro

<div class="sticky">
	<div class="area1">
    이미지, ALWAYS 영역
    </div>
    
    <div class="area2">
    갤러리 영역
    </div>
</div>

ALWAYS의 영역의 애니메이션을 위해 두 개의 영역으로 잡았으며, 마지막의 이미지와 텍스트 리스트 부분은 Y 값을 위로 올려서 스크롤이 되게 만들었다.

  const groupSlide = gsap
    .timeline({
      scrollTrigger: {
        trigger: ".sc-intro .group-slide",
        start: "0% 0%",
        end: "100% 100%",
        scrub: 0,
        //   markers: true,
        invalidateOnRefresh: true,
      },
    })
    .to(
      ".sc-intro .content-wrap",
      {
        x: function () {
          return -$(".sc-intro .area1").outerWidth() + window.innerWidth;
        },
      },
      "bg"
    )

이전처럼 xPercent : -100% 안한 이유는 ALWAYS 영역의 애니메이션을 처리하기 위해 area1의 넓이 값 만큼 X값을 움직인 뒤 페이지의 넓이 만큼 동시에 움직여서 정확하게 가운데로 올 수 있게 만들었다.

  gsap.to(".wander-img figure", {
    xPercent: -250,
    scrollTrigger: {
      trigger: ".sc-intro .group-slide .wander-img",
      containerAnimation: groupSlide,
      start: "left 100%",
      end: "left 0%",
      scrub: 0,
    },
  });

중간의 이미지가 움직이는 애니메이션을 넣기 위해 containerAnimation 속성을 사용해서 애니메이션을 넣어줬다. 사용법은 간단하게 애니메이션을 같이 진행시킬 영역의 타임라인 변수를 지정해주면 된다.

트리거의 위치를 left, right를 줘서 트리거를 가로로 줄 수 있으며 그때 동안 실행시킬 애니메이션을 Gsap의 to로 지정하였다

  • containerAnimation : 애니메이션을 적용할 영역을 지정하여 애니메이션을 같이 진행

텍스트 애니메이션


텍스트가 위로 올라오는 애니메이션은 여러군데 사용해서 html의 data-effect="y-move"를 지정하여 Gsap set으로 설정해주었다.

gsap.set(`[data-effect="fade"]`, { opacity: 0 });
gsap.set(`[data-effect="x-move"]`, { xPercent: 100 });
gsap.set(`[data-effect="y-move"]`, { yPercent: 100 });
 gsap.to('.sc-order .group-call [data-effect="y-move"]', {
    scrollTrigger: {
      trigger: ".sc-order .title-area",
      start: "0% 80%",
      end: "100% 80%",
      scrub: 0,
      // markers: true,
    },
    yPercent: 0,
    stagger: 0.01,
  });

반복문으로 타임라인을 써서 애니메이션을 줄 수도 있지만 stagger란 속성을 사용해서 간단하게 애니메이션을 설정하였다.


텍스트 분리

html에서 텍스트를 분리하는게 아닌 JS에서 텍스트를 분리할 수 있게 하는 split 사용하여 텍스트를 분리했다.

const visualText1 = new SplitType(".sc-intro .sub-title-area", {
  types: "words, chars",
});

문장, 단어로 텍스트를 분리할 수 있다.


사이드 바

인테리어 영역을 클릭하면 사이드바가 열리도록 만들었다.

$(".sc-interior .group-interior .interior-item").click(function () {
  const room = $(this).data("room");

  if (room == "bed-room") {
    $(`[data-room="bed-room"]`).css("display", "block");
  } else if (room == "scand-room") {
    $(`[data-room="scand-room"]`).css("display", "block");
  } else {
    $(`[data-room="eco-room"]`).css("display", "block");
  }

  $(".interior-side").toggleClass("active");
  $("body").toggleClass("active");

  setTimeout(() => {
    $(".interior-side .group-side").toggleClass("active");
  }, 300);
});

인테리어 영역의 data를 가지고 와서 각 data에 맞는 영역을 보이게 했다
사이드바 영역이 아닌 곳을 클릭하면 닫히게 끔 만들었다

$(document).click(function (e) {
  if (
    !$(
      ".interior-side .group-side, .sc-interior .group-interior .interior-box .interior-item").has(e.target).length) {
    $(".interior-side .group-side").removeClass("active");
    setTimeout(() => {
      $(".interior-side").removeClass("active");
      $("body").removeClass("active");
      $(`.interior-side [data-room*="room"]`).css("display", "none");
    }, 1200);
  }
});

클립패스


배경 이미지의 영역, 고정되어 움직이는 텍스트, 이미지 영역으로 2개의 영역으로 나누었다

<div class="sticky">
	텍스트, 이미지
</div>

<div>
	배경 이미지
</div>

배경 이미지의 부분은 margin-top 조절해서 sticky 영역과 같이 보여지게 하였다
영역이 사라지는 부분을 처음엔 height 값을 조절했지만 텍스트 부분이 겹쳐보여 height값으로는 안되서 클립패스를 사용했다.

clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
//보이는 코드

첫 번째 영역 빼고 전부 안보이게 한 다음 Gsap으로 애니메이션을 만들었다

clip-path: polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%);
//안보이는 코드
interiorList = gsap.timeline({
  scrollTrigger: {
    trigger: '.bg-area',
    start: "0% 0%",
    end: "100% 100%",
    scrub: 0,
  },
})
interiorList.to('.sc-order-interior .group-interior .area1', {
  "clip-path": "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)"
}, 'a');
interiorList.to('.sc-order-interior .group-interior .area2', {
  "clip-path": "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"
}, 'a');
interiorList.to('.sc-order-interior .group-interior .area2', {
  "clip-path": "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)"
}, 'b');
interiorList.to('.sc-order-interior .group-interior .area3', {
  "clip-path": "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)"
}, 'b');

area1, area2 의 클립패스를 조절해서 1번은 안보이게 만들고 2번은 보여지게 만드는걸 동시에 진행되도록 했다 area2, area3 똑같이 만들었다.


마우스 따라 움직이는 영역

$(".sc-visual, #footer").mousemove(function (e) {
  const x = (20 * e.clientX) / $(".sc-visual").width();
  const y = (10 * e.clientY) / $(".sc-visual").height();
  
  gsap.to(".sc-visaul .img-box",{x:x,y:y})
});

뷰포트 내 좌표를 가지고 온 뒤, 너무 많이 움직일 필요는 없어 영역의 크기로 나누어 x값을 조절했다


matchMedia 사용

반응형 처리를 위해 Gsap의 matchMedia 사용했다. 사용법은 Css의 미디어 쿼리 처럼 사용할 수 있어 간단하게 사용하였다.

let mm = gsap.matchMedia();
mm.add("(min-width: 1000px)", () => {}

이런식으로 사용해서 특정 크기에서만 사용할 수 있는 애니메이션을 넣어서 반응형 처리를 쉽게 할 수 있다.


lenis 사용

부드러운 스크롤을 위해 lenis 사용하였다.

lenis.on("scroll", ScrollTrigger.update);

gsap.ticker.add((time) => {
  lenis.raf(time * 800);
});

gsap.ticker.lagSmoothing(0);

Gsap용으로도 사용할 수 있게 되어 있어 간단하게 가능하며,
스크롤의 부드러움 값을 정하는 부분은 time 값을 조절해가면서 사용 할 수 있다


ScrollToPlugin

각 버튼을 누르면 각각의 영역으로 이동하는 애니메이션을 만들었다

$("#header .gnb-item").each(function (index) {
  const targetIndex = index;

  $(this).click(function () {
    gsap.to(window, {
      duration: 0.7,
      scrollTo: { y: `#sc${targetIndex + 1}` },
    });

    $("#header .gnb").removeClass("active");
    $("#header .menu-btn span.close").removeClass("active");
    $("#header .menu-btn span.open").removeClass("remove");
  });
});

각각의 세션마다 id값을 sc1, sc2... 정하고 반복문을 돌려서 각 영역의 y값으로 움직일수 있도록 만들었다

0개의 댓글