엔터프라이즈 블록체인 클론코딩

2025. 8. 24.공부/HTML,CSS

728x90

 

 

URL : https://developedbyssony.github.io/enterpriseBlockchain/

컨텐츠 영역에 섹션이 16개 들어갔으며, 중간에 div로 묶어준 section에 data-theme="dark"를 적용하였다. 또, .sc_service 섹션 같은 경우 인터랙션에 용이하기 위해 내부에 수직 컨텐츠와 수평 컨텐츠를 따로 묶어주었다. 클론을 하면서 GSAP을 활용한 스크롤 인터랙션을 구사하는 것에 중점을 두었다. 본 포스팅에서 스크롤 인터랙션 시나리오를 간단하게 정리하고자 한다.

 

일단 GSAP 활용하기 위해 CDN을 넣어야한다. 스크롤 인터랙션을 구현하기 위하여 스크롤 트리거용 CDN도 넣어준다.

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>

 

 

a. 인트로 구간

 

const motionIntro = gsap.timeline({
  scrollTrigger:{
    trigger: ".sc_intro",
    start: "top top",
    end: "+=7000",
    scrub: true,
    pin:true
  }
});

const introText = $(".sc_intro .intro_description .intro_description_text");

motionIntro.addLabel('a')
.to('.sc_intro .dimmed', {opacity:1 },'a')
.to(introText[0], { opacity: 1 },'a')
.to(introText[0], { opacity: 0 ,
  onStart:function(){
    $('.header').addClass('show');
  },
  onReverseComplete:function(){
    $('.header').removeClass('show');
  }
})
.to(introText[1], { opacity: 1 })
.to(introText[1], { opacity: 0 })
.to(introText[2], { opacity: 1 })
.to(introText[2], { opacity: 0 })
.to(introText[3], { opacity: 1 });

 

 

 

const showTitleArr = $(".showcase_intro_text");
const showImgArr = $(".showcase_img img");
const motionShowcase = gsap.timeline({
  scrollTrigger:{
    trigger: ".sc_showcase",
    start: "0% 0%", 
    end: "100% 100%",
    scrub: 0
  }
});
motionShowcase
.to('.sc_showcase .dimmed',{ autoAlpha:1 },'a') // 화면 dimmed
.to('.showcase_intro', { autoAlpha:1 },'a') // 해당 섹션 인트로 화면 투명도 100%

.to(showTitleArr[0], {xPercent:100 },'b') // 첫번째 텍스트 오른쪽으로 100% 이동
.to(showTitleArr[2], { xPercent:-100},'b') // 마지막 텍스트 왼쪽으로 100% 이동
.to('.sc_showcase .dimmed',{ autoAlpha:0 },'b') // dimmed된 화면 다시 밝게

.to('.showcase_intro', { autoAlpha:0},'c') // 해당 섹션 인트로 화면 투명도 0%
.to(showImgArr[2], { height:0},'c') // 해당 이미지 height 스크롤 내리며 0으로 줄어듬
.to(showImgArr[1], { height:0,'c'}) // 해당 이미지 height 스크롤 내리며 0으로 줄어듬

.to('.sc_showcase .dimmed',{ autoAlpha:1 },'d') // 화면 dimmed
.to('.showcase_description',{ autoAlpha:1 },'d') // 글자 투명도 100%

 

b. 흑백 전환 구간

data-theme="dark"라는 속성의 div 구간에 진입하면 body에 dark클래스가 자동 적용되어 전역적으로 다크 테마를 적용하게 하였다. 트리거 구간의 0%가 뷰포트의 55%에 도달하면 시작하고, 트리거의 100%가 뷰포트의 100%에 도달하면 끝난다.

ScrollTrigger.create({
  trigger: `[data-theme="dark"]`,
  start: "0% 55%",
  end: "100% 100%",
  toggleClass:{
    targets:"body",
    className:"dark",
  }
});

 

const possibility = gsap.timeline({
  scrollTrigger: {
    trigger: ".sc_possibility",
    start: "0% 0%",
    end: "100% 100%",
    scrub: 0,
    invalidateOnRefresh:true,
  },
});
possibility.to(".sc_possibility .slide_sub_wrap", {
  xPercent:-100,
  x:function(){
    return window.innerWidth-100;
  }
});

const feature = gsap.timeline({
  scrollTrigger: {
    trigger: ".sc_feature",
    start: "0% 95%",
    end: "100% 80%",
    scrub: 0
  },
});
feature.from('.sc_feature .col-left',{xPercent:-50},'a')
feature.from('.sc_feature .green',{xPercent:50},'a')


const feature2 = gsap.timeline({
  scrollTrigger: {
    trigger: ".sc_feature",
    start: "0% 45%",
    end: "100% 35%",
    scrub: 0,
    onEnter:function(){
      $('.sc_feature').addClass('blur')
    },
    onLeaveBack:function(){
      $('.sc_feature').removeClass('blur')
    }
  },
});
feature2.from('.sc_feature .feature_title',{autoAlpha:0})

 

c. .sc_service 구간

- .group_hr에서 카드들의 좌-> 우 순차적 이동

const service1 = gsap.timeline();
service1
.addLabel("a")
.to(".sc_service .group_hr .slide",{x:-515,duration:3},"a")
.addLabel("b")
.to('.sc_service .group_hr .slide',{
  x:function(){
    return $('.sc_service .slide_head .headline').outerWidth()*-1
  }})
.to(".sc_service .group_hr .card_item:nth-child(2)",{xPercent:-100,x:-40,duration:3},"b")
.to(".sc_service .group_hr .card_item:nth-child(3)",{xPercent:-200,x:-80,duration:3},"b")
.to(".sc_service .group_hr .card_item:nth-child(4)",{xPercent:-300,x:-120,duration:3},"b")

 

- .group_vt가 하단에서 위로 밀려오며 등장 + 카드 이동

 

.addLabel("c")
.from(".sc_service .group_vt",{autoAlpha:0},"c")
.from(".sc_service .group_vt",{yPercent:100,y:"-200",duration:8,ease:"none"},"c")
.from(".sc_service .group_vt .card_lock",{autoAlpha:0})
.addLabel("d")
.to(".sc_service .group_vt .card_item:nth-child(2)",{x:-445,duration:3},"d")
.to(".sc_service .group_vt .card_item:nth-child(3)",{x:-885,duration:3},"d")
.to(".sc_service .group_vt .card_item:nth-child(4)",{x:-1325,duration:3},"d")

 

 

- "누구든 무엇이든"(엔딩 텍스트) 등장

.addLabel("e")
.from(".sc_service .group_vt .end_txt_box",{autoAlpha:0,duration:3},"e")

 

d. 끊임없이 흐르는 띠배너 구간

 

@keyframes banner {
  from { transform: translateX(0); }
  to { transform: translateX(300%); }
}

.sc_banner .content_list {
  display: flex;
  margin-left:-705px ;
}

.sc_banner .content_list .content_item:nth-child(3n-1) {
  background: #0049ff;
}

.sc_banner .content_list .content_item:nth-child(3n-2) {
  background: #00bf41;
}

.sc_banner .content_list .content_item:nth-child(3n) {
  background: #e657af;
}

.sc_banner .content_list .content_item {
  position: relative;
  color: #fff;
  display: flex;
  font-size: 24px;
  width: 235px;
  height: 60px;
  justify-content: center;
  align-items: center;
  animation: banner 8s linear infinite running;
}

 

 

'공부 > HTML,CSS' 카테고리의 다른 글

셀세이프 클론 코딩  (0) 2025.08.23
웹 구축을 위한 최소한의 조건, 웹 접근성  (1) 2024.10.04
[Component] 간단한 헤더 만들기  (0) 2024.01.20
[HTML/CSS] 뷰포트 중앙정렬하기  (0) 2024.01.03
[HTML/CSS] em과 rem  (0) 2023.12.02