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

핑구·2023년 7월 27일
2

Portfolio

목록 보기
3/5

🎬 엔터프라이즈블록체인

👉 사이트명 : 엔터프라이즈블록체인
👉 작업기간 : 3일
👉 사용언어 : HTML5, CSS3, Jquery
👉 라이브러리 : GSAP
👉 분류 : PC 세미 반응형 웹사이트
👉 URL : https://seona-cha.github.io/enterprise


POINT ✨

✔️ 모션의 분석과 이해
✔️ GSAP + ScrollTrigger를 활용한 애니메이션 구현
✔️ Video Background로 사용
✔️ Top버튼 위치 변화
✔️ 한 방향으로 계속 흘러가는 텍스트 배너


구조 살펴보기 👀

🔍 전체 태그를 wrapper로 감싸주기

세미 반응형이지만 PC만 지원하도록 만들었기 때문에, 최소너비를 1300픽셀로 잡아주었다.
이때, 컨텐츠의 수평 스크롤영역 때문에 가로스크롤이 생길 위험을 낮추기 위해 overflow-x:hidden을 사용했는데, body와 wrapper에 둘다 각각 1300px의 min-width를 주고, wrapper에 overflow-x:hidden을 사용해서 화면이 1300px보다 작아서 넘치는 영역에만 스크롤이 생길 수 있도록 코딩했다.

.wrapper{
  min-width:1300px;
  overflow-x: hidden;
}
body{
  min-width:1300px;
}

🔍 시멘틱 태그를 활용해 영역 구성

🔍 각각의 section에는 h2태그로 제목 구성

🔍 클래스명에 통일성을 주어 직관적으로 구조를 파악할수있도록 구성

각 섹션 내부 수평으로 스크롤되는 영역은 'group-hori', 수직으로 스크롤되는 영역은 'group-scroll'로 구성하여 컨트롤해서 구조파악하기 용이하게 했다.

<section class="sc-data sc-card">
  <div class="group-hori">
  .
  .
  </div>
  <div class="group-scroll">
  .
  .
  </div>
</section>

🔍 article

section들을 모은 영역은 독립적으로 존재할수 있는 article 태그로 감쌀 수 있다.
엔터프라이즈블록체인 사이트를 클론코딩하면서 DATA ID 내용이 나열되는 영역은 'DATA ID'라는 공통 내용을 담은 독립적인 컨텐츠기 때문에 article로 구성했다.


📍 GSAP + ScrollTrigger

사이트의 모션 효과를 만들 위해 Greensock에서 만든 GSAP이라는 JS 라이브러리를 이용했다. 😎
GSAP의 플러그인인 ScrollTrigger를 함께 사용하여 스크롤을 이용해 애니메이션이 움직이고 멈추도록 만들었다.

👉 ScrollTrigger 사용법

① timeline 메서드를 이용해 스크롤시 동작할 애니메이션을 만들어준다.

기본적으로 나열된 순서에 따라 동작하지만, 동시에 동작하고 싶은 애니메이션은 addLabel을 이용해 Label을 선언하고, 중괄호 뒤에 붙여주면 같은 Label이 붙은 애니메이션은 동시에 동작하게 된다.
또 { 중괄호 안 } 의 duration, delay 속성을 활용하여 타이밍을 더 디테일하게 컨트롤할 수 있다.

const intro = gsap.timeline();
intro
  .addLabel('a')
  .to(".sc-intro .text-bg", {backgroundColor:"rgba(0,0,0,0.6)", duration: 100},'a')
  .from(".sc-intro .t01", {autoAlpha: 0, duration: 100},'a')
  .to(".sc-intro .t01", {autoAlpha: 0, duration: 100},"+=1")
  .from(".sc-intro .t02", {autoAlpha: 0, duration: 100}, "+=1")
  .to(".sc-intro .t02", {autoAlpha: 0, duration: 100},"+=1")
  .from(".sc-intro .t03", {autoAlpha: 0, duration: 100}, "+=1")
  .to(".sc-intro .t03", {autoAlpha: 0, duration: 100},"+=1")
  .from(".sc-intro .t04", {autoAlpha: 0, duration: 100}, "+=1")

② ScrollTrigger를 만들어 애니메이션을 적용한다.

ScrollTrigger.create({
  animation: intro,
  trigger: ".sc-intro",
  start: "top top",
  end: "+=7000",
  scrub: true,
  pin: true,
})

animation: 실행할 애니메이션의 이름
trigger: 어떤 요소를 기준으로 할지
start: 시작점 기준. "요소 / 창"
end: 끝점 기준. "요소 / 창" , "+=숫자" ("+=3000"이면 시작점에서 3000px이 스크롤 될때까지 동작)
pin:true: 애니메이션이 동작하는 동안에 영역이 화면에 고정
scrub:true: 스크롤이 중단되거나 뒤로 돌아갈때 애니메이션도 함께 정지되거나 역재생한다.

👉 ScrollTrigger을 이용한 Class 컨트롤

toggleClass 메서드를 이용해 간단하게 클래스를 on/off할 수도 있고,
'onEnter','onLeave', 'onEnterBack','onLeaveBack' 메서드를 이용하면 원하는 타이밍에 클래스를 on/off할 수도 있다.


// 1
ScrollTrigger.create({
  animation: intro,
  trigger: ".sc-intro",
  start: "top top",
  end: "+=7000",
  scrub: true,
  pin: true,
  markers: false,
  toggleClass:{
    targets:"#topBtn", className:"hide"
  }
})

// 2
ScrollTrigger.create({
  trigger:'body',
  start:"1000px 0%",
  end:"100% 100%",
  onEnter:function(){
    $('.header').addClass('fixed')
  },
  onLeaveBack:function(){
    $('.header').removeClass('fixed')
  }
})

📍 동영상을 Background로 사용할 때

position:absolute로 위치를 영역에 고정시키고, z-index를 이용하여 뒤로 보냈다.
비디오에 autoplay, loop도 줬는데 ..! 자동재생이 될때가 있고 안될때가 있음 💧
왜 그런지 찾아보니까 크롬에서 소리가 있는 동영상은 자동재생이 안된다고, 이럴땐 muted를 써줘야한다고 한다.

<video src="./videourl" autoplay loop muted></video>

📍 Visual 영역


처음엔 각각 영역을 잡고 Background를 주었는데 이미지 영역과 텍스트 영역을 따로 잡고 코딩하는 방법이 더 간단하다.

👉 MarkUp

이미지가 absolute로 붙어서 마지막 이미지부터 보일 것이기 때문에 역순으로 코딩한다.

<section class="sc-showcase">
  <h2 class="blind">비주얼영역</h2>
  <div class="group-visual">
    <figure class="img-box"><img src="./asset/images/img-showcase03-pc.jpg" alt></figure>
    <figure class="img-box"><img src="./asset/images/img-showcase02-pc.jpg" alt></figure>
    <figure class="img-box"><img src="./asset/images/img-showcase01-pc.jpg" alt></figure>
  </div>
  <div class="group-text">
    <div class="text-bg"></div>
    <p class="t01">기록하고</p>
    <p class="t02">증명하고</p>
    <p class="t03">성장하기</p>
  </div>
  <div class="desc">
    <div class="text-bg"></div>
    <p>
      엔터프라이즈블록체인은 블록체인 네트워크<br>
      DATA ID를 활용해 그 문제를 해결하고 새로운 방식을<br>
      제안하고자 합니다.
    </p>
  </div>
</section>

👉 CSS

이미지 영역과 텍스트 영역은 absolute로 붙여주고, 각 영역의 너비와 높이를 잡아준다.
포인트는 다른 영역의 높이는 100vh로 잡고, 이미지를 담는 div영역만 100%로 잡기 !
그리고 overflow:hidden;으로 height값이 잘리는 부분에서 넘치는 영역은 안보이게 한다.

.sc-showcase{ 
    position: relative; 
    width: 100%; height: 100vh; 
}
.sc-showcase .group-visual{
    position: absolute; 
    top: 0; left: 0;
    width: 100%; height: 100vh; 
}
.sc-showcase .group-visual .img-box{
    position: absolute; 
    top: 0; left: 0;
    z-index: -2;
    width: 100%; height: 100%; 
    overflow: hidden; 
}
.sc-showcase .group-visual img{
    width: 100%; height: 100vh;
    object-fit:cover;
}
.sc-showcase .group-text{
    position:absolute;
    top: 0; left: 0;
    width: 100%; height: 100vh;
    .
    .
}

.sc-showcase .desc{
    position:absolute;
    top: 0; left: 0;
    width: 100%; height: 100vh;
    .
    .
}

👉 Animation

이미지 넘어가는 타이밍이랑 텍스트 나타나고 사라지는 타이밍을 잘 배치해서 애니메이션을 만들어준다 .
이미지 넘어가는건 100%였던 height값을 0으로 바꿔서 구현함.

showcase
    .addLabel('a')
    .fromTo(".sc-showcase .group-text .text-bg", {backgroundColor:"rgba(0,0,0,0.0)"}, {backgroundColor:"rgba(0,0,0,0.6)",duration:20},"a")
    .from(".sc-showcase .group-text", {autoAlpha:0,duration:20},"a")
    

    .addLabel('b')
    .to(".sc-showcase .group-text .text-bg", {backgroundColor:"rgba(0,0,0,0.0)",duration:20},"b")
    .to(".sc-showcase .t01", {xPercent:100,duration:20},'b')
    .to(".sc-showcase .t03", {xPercent:-100,duration:20},'b')
    
    .addLabel('c')
    .to(".sc-showcase .t01", {autoAlpha:0,duration:20},'c')
    .to(".sc-showcase .t02", { autoAlpha:0,duration:20},'c')
    .to(".sc-showcase .t03", {autoAlpha:0,duration:20},'c')

    .to(".sc-showcase .img-box:nth-child(3)",{height:0,duration:20})
    
    .to(".sc-showcase .img-box:nth-child(2)",{height:0,duration:20})
    .to(".sc-showcase .desc .text-bg",{backgroundColor:"rgba(0,0,0,0.4)", duration:20},)
    .from(".sc-showcase .desc",{autoAlpha:0,duration:20})

📍 DATA 영역 모션 분석

.group-hori 영역이 수평으로 스크롤 됨, 마지막 카드는 고정
.group-scroll 영역이 수직으로 스크롤 됨
③ ②번이 진행되면서 카드 리스트2 의 첫번째 카드가 페이드인되면서 ①에서 고정된 카드를 덮음 (안보이게)
④ 나머지 카드가 스크롤되어 올라오고, ③에서 나타난 카드 뒤로 겹쳐짐

시간을 가장 많이 잡아먹은 부분이었다.. 😇
모션자체는 구현할만 했는데 화면 너비나 높이가 줄어들면 자꾸 위치가 바뀌어서 힘들었음.


📍 컨텐츠 너비에 유동적으로 반응하는 가로 스크롤


창 크기를 줄이거나 늘릴때도 가로 스크롤 컨텐츠의 끝점이 창 너비 끝점과 맞게 신경썼다.
컨텐츠 너비와 화면너비를 변수에 넣어서 연산해보거나 방법은 여러가지였지만 여러가지 시도를 해본끝에
가장 간단한 코드는 이거였다.

.to(".sc-economy .group-hori",{xPercent:-100,x:"100vw",duration:4},"a")

xPercent:-100: 컨텐츠의 너비만큼 왼쪽으로 밀어버린다
x:"100vw": 왼쪽으로 밀었던걸 화면너비만큼 다시 오른쪽으로 땡겨온다
이걸 동시에 실행하면 손쉽게 맞출수있다
이렇게 쉬운걸 헤매다니 .. 😶‍🌫️


📍 맨 아래에서 Top버튼 Position 변화.

Top버튼이 position:fixed로 항상 같은 영역에 붙어있다가 푸터까지 스크롤이 내려오면 fixed 속성이 사라진다. 이 부분은 ScrollTrigger와 클래스 컨트롤로 쉽게 구현할 수 있다.

#topBtn a{
    position: fixed;
    bottom: 40px; right: 100px;
    .
    .
}
#topBtn a.fixed{
    position: absolute;
    right: 100px; bottom:100px;
}
ScrollTrigger.create({
    trigger: ".footer",
    start: "0% 100%",
    end: "110% 100%",
    scrub: true,
    onEnter:function(){
        $('#topBtn a').addClass('fixed');
    },
    onLeaveBack:function(){
        $('#topBtn a').removeClass('fixed');
    }
});

📍 한 방향으로 계속 흘러가는 텍스트 배너


한 방향으로 끝없이 흘러가는 배너는 keyframe을 활용해서 구현해주었다.
무한으로 텍스트가 나오는것처럼 보이지만 사실 트릭이다. 한 블럭 가면 다시 되돌아오는 구조로 만들면 됨.

<section class="sc-banner02">
  <h2 class="blind">Join us</h2>
  <div class="banner-overflow">
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
    <span>JOIN <i>us</i></span>
  </div>
</section>
.banner-overflow {
    display: flex;
    margin-left:-705px ;
  }
  .sc-banner02 span{
    width: 235px;
    height: 60px;
    animation: banner02 8s linear infinite running;
    padding: 0;
    margin: 0;
}
@keyframes banner02 {
  from { transform: translateX(0); }
  to { transform: translateX(300%); }
}
profile
배운것은 그날그날 잊지않고 기록하기

1개의 댓글

comment-user-thumbnail
2023년 7월 27일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기