엔터프라이즈 블록체인

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

Enterprise Blockchain

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


POINT

  • 모션에 따른 구조의 이해
  • GSAP, ScrollTrigger 사용
  • GSAP의 다양한 메소드, 이벤트 핸들러 사용

Sticky

화면에 요소를 고정시킬 때, GSAP의 Pin 기능을 사용할 수도 있지만, Pin 기능을 사용하면 레이아웃이 이상해질 수 있고, position : fixed의 기능은 position: sticky로도 대체가 가능해 sticky를 사용하였다.


Intro

<section>
	<div class="content-wrap">
		화면에 고정시켜서 보여줄 내용
	</div>
</section>

position: sticky 속성을 사용하여 .content-wrap 요소가 스크롤 시 화면에 고정되도록 설정 하였다. 충분히 스크롤이 가능하도록 부모 요소에 높이 값을 지정

section {
	height: 600vh
}

.content-wrap {
    width: 100%;
    height: 100vh;
    position: sticky;
    top: 0;
}

GSAP과 ScrollTrigger를 활용하여 인트로 글자가 변경될 때 헤더 부분의 클래스를 제어하기 위해 이벤트 핸들러를 사용

const intro = gsap
  .timeline({
    scrollTrigger: {
      trigger: ".sc-intro",
      start: "0% 0%",
      end: "100% 100%",
      scrub: 0,
    },
  })
  .to(".sc-intro .intro-description", { background: "rgba(0,0,0,.7)" }, "bg")
  .to(".sc-intro .desc-text1", { opacity: 1 }, "bg")
  .to(".sc-intro .desc-text1", {
    opacity: 0,
    onStart: function () {
      $("#header").addClass("active");
    },
    onReverseComplete: function () {
      $("#header").removeClass("active");
    },
  })
  • onStart : .sc-intro .desc-text1 요소의 opacity가 0으로 변할 때, 호출되어 #header에 active 클래스를 추가
  • onReverseComplete : 스크롤을 위로 올려서 애니메이션이 역방향으로 완료될 때 호출되어 #header의 active 클래스를 제거
  • label : 애니메이션의 지점을 label 사용해 애니메이션을의 시작점을 정하였다
    (.to("",{},"bg") : 라벨 이름이 같으면 같이 실행, bg+=5 or bg-=5 : X초뒤 시작 X초 먼저 시작)
  • timeline : 애니메이션을 순차적으로 실행시킬 수 있는 메소드

Slogan

슬로건의 배경이미지, 텍스트 부분들은 따로 따로 만들어 position: absolute;로 위치값을 조정

<section>
	<div>
		슬로건 배경 이미지
	</div>
    
	<div>
		슬로건 텍스트
	</div>

	<div>
		슬로건 텍스트
	</div>
</section>

이렇게 구조를 잡았으며, absolute을 사용해서 각 요소의 z-index를 조절 할 수도 있지만 이미지를 역순으로 배치 하였다.

const slogan = gsap
  .timeline({
    scrollTrigger: {
      trigger: ".sc-slogan",
      start: "0% 0%",
      end: "100% 100%",
      scrub: 0,
      // markers: true,
    },
  })
  .to(".slogan-text-box", { background: "rgba(0,0,0,.7)" }, "bg")
  .to(".slogan-title", { opacity: 1 }, "bg")

  .to(".slogan-text1", { xPercent: 100 }, "text")
  .to(".slogan-text2", { xPercent: -100 }, "text")

  .to(".slogan-text-box", { background: "rgba(0,0,0,0)" }, "text")
  .to(".slogan-title", { opacity: 0 })
  .to(".bg-img1", { height: 0 })
  .to(".bg-img2", { height: 0 })

  .to(".slogan-description-text", { opacity: 1 }, "bg-end")
  .to(".slogan-text-box", { background: "rgba(0,0,0,.4)" }, "bg-end");

이미지들의 높이값을 0으로 줄 때 img의 높이 값을 없애는게 아닌 이미지의 높이는 100vh로 고정시키고 부모의 높이값을 조절했다


색상 변경

const business = ScrollTrigger.create({
  trigger: ".sc-business",
  start: "0% 10%",
  end: "100% 100%",
  scrub: 0,
  onEnter: function () {
    $("#header").addClass("dark");
    $(".lang-list").addClass("white");
  },
  onLeaveBack: function () {
    $("#header").removeClass("dark");
    $(".lang-list").removeClass("white");
  },
});

const dark = ScrollTrigger.create({
  trigger: '[data-theme="dark"]',
  start: "0% 50%",
  end: "100% 20%",
  scrub: 0,
  toggleClass: {
    targets: "body",
    className: "dark",
  },
  onEnter: function () {
    $("#header").removeClass("dark");
    $(".lang-list").removeClass("white");
  },
  onLeaveBack: function () {
    $("#header").addClass("dark");
    $(".lang-list").addClass("white");
  },
});

중간의 header와 body의 색상을 변경하기 위해 GSAP으로 조절 하였다


가로 스크롤

스크롤 될때마다 요소의 x값을 계속 밀어주기 위해 두개의 요소를 감싸는 div를 만들었다.

<div class="sticky">
	<div class="group">
		<div>
    		첫번째 요소
    	</div>
    
    	<div>
    		두번째 요소
    	</div>
    </div>
</div>

group의 정확한 width값을 알기 위해 max-content란 속성을 사용하였다. 부모가 display:flex면 사용할 필요는 없지만, 사용을 안한 경우엔 max-content란 속성을 활용하여 width값을 정확히 알 수 있다.

.group {
    width: max-content;
    height: 100%;
    display: flex;
    align-items: center;
}

요소의 x값을 미는건 생각보다 간단하게 밀 수 있다

const dataInfo = gsap
  .timeline({
    scrollTrigger: {
      trigger: ".sc-data-info",
      start: "0% 0%",
      end: "100% 100%",
      scrub: 0,
      // markers: true,
      invalidateOnRefresh: true,
    },
  })
  .to(".group", {
    xPercent: -100,
    x: function () {
      return window.innerWidth;
    },
  });

지금의 레이아웃 경우는 두 번째의 요소가 width:100vw 값으로 화면에 꽉차게 보여지고 있으며, 감싸고 있는 부모의 요소를 xPercent:100을 사용해 x축을 -100% 만큼 이동 시킨 뒤 window.innerWidth 값 만큼 x축으로 동시에 이동 시킨다.

  • x축 -100% 이동
  • x축 현재 화면의 크기 만큼 이동
  • xPercent: -100에서 window.innerWidth를 더한 값만큼 이동했을때 마지막 내용이 x축기준으로 정 가운데에 위치

그리고 x축의 값을 이동 시킬 때 브라우저 크기에 맞게 보여지게 하기 위해 invalidateOnRefresh: true 사용 (윈도우 리사이징 할 때 새로고침 할수 있도록)
return 함수를 써서 윈도우 리사이징 할 때도 새로고침 할 수 있게 만들었다.


DATA 영역

총 세개의 영억으로 잡아주었다.

  • 첫 DATA영역의 카드를 합치기
  • 합쳐진 뒤 올라오는 영역
  • 마지막에 카드를 다시 합치는 영역
<div class="content1">
	<div class="sticky-wrap">
		<div class="sticky">
	    	카드 영역
	    </div>
    </div>
</div>

<div class="content2">
	<div>
    위로 올라오는 텍스트 영역
    </div>
</div>

<div class="content3">
	<div class="sticky">
    	카드 영역
    </div>
</div>

마크업은 이런식으로 잡은 뒤 하나의 영역으로 보여지게 하기 위해서 content의 높이 값 보다 sticky-wrap 높이 값을 더 많이 줘서 실제 영역보다 더 많이 스크롤을 고정 시키고 두 번째의 요소는 margin-top 값을 조정하여 하나의 영역으로 이어지게 해주었다.

제일 중요한 카드 부분은 content 영역 마다 미리 만들어서 content 영역이 스크롤 될 때 바꿀 수 있게 하였다.

	onEnter: function () {
        gsap.set(".sc-service .area2 .card-area .card", { opacity: 0 });
        gsap.set(".sc-service .area3 .card-list-item.card-lock", {
          opacity: 1,
        });
      },
      onLeaveBack: function () {
        gsap.set(".sc-service .area2 .card-area .card", { opacity: 1 });
        gsap.set(".sc-service .area3 .card-list-item.card-lock", {
          opacity: 0,
        });
      },

onEnter와 onLeaveBack 으로 실행 시켜 set으로 속성 상태를 변경한다

  • set : 초기값 세팅
  • onEnter : 트리거가 도달했을때 실행
  • onLeaveBack : 반대 방향으로 스크롤 해서 트리거가 도달 했을때 실행

Top 버튼

스크롤을 내렸을 땐 버튼이 안보이다가 다시 올릴땐 보이게 만들었다.

ScrollTrigger.create({
  trigger: ".sc-slogan",
  start: "0% 0%",
  end: "100% 100%",
  endTrigger: "#footer",
  onUpdate: function (self) {
    direction = self.direction;
    if (direction == 1) {
      $(".top-btn").removeClass("active");
    } else {
      $(".top-btn").addClass("active");
    }
  },
  onLeaveBack: function () {
    $(".top-btn").removeClass("active");
  },
});

endTrigger를 사용하여 슬로건의 영역부터 푸터의 영역까지 스크롤 트리거를 잡아주었다. onUpdate란 메소드를 사용하여 direction란 속성은 스크롤이 내려가면 1 올라가면 -1의 값을 출력하는데 if문을 통해서 Top 버튼의 숨김 처리를 하였다.

버튼을 눌렀을때 스크롤 이동은 Gsap의 ScrollToPlugin 사용하여 간단하게 만들었다.

$(".top-btn").click(function () {
  gsap.to(window, { duration: 1, scrollTo: 0 });
});

0개의 댓글