HTML/CSS/JS - 스타벅스 예제(2)

ekgns0508·2023년 10월 25일

html/css/js

목록 보기
11/11

11. lodash 라이브러리

const badgeEl = document.querySelector('header .badges');

// document는 html문서자체를 말하는 거라면 window는 브라우저의 하나의 탭(창)을 의미한다.
// 화면 자체를 스크롤 할 때의 로직
// 스크롤이 될때마다 함수가 실행되므로 이를 제어하기 위한 'lodash'라이브러리를 cdn으로 받는다.
window.addEventListener('scroll', _.throttle(function() {
  console.log(window.scrollY);
  if (window.scrollY > 500) {
    // 배지 요소를 숨긴다.
    badgeEl.style.display = 'none';
  } else {
    // 배지 요소를 보인다.
    badgeEl.style.display = 'block';
  }
}, 300)); // _.throttle(함수, 시간)
  • addEventListener() 를 이용해서 화면이 스크롤이 될때 특정 함수를 실행시킨다면 스크롤할 때 무수히 많은 함수가 실행되게 된다. 이에 부하를 줘 함수를 조금 실행되게끔 설정하기 위해 ‘Lodash’라이브러리를 cdn으로 가져온다.
  • _.throttle(함수, 시간) 을 이용해서 함수에 부하시간을 줄 수 있다.
  • badgeEl.style.display = ‘none’ : style 전역속성에서 display값에 ‘none’을 부여해 보이지 않게 할 수 있다.

12. gsap 라이브러리로 다양한 애니메이션 처리하기

gsap.to(badgeEl, .6, {
  opacity: 0,
  display: 'none'
});

gsap라이브러리를 이용해서 gsap.to(요소, 지속시간, 옵션)을 이용해서 애니메이션 효과를 처리할 수 있다.옵션에는 객체 형태의 값을 지정해주면 된다.

위의 코드에서는 badgeEl이라는 요소 opacity(투명도)를 0으로, display속성의 값을 ‘none’으로 0.6초의 지속시간동안 바뀌게 한다.

(opacity 속성처럼 값을 숫자로 입력하는 속성들은 전환효과(transition, gsap)을 통해 요소의 전/후 상태를 중간 숫자의 값으로 자연스럽게 만들어줄 수 있지만, display 속성처럼 값이 숫자가 아닌 속성은 전/후 상태의 중간값이 존재하지 않기 때문에 자연스러운 전환 효과를 적용할 수 없다)

순차적 애니메이션

const fadeEls = document.querySelectorAll('.visual .fade-in');
fadeEls.forEach(function(fadeEl, index) {
  gsap.to(fadeEl, 1, {
    delay: (index + 1) * .7,
    opacity: 1
  });
});
  • document.querySelectorAll('.visual .fade-in') : html문서에서 클래스리스트에 ‘visual’, ‘fade-in’이 들어있는 요소들 전부를 가져와 유사배열 형태로 가져온다.
  • fadeEls.forEach(function() {}) : 가져온 유사배열의 요소들을 하나씩 돌며 로직을 수행한다.
  • gsap.to(fadeEl, 1, {옵션}) : 위에서 배웠듯이 gsap라이브러리를 이용해서 각 fadeEl요소들에 1초의 지속시간을 부여하면 옵션의 값들에 변화를 준다.
    (위 코드에서는 gsap 라이브러리의 옵션중 하나인 ‘delay’를 (index + 1) * 0.7의 값으로 부여해 각 요소들이 0.7, 1.4, 2.1, 2.8초마다 투명도를 1로 변경되게끔 했다)

y축에서 떨어지는 애니메이션

function floatingObject(selector, delay, size) {
  // gsap.to(요소, 시간, 옵션(객체));
  gsap.to(selector, random(1.5, 2.5), {
    y: size, // 위에서 20Px만큼 내려오는 애니메이션이 실행된다.
    repeat: -1,  // -1 : 무한반복
    yoyo: true,  // 한번 재생된 애니메이션을 다시 뒤로 돌린다.
    ease: Power1.easeInOut, // gsap easing을 검색해 다양한 애니메이션 효과들을 불러올 수 있다.
    delay: random(0, delay)  // 몇초뒤에 애니메이션이 실행될지 지연시간을 지정한다.
  });
}
floatingObject('.floating1', 1, 15);
floatingObject('.floating2', .5, 15);
floatingObject('.floating3', 1.5, 20);

위에서 살펴보았듯이 gsap.to() 메소드에 다룰 요소, 시간, 옵션들을 정의함으로써 애니메이션을 적용해볼 수 있다.

  • y : y축에서 얼마만큼 떨어지는 애니메이션을 적용시킬지 지정한다.
  • repeat : -1로 지정할 경우 무한으로 반복할 수 있다.
  • yoyo : 한번 재생된 애니메이션을 반대로 실행하는 애니메이션도 실행한다.
  • ease : gsap easing을 검색했을 때 사용할 수 있는 다양한 애니메이션 처리 효과를 가져올 수 있다.
  • delay : 애니메이션이 몇 초 뒤에 실행될지 지정한다.

13. SWIPER 라이브러리

swiper 라이브러리는 6버전을 사용한다.

최신버전인 7, 8버전과 6버전의 차이는 사용하는 클래스명이 다른것이라고 보면 된다.

Swiper 라이브러리를 통해 슬라이드들을 자동으로 넘어가는 효과를 처리할 수 있다.

<link rel="stylesheet" href="https://unpkg.com/swiper@6.8.4/swiper-bundle.min.css" />
<script src="https://unpkg.com/swiper@6.8.4/swiper-bundle.min.js"></script>

기본사용방법

<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <a href="javascript:void(0)">크리스마스 & 연말연시 스타벅스 매장 영업시간 변경 안내</a>
    </div>
    <div class="swiper-slide">
      <a href="javascript:void(0)">[당첨자 발표] 2021 스타벅스 플래너 영수증 이벤트</a>
    </div>
    <div class="swiper-slide">
      <a href="javascript:void(0)">스타벅스커피 코리아 애플리케이션 버전 업데이트 안내</a>
    </div>
    <div class="swiper-slide">
      <a href="javascript:void(0)">[당첨자 발표] 뉴이어 전자영수증 이벤트</a>
    </div>
  </div>
</div>

swiper를 적용하고 싶은 구간을 클래스명 ‘swiper-contaier’를 사용해서 지정하고, 그 안에 클래스명 ‘swiper-wrapper’를 사용해서 구간을 지정한다.

슬라이드 애니메이션을 지정하고 싶은 요소들을 생성한후 클래스명을 ‘swiper-slide’를 지정해주고 옵션들을 자바스크립트로 조정해준다.

// new Swiper(선택자, 옵션)
new Swiper('.notice-line .swiper-container', {
  direction: 'vertical',
  autoplay: true,
  loop: true
});

Swiper의 생성자에 css 선택자와 옵션을 지정해준다.

  • direction : vertical : 슬라이드의 방향으로 수직으로 설정한다.
  • autoplay : true :
  • 위의 코드에서는 .notice-line 클래스를 가지고 있는 요소의 하위 요소중에 .swiper-container 클래스를 갖고 있는 요소에 direction은 ‘vertical’ 수직방향으로, autoplaytrue로 지정해 자동으로 스와이프되도록 지정했고, loop옵션을 true값을 지정해 계속 반복하도록 설정했다.

다양한 옵션들

<div class="swiper-container">
	<div class="swiper-wrapper">
		<div class="swiper-slide"></div>
		<div class="swiper-slide"></div>
		<div class="swiper-slide"></div>
		<div class="swiper-slide"></div>
	</div>
</div>

위에서 살펴보았듯이 swiper 라이브러리를 사용하기 위해서는 swiper-container 클래스의 요소와 swiper-wrapper 클래스의 요소가 필수이다. swiper-wrapper 클래스의 요소 안에 슬라이드로 만들고 싶은 요소들을 지정하기 위해 swiper-slide 클래스의 요소들을 만들 수 있다.

new Swiper('.promotion .swiper-container', {
  slidesPerView: 3, // 한번에 보여줄 수 있는 슬라이드의 개수
  spaceBetween: 10, // 슬라이드 사이 여백 10px
  centeredSlides: true, // 1번 슬라이드가 가운데 보이기
  loop: true,
  autoplay: {
    delay: 5000  // 5s
  },
  pagination: {
    el: '.promotion .swiper-pagination',  // 페이지 번호 요소 선택자
    clickable: true // 사용자의 페이지 번호 요소 제어 가능 여부
  },
  navitgation: {
    prevEl: '.promotion .swiper-prev',
    nextEl: '.promotion .swiper-next'
  }
});

똑같이 Swiper() 생성자를 이용해서 애니메이션을 적용할 요소와 옵션을 지정해준다.

  • slidesPerView : 화면에서 한번에 보여줄 수 있는 슬라이드의 개수를 지정한다.
  • spaceBetween : 슬라이드 사이의 여백을 지정해준다.
  • centeredSlides : 메인 슬라이드를 가운데에 표시할지에 대한 여부를 지정한다.
  • loop : 반복여부를 지정한다. 한번에 보여줄 수 있는 슬라이드의 개수를 3개로 지정해놓은 상태이므로 첫번째 가운데 슬라이드의 왼쪽에 마지막 슬라이드가 나타난다.
  • autoplay : 자동재생의 옵션값에 다시 delay 속성을 줘 지정한 시간마다 슬라이드가 전환되도록 한다.
.notice .promotion .swiper-slide {
  opacity: .5;
  transition: opacity 1s;
  position: relative;
}
.notice .promotion .swiper-slide-active {
  opacity: 1;
}

위에서 지정한 swiper-slide클래스의 요소들중에서 현재 선택되어 보여지고 있는 슬라이드에는 swiper-slide-active 클래스가 새로 붙게 된다. 따라서 해당 클래스에 스타일을 주어 보여지고 있는 슬라이드와 보여지고 있지 않은 나머지 슬라이드들과의 스타일에 차이점을 줄 수가 있다.

위에서는 보여지는 슬라이드에는 투명도 1을, 보여지지 않는 슬라이드들에는 투명도를 0.5를 부여하고 transition 속성으로 자연스럽게 처리하도록 했다.

pagination

<div class="swiper-container">
	<div class="swiper-wrapper">
		...
		<div class="swiper-pagination"></div>

		<div class="swiper-prev">
      <div class="material-icons">arrow_back</div>
    </div>
    <div class="swiper-next">
      <div class="material-icons">arrow_forward</div>
    </div>

	</div>
</div>

슬라이드들을 점으로 찍어 점을 누르면 해당 슬라이드로 이동하는 pagination을 사용하기 위해 swiper-pagination 클래스의 요소를 생성한다.

swiper-wrapper, swiper-slide 와 마찬가지로 swiper-container 안에 있어야 한다.

new Swiper('.promotion .swiper-container', {
	...,
	pagination: {
    el: '.promotion .swiper-pagination',  // 페이지 번호 요소 선택자
    clickable: true   // 사용자의 페이지 번호 요소 제어 가능 여부
  },
  navigation: {
    prevEl: '.promotion .swiper-prev',
    nextEl: '.promotion .swiper-next'
  }
});
  • pagination 옵션
    • el : 페이지 번호 요소 선택자를 지정한다. 위의 swiper-pagination 요소를 지정해준다.
    • clickable : 클릭했을때 슬라이드로 넘어갈지를 정한다.
  • navigation 옵션
    • prevEl : 이전 버튼요소를 선택자로 지정해준다.
    • nextEl : 다음 버튼 요소를 선택자로 지정해준다.
.swiper-pagination .swiper-pagination-bullet {
	...
	background-color: transparent;
  background-image: url("../images/promotion_slide_pager.png");
}

swiper-pagination 클래스를 지정한 요소의 각 점은 swiper-pagination-bullet 클래스를 갖게 된다.

해당 클래스를 선택해서 바꾸고 싶은 이미지로 버튼색상을 변경할 수도 있다.

.swiper-pagination .swiper-pagination-bullet-active {
  background-image: url("../images/promotion_slide_pager_on.png");
}

각 점은 선택될시 swiper-pagination-bullet-active 클래스를 추가로 갖게되며 해당 요소를 css로 스타일을 편집해 선택됬을때의 점의 이미지등을 변경해줄수도 있다.

14. 요소 슬라이드

calc()

width: calc(819px * 3 + 20px);
width: calc(100% - 50px);

css에서는 수동으로 계산해야 하는 불편함을 없애고자 calc()함수를 제공해준다.

calc(100% - 50px)와 같이 여러가지 단위를 함께 사용할 수도 있다.

가운데 배치

position: absolute;
top: 40px;
left: 50%;
margin-left: calc((819px * 3 + 20px) / -2);

요소를 화면의 수평기준으로 가운데로 정렬하기 위해 left 속성으로 화면의 왼쪽에서 50%의 위치에 배치시키고 margin-left 속성으로 현재 요소의 절반만큼을 왼쪽으로 당겨오면 요소를 가운데로 정렬시킬 수 있다.

(반대로 right 속성으로 50%를 부여했을 경우에는 margin-right 속성으로 요소의 절반만큼 오른쪽으로 당겨오면 된다.)

15. youtube iframe api 사용해보기

iframe 삽입에 대한 YouTube Player API 참조 문서  |  YouTube IFrame Player API  |  Google for Developers

youtube iframe api 사이트에 들어가서 ‘시작하기’부분을 확인해보면 html에서 내장플레이어를 만드는 방법을 볼 수 있다.

// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// 3. This function creates an <iframe> (and YouTube player)
//    after the API code downloads.
function onYouTubeIframeAPIReady() {  // 정해져있는 함수명으로 바뀌면 안된다.
  new YT.Player('player', { // 'player'를 id값으로 갖는 요소를 불러온다.
    videoId: 'An6LvWQuj_8', // 최초 재생할 유튜브 ID
    playerVars: {
      autoplay: true,   // 자동 재생 유무
      loop: true,       // 반복 재생 유무
      playlist: 'An6LvWQuj_8' // 반복 재생할 유튜브 ID 리스트
    },
    events: {
      // 동영상 플레이어가 준비될경우 실행하는 함수
      onReady: function(event) {
        event.target.mute() // 음소거, event.target : 실행되고 있는 동영상
      }
    }
  });
}
  • var tag = document.createElement('script') : tag 변수에 script 요소를 만들어 저장한다.
  • tag.src = "https://www.youtube.com/iframe_api" : 생성한 script요소의 src 속성으로 정해져있는 api의 url을 지정해준다.
  • onYouTubeIframeAPIReady() : api에서 정해놓은 함수명으로 변경되어서는 안된다.
  • new YT.Player(’player’, {옵션}) : 동영상 플레이어에 옵션을 정하는 부분으로 ‘player’는 html에서 id값으로 ‘player’를 지정한 요소를 찾아 가져온다.
  • videoId : 재생할 유튜브 동영상의 Id 값을 가져온다.

16. ScrollMagic 라이브러리 사용하기

ScrollMagic - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers

위 사이트에서 cdn script 코드를 복사해서 header 태그내에 붙여준다.

ScrollMagic 라이브러리를 이용해서 스크롤을 할 때 효과를 부여할 수 있다.

자바스크립트

const spyEls = document.querySelectorAll('section.scroll-spy');
spyEls.forEach(function(spyEl) {
  new ScrollMagic
  .Scene({
    triggerElement: spyEl, // 보여짐 여부를 감시할 요소를 지정
    triggerHook: .8,  // 트리거 요소가 뷰포트의 어느 위치에서 걸리면 실행될지 지정
  })
  .setClassToggle(spyEl, 'show')  // 다룰 요소가 대상이 되었을때 'Show'클래스를 추가해준다.
  .addTo(new ScrollMagic.Controller());
});
  • const spyEls = document.querySelectorAll(’section.scroll-spy’) : 클래스 선택자로 secition 태그에 scroll-spy 클래스가 있는 요소들을 검색하여 유사 배열 형태로 spyEls 변수에 담아준다.
  • spyEls.forEach(function(spyEl) {}) : spyEls 변수에 담아있는 요소들을 순차적으로 돌며 함수를 실행한다.
  • new ScrollMagic.Scene({}) : 옵션값으로 트리거로 작동할 요소와 트리거가 작동할 뷰포트의 위치를 지정한다.
    • triggerElement : spyEl : 트리거로 작동할 요소를 spyEl로 지정해준다.
    • triggerHook : .8 : 뷰포트의 0.8의 위치에 triggerElement에서 지정한 요소가 위치하게 될때 작동하도록 한다. (위 : 0, 아래 : 1)
  • setClassToggle(spyEl, ‘show’) : spyEl 요소가 트리거로 발동되었을 때 클래스리스트에 ‘show’라는 클래스를 추가해주도록 한다.
<div class="scroll-spy">
	<div class="back-to-position to-left"></div>
	<div class="back-to-position to-right"></div>
</div>
.back-to-position {
  opacity: 0;
  transition: 1s;
}
.back-to-position.to-right {  /*왼쪽에서 오른쪽으로*/
  transform: translateX(-150px);  /*수평으로 -150px 만큼 이동*/
}
.back-to-position.to-left {   /*오른쪽에서 왼쪽으로*/
  transform: translateX(150px);   /*원래 위치로*/
}
.show .back-to-position {
  opacity: 1;
  transform: translateX(0);
}
  • 위와 같은 html 코드와 css 를 지정했을 때 scroll-spy 클래스의 div 요소가 뷰포트의 0.8의 부분에 위치하기 전까지 스크롤을 움직이지 않을 경우에는 클래스리스트에 ‘show’ 클래스가 붙지 않지만 0.8부분에 위치하게 될경우에는 붙게돼 scroll-spy show의 클래스를 갖게 된다.
  • 자식 요소들은 ‘back-to-position’ 클래스를 갖게 하고 css스타일로 기본적으로 투명도를 0으로 지정해 완전 투명하게 했고 전환효과를 1초를 주었다.
  • ‘back-to-position’과 ‘to-right’ 또는 ‘to-left’를 갖는 클래스는 각각 현재 위치에서 -150px, +150px 만큼 움직이게했다.
  • ‘show’클래스와 ‘back-to-position’을 갖는 요소 즉 뷰포트의 위치의 0.8부분에 위치하게돼 ‘show’ 클래스를 갖게된 요소(여기서는 부모 요소)는 투명도를 1로 설정하고 transform속성을 통해 다시 원래의 위치로 이동하게 했다.
  • 결과적으로 뷰포트의 0.8부분에 위치하지 않는 back-to-position 클래스를 갖는 요소들은 화면에서 보이지 않게 되고, 기존 위치에서 -150px, 150px 만큼 기존 위치로부터 1초동안 움직이게 하고 스크롤을 내리면서 0.8의 위치가 되었을 때 ‘show’클래스가 추가되면서 다시 원래 위치로 돌아가게 되고 투명도가 1이 되어 다시 화면에 보여지게 된다.

17. 특수기호

Character Entity Reference Chart - W3cubTools

“<” 와 같은 특수기호들은 태그내에 값을 지정한다고 해서 출력이 되질 않는다. 왜그런지 살펴보자.

<div>

위와 같은 글자가 출력되게 하고 싶지만 실제로는 출력되지 않는다. div 시작 태그로 인식하기 때문에 “<”와 “>” 부분을 태그로 인식하게 된다. 따라서 글자로서 출력되게 하고 싶을 경우에는 아래와 같이 작성해야 한다.

&lt;div&gt;

위와 같이 “&”와 지정된 키워드, 그리고 “;”을 함께 작성해주면 특정한 특수기호들을 출력할 수 있다.

위에 북마크된 사이트에 들어가면 다양한 특수기호 문법들을 살펴볼 수 있다.

18. 현재 날짜값 가져오기

const thisYear = document.querySelector('.this-year');
thisYear.textContent = new Date().getFullYear();
  • new Date() : 현재 날짜값을 가지고 있는 객체를 불러온다.
  • thisYear.textContent = new Date().getFullYear() : new Date()를 통해 현재 날짜값을 가지고 있는 객체를 불러오고 해당 객체의 getFullYear() 함수를 사용해서 현재 년도를 가져온다. 또한, thisYear.textContent 값으로 지정해 this-year 클래스를 가지고 있는 요소의 값으로 지정한다.

19. 페이지 상단으로 이동하기

gsap - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers

위에서 살펴보았듯이 gsap cdn코드(gspa.min.js)를 html문서내에 넣는 것으로 gsap라이브러리를 사용할 수 있다. 하지만 너무 많은 기능들을 하나의 cdn코드내에 넣는 것은 버겁기 때문에 gsap에서는 별도의 기능들을 따로 분리를 해놓았다. 여기서는 페이지 상단으로 이동하는 애니메이션을 처리하기 위해 ScrollToPlugin.min.js를 불러온다.

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollToPlugin.min.js" 
	integrity="sha512-v/m68W+vaGN/6igoyFpd4GlQzu0jx9/n5gr2PKq5vif+RObyGKHse384YHrOULaxZ810XhlHUrmB3U8UnPB19Q==" 
	crossorigin="anonymous" referrerpolicy="no-referrer">
</script>

html

<div id="to-top">
  <div class="material-icons">arrow_upward</div>
</div>

id값을 ‘to-top’을 갖는 div 요소를 만들고 그 안에 material-icons에서 위를 가리키는 화살표의 아이콘을 가져오기 위해 클래스명을 ‘material-icons’, 값을 ‘arrow_upward’로 지정해준다.

javascript

const toTopEl = document.querySelector('#to-top');

toTopEl.addEventListener('click', function() {
  gsap.to(window, .7, {
    scrollTo: 0 // scrollTo 플러그인이 있다면 scrollTo 옵션을 통해 원하는 지점으로 스크롤을 이동시킬 수 있다.
  });
});

html코드로 만든 div 요소를 querySelector()를 이용해서 불러온다. 해당 요소에 이벤트리스너를 추가해 ‘클릭’ 이벤트가 일어날시 함수를 실행하도록 한다. gsap의 to() 를 이용해서 ScrollToPlugin.js를 이용해서 맨위로 이동하게끔 한다.

0개의 댓글