[Web Project] LINE Renewal Project

yenaryu·2022년 9월 16일
0

Web

목록 보기
23/24

🍀 LINE 리뉴얼 프로젝트

LINE Renewal

라인 주식회사(LINE Corporation)는 커뮤니케이션 앱 라인(LINE)을 기반으로 커뮤니케이션, 콘텐츠, 엔터테인먼트, 광고 사업 등 모바일에 특화된 서비스를 개발 및 운영하고 있습니다. 이외에도, 핀테크와 AI 사업 등 다양한 분야로 진출하고 있습니다. 라인은 자사 미션인 ‘클로징 더 디스턴스(Closing the Distance)’를 바탕으로 전 세계를 대상으로 라인 서비스를 전개하고 있습니다.

💡Renewal

🔸BEFORE

  1. 라인 대표 홈페이지 (linepluscorp.com) 기준 회사에 대한 철학이 가장 강조되어 있고, 서비스에 대한 정보 및 라인이라는 회사의 트렌디한 아이덴티티가 부족하다고 생각됨
  2. 자료전달은 잘 되지만 이미지와 효과요소가 부족해 단조로움.
  3. 라인의 트레이드 마크인 초록색 보다는, 흰-검을 주로 사용하여 (개인적으로) 아쉬움을 느낌
  4. 반응형으로 구성하긴 했으나, 모바일에 최적화되어있지 않아 폰트 및 배치가 투박하게 구성되어있음.

🔸AFTER

  1. 라인의 슬로건을 내세워, 가상의 라인 홈페이지를 제작
  2. 라인이라는 서비스의 실적과 현재 진행하는 서비스에 대해 직관적으로 보여주고자 함.
  3. 기본적으로 회사의 홈페이지이기 때문에 깔끔함을 가장 우선순위로 삼았지만, 트렌디함을 살리기 위해 디자인적 요소를 충분히 사용하며 효과-기본-효과-기본을 적절히 섞어서 구성
  4. 초록색이라는 라인 고유의 아이덴티티를 살리되 채도 높은 색상이기 때문에, 포인트요소로 사용하여 너무 정신없지 않도록 구성
  5. 반응형으로 큰화면부터 태블릿, 웹모바일, 모바일휴대폰까지 모든 반응형을 세심하게 구성

🔸WIREFRAME

▪️ header + main

라인의 슬로건을 메인 화면에 배치하며, 'LINE'이라는 서비스의 색깔을 잘 보여줄 수 있는 영상을 loop로 반복재생함. (동영상은 라인의 홈페이지를 참고하여 직접 편집하여 사용함) 메뉴 네비게이션과 메뉴를 함께 배치하여 사용자가 원하는 서비스를 사용할 수 있도록 배치함

▪️ menu

큰 구성은 회사 / 서비스 / 보도자료 / 채용으로 기존의 라인 메뉴 구성과 유사하게 배치함. 왼쪽에는 회사에 대한 기본 정보 및 언어 전환 (영문 버전은 클릭시 준비중입니다. 라는 알림창), sns로 간결한 배치

▪️ LIFE ON LINE (effect01)

라인의 대표 슬로건인 'LIFE ON LINE'을 메인 화면 다음에 배치하여, 스크롤에 따라 글자가 움직이도록 gsap효과 부여. 기존 라인의 웹페이지와 다르게 효과를 중심으로 it기업의 트렌디한 느낌을 강조하고자 함

▪️ result

라인이라는 기업 및 서비스가 이뤄낸 성과를 강조하여, 지금까지 걸어온 길들을 사용자가 한 눈에 볼 수 있게 구성함. 스크롤에 따라 배치된 방향에서 등장하는 감각적인 효과를 부여함

▪️ service

라인이 대표적으로 제공하는 서비스를 보여줌. 서비스를 보여주는 부분은 되도록 깔끔하고 직관적으로 볼 수 있게 가장 베이직한 구성을 선택함. 이미지와 버튼에 hover을 부여해 너무 단조롭지않게 구성함

▪️ LINER INTERVIEW (effect02)

현재(2022.09 기준) 하반기 신입 공개채용을 가장 큰 이벤트로 하고 있기 때문에, 라인 재직자들의 인터뷰를 구성해 각 직군의 종사자들의 인터뷰를 제공하고자 함. effect01과 같이 스크롤시 글자가 움직이도록 하며, 인터뷰 박스가 스크롤에 맞춰 나오는 효과를 위주로 구성함. 각각 인터뷰 hover시 해당 인터뷰이의 사진이 보여지도록 함.

▪️ news

라인의 최신 동향을 알 수 있는 뉴스 페이지를 가장 하단에 구성하여, 가장 기본적인 swiper형식으로 카드뉴스와 같이 구성함. hover시 padding으로 색상을 부여해 너무 단조롭지 않게 구성.


🔸파일 구조/명

  • index.html : 마크업
  • asset
    1) css : watch sass -> css
    2) font : 사용 폰트
    3) image : 사용 이미지
    4) js
    • main.js
      5) scss :
    • abstracts
      • _mixins.scss : 미디어쿼리/말줄임
    • base
      • _preset.scss : common
      • _reset.scss : reset
      • _typo.scss : font
    • layout
      • _footer.scss : footer
      • _header.scss : header
    • pages
      • _index.scss : main
    • vender
      • _swiper.scss : swiper 링크
    • style.scss : @import


🍀 개념

🔹 반응형 웹페이지

🔸clamp(최소, 선호, 최대)

clamp()는 최소/최대 값 범위 사이의 값을 표현할 수 있는 경우 사용
선호값은 기본값으로 vw로 작성한다.
ex) fontsize : clamp(35px, 6vw,100px)

🧐 vw로 작성하는 이유?
상대값이기 때문에, px와 같은 절대 단위를 사용하면 clamp함수 기능을 할 수 없다.
최소보다는 작아질 수 없고, max보다는 커질 수 없는 가변값이다.
🧐 vw값을 구하는 방법?
vw계산기를 사용한다.


🔸미디어쿼리

scss에서 미디어쿼리를 사용할 때, mixin을 사용하여 코드를 정리하면 편하게 사용 가능하다

/*반응형 화면 크기 변수 설정*/
$mobile: 767px; //320
$tablet: 1023px; // 768
$desktop: 1200px; //1024

/*반응형, 브라우저 크기가 767px 이하일때*/
@mixin mobile{
  @media (max-width: $mobile){
    @content;
  }
}

/*반응형, 브라우저 크기가 768이상, 1023px 이하일때*/
@mixin tablet{
  @media (max-width: $tablet){
    @content;
  }
}

/*반응형, 브라우저 크기가 1024px 이상일때*/
@mixin desktop{
  @media (max-width: $desktop){
    @content;
  }
}

🧐 Mixin이란?

‘믹스인’은 재사용 가능한 기능을 만드는 방식을 의미한다.

  • 선언하기 : @mixin
  • 사용하기 : @include

🔹scss

🔸폴더 의미

📁abstract
실제 스타일은 없고, 그저 다른 폴더에 정의된 스타일을 돕는 역할
글로벌 변수, 함수는 _variables 파일 / mixins은 _mixins에 작성

📁base
사이트 전반에 걸쳐서 재사용되는 스타일 정의
사이트 전반에 사용될 폰트, 디폴트 스타일 등

📁components
사이트 내에서 재사용가능한 작은 부분들을 정의
layout과 유사하지만, 작은 요소들을 정의한다는 것에서 차이점이 있음
buttons, forms 등 겹치는 요소

📁layout
사이트 구조에 해당하는 레이아웃 정의
headers, footers 등

📁pages
각 페이지에서 사용될 구체적인 스타일
main 페이지 등

🖇️style.scss
폴더에 따라 분류한 scss파일들을 한 군데에 모을 hub 역할
모든 파일을 import해준다.
import만 담당하는 폴더이기 때문에 다른 파일들과 달리 _을 하지 않아야 한다.


🔸중첩

상위 선택자의 반복을 피하고 좀 더 편리하게 복잡한 구조를 작성 가능

.sc-main {
  width: 100%;
  .main-list {
    display : flex;
    .main-item {
      margin : 10px;
    }
  }
}

🔸부모 선택자 참조

&을 사용하여, 부모 선택자를 참조할 수 있음

.btn-nav {
  position: absolute;
  &.active {
    color: #fff;
  }
}

이는 btn-nav.active와 같다.



🍀 코드분석

🔹loading

🔸css로 배경+로고 위치 설정

.loading{
    position: fixed;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: #06c755;
    z-index: 500;
    .load-img{
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        overflow: hidden;
        img{width: 250px;}
    }
}
  • 로딩 화면 position fixed, w100 h100으로 전체 화면 조성
  • 로고 이미지는 poa를 사용하여, 가운데 정렬

🔸js로 효과 시간 조정 (연결)

gsap.to('.loading',{
  delay:1.2,
  opacity:0,
  display:'none',
  height:0,
  onComplete:function(){
    intro.play()
  }
})

로딩 전체화면에 delay:1.2를 부여해, 1.2초동안 로딩화면 재생
숨겼다가->재생도되록

gsap.to('.loading img',{
  delay:0.8,
  opacity:0,
  onComplete:function(){
    intro.play()
  }
})

라인 아이콘은 0.8초동안 재생되도록 보였다가->안보이게

mainTxt = gsap.timeline({})
const intro = gsap.fromTo('.sc-main .title-area .word',{
  yPercent:100,
  opacity:0
},{
  yPercent:0, 
  stagger:0.5,
  opacity:1,
  paused:true
})

로딩화면이 끝난 후, 메인이미지의 텍스트 효과 부여하기
로딩이 끝날 때 까지 멈췄다가, 0->1로 보여지면서 아래에서 위로 올라오는 효과


🔹header menu

🔸메뉴 이동시 헤더 고정

$('.btn-menu').click(function(e){ 
    e.preventDefault(); 
    
    if($(this).hasClass('active')){
      $('body, .group-menu, .btn-menu').removeClass('active'); 
      $(this).find('.blind').text('메뉴열림');
    }else{
      $('body, .group-menu, .btn-menu').addClass('active'); 
      $(this).find('.blind').text('메뉴닫힘')
    }
  });

btn-menu 메뉴를 클릭했을 때,

  • if active가 존재한다면 (열려있으면)
    • body에 active 제거 (oh)
    • group-menu op1 visi 제거 (숨겨짐)
    • btn-menu 닫힘버튼으로 변경
    • blind 텍스트 메뉴열림으로 변경
  • else 존재하지 않는다면 (닫혀있으면)
    • body에 active (oh x) +
    • group-menu op1 vi1 보여짐
    • btn-menu 열림버튼으로 변경
    • blind 텍스트는 메뉴닫힘으로 변경

🔸스크롤 메뉴

  var FirstScroll = 0;
  var prevScrollTop = $(window).scrollTop(),
    curr = $(window).scrollTop(); //브라우저 스크롤했을때 위치
 
  $(window).scroll(function(e){
    e.preventDefault();
    curr = $(this).scrollTop(); //= window scrollTop
//반대스크롤시 보이게
    if ( curr < prevScrollTop ){ //반대스크롤하면
      $(".group-header").addClass('active'); //메뉴보여짐
      $(".group-header").removeClass('hide'); //헤더숨김

      if(curr >= 100){ //+curr이 100보다 크거나 같다면
        $('.group-header').addClass('active'); //메뉴보이게
      }else{
        $('.group-header').removeClass('active'); //아니라면 메뉴 안보이게
      }
//스크롤시 사라지게
    } else if( curr > prevScrollTop ) { //스크롤탑위치에서 스크롤해서 내려가면
      $(".group-header").removeClass('active'); //메뉴도 없애면서
      $(".group-header").addClass('hide'); //헤더 숨김
    }
    prevScrollTop = curr;
  });

🔸메뉴 열릴 때 동그라미가 퍼지는 효과

&::before{ 
    content: '';
    width: 100px; height: 100px;
    position: absolute;
    top: 0;right: 0;
    background: #06c755;
    transform: scale(0);
    border-radius: 50%;
    transition: 1s;
}

&.active{visibility: visible;
opacity: 1;
    &::before{
        transform: scale(50);
    }
} 

group-menu에 before을 만들어, 검은 동그라미 생성
scale을 0으로 한 뒤, active가 되었을 때 함께 transform scale50으로 동그랗게 퍼져가는 모양 생성
group-menu의 텍스트들보다 z-index가 낮아야 함


🔹result

🔸html에 data수치 삽입

<li class="result-item" data-x ="-20"> 
    <p class="sort">월간 이용자 수</p>
    <div class="img-area">
        <em class="num">2억명</em>
        <div class="img-box">
            <img src="./assets/image/result1.jpg" alt="월간 이용자 수">
        </div>
    </div>
</li>
<li class="result-item right" data-x ="20">
    <p class="sort">다운로드 수</p>
    <div class="img-area">
        <div class="img-box">
            <img src="./assets/image/result2.jpg" alt="다운로드 수">
        </div>
        <em class="num point">5억회</em>
    </div>
</li> 

x축 기준으로 오른쪽, 왼쪽에서 li들이 나올 수 있게 구성할 것이기 때문에
data-x를 음수 양수 번갈아서 배치함
데이터 수치를 넣어놔야 컨트롤이 가능함.

🔸js로 변수 생성

const result = document.querySelectorAll('.sc-result .result-item');
result.forEach(el=>{

  xVal = (el.dataset.x) ? el.dataset.x : 0;

    gsap.from(el,{
        scrollTrigger:{
            trigger:el,
            start:"0% 50%",
            end:"top bottom",
            scrub:2,
        },
        xPercent:xVal, //여기에 xval변수값쓰기
        opacity:0
    })
})

데이터수치에 대한 변수 xVal을 만들어서
if문 작성 : el.dataset.x 값이 있다면(?) el.dataset.x의 값을 사용하고, 없다면(:) 0을 사용하도록 함
gsap에 xPercent에 변수를 넣어, 해당 위치에서 변수값을 사용 할 수 있도록 구성


🔹effet

✔️스크롤에 따라 서로 반대방향으로 무브

🔸css로 시작 지점을 다르게 잡아줌

&.one{left: -100%;}
&.two{right: 0;}

서로 반대방향으로 스크롤될 수 있도록, 시작 지점을 다르게 잡아준다
텍스트를 왼쪽/오른쪽으로 고정해놔서 스크롤해도 공백이 생기지 않게

🔸js로 무브

$('.sc-effect01 .effect-top.one').each(function(i,el){
  gsap.to('.sc-effect01 .effect-top.one',{
  scrollTrigger:{
  trigger:el,
  start:'top 95%',
  end:'bottom top',
  toggleClass: "hide",
  scrub:5
  },
  xPercent:50 
  })
  })

$('.sc-effect01 .effect-top.two').each(function(i,el){
  gsap.to('.sc-effect01 .effect-top.two',{
  scrollTrigger:{
  trigger:el,
  start:'top 95%',
  end:'bottom top',
  toggleClass: "hide",
  scrub:5
  },
  xPercent:-50 
  })
  })

start : 내 스크롤은 맨 위에 닿고, 윈도우기준 거의 바닥(95%)에 닿을 때 시작

  • one (left:-100) : 오른쪽으로 무브해야하기 때문에 50
  • two (right:0) : 왼쪽으로 무브해야하기 때문에 -50

🔹effet + box

🔸css box 위치 가운데정렬

 .box-area{
        left: 100%;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        z-index: 1;
        width: 100%;
        display: flex;
        justify-content: center;
 }

display flex, justify-content: center으로 가운데정렬하여
최대 스크롤을 해도 맨 왼쪽으로 가지 않도록 고정시킴

🔸js timeline으로 폰트+박스 연결

const effect02 = gsap.timeline({
      scrollTrigger:{
          trigger:".sc-effect02", 
          start:"0% 0%",
          end:"+=500%",
          scrub: 5,
          pin : true,
      },
    })
    effect02.addLabel('eff2')
    .to('.sc-effect02 .effect-top.one',{xPercent:50},'eff2')
    .to('.sc-effect02 .effect-top.two',{xPercent:-50},'eff2')
    .to('.box-area',{ left:'-10%'},'eff2')
  • timeline을 사용해서 연결하여, 폰트(effect-top.one/two)와 박스(box-area)를 한 번의 스크롤에 함께 영향받게 구성
  • one은 xPercent50으로 왼쪽으로 이동, two는 -50으로 오른쪽으로 이동
  • box는 left-10%의 위치에서 스크롤에 의해 오른쪽에서 왼쪽으로 무브되는 형태



0개의 댓글