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’을 부여해 보이지 않게 할 수 있다.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초의 지속시간을 부여하면 옵션의 값들에 변화를 준다.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 : 애니메이션이 몇 초 뒤에 실행될지 지정한다.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 :<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 속성으로 자연스럽게 처리하도록 했다.
<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'
}
});
.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로 스타일을 편집해 선택됬을때의 점의 이미지등을 변경해줄수도 있다.
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 속성으로 요소의 절반만큼 오른쪽으로 당겨오면 된다.)
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 값을 가져온다.위 사이트에서 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);
}
scroll-spy show의 클래스를 갖게 된다.Character Entity Reference Chart - W3cubTools
“<” 와 같은 특수기호들은 태그내에 값을 지정한다고 해서 출력이 되질 않는다. 왜그런지 살펴보자.
<div>
위와 같은 글자가 출력되게 하고 싶지만 실제로는 출력되지 않는다. div 시작 태그로 인식하기 때문에 “<”와 “>” 부분을 태그로 인식하게 된다. 따라서 글자로서 출력되게 하고 싶을 경우에는 아래와 같이 작성해야 한다.
<div>
위와 같이 “&”와 지정된 키워드, 그리고 “;”을 함께 작성해주면 특정한 특수기호들을 출력할 수 있다.
위에 북마크된 사이트에 들어가면 다양한 특수기호 문법들을 살펴볼 수 있다.
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 클래스를 가지고 있는 요소의 값으로 지정한다.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>
<div id="to-top">
<div class="material-icons">arrow_upward</div>
</div>
id값을 ‘to-top’을 갖는 div 요소를 만들고 그 안에 material-icons에서 위를 가리키는 화살표의 아이콘을 가져오기 위해 클래스명을 ‘material-icons’, 값을 ‘arrow_upward’로 지정해준다.
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를 이용해서 맨위로 이동하게끔 한다.