완성 화면
코드 보기 / CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'ReciaSerifDisplay';
}
body {
height: 20000px;
background: #102a46;
}
.scrollTop {
position: fixed;
left: 10px;
top: 10px;
z-index: 1000;
width: 40px;
height: 40px;
background-color: rgba(0, 0, 0, 0.5);
text-align: center;
font-size: 14px;
line-height: 40px;
color: #fff;
}
.fixed {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
.s1-text1 {
font-size: 30vw;
color: #fff;
text-align: center;
}
.s1-text2 {
font-size: 0vw;
line-height: 2;
padding-top: 8vw;
color: #fff;
text-align: center;
}
.s1-text3 {
font-size: 0vw;
line-height: 2;
padding-top: 8vw;
color: #fff;
text-align: center;
}
.s1-text4 {
font-size: 0vw;
line-height: 2;
padding-top: 8vw;
color: #fff;
text-align: center;
}
.s1-img1 {
width: 200vw;
height: 100vh;
}
.s1-img1>div:nth-child(1) {
padding: 0 0vh;
}
.s1-img1>div:nth-child(2) {
padding: 0 0vh;
}
.s1-img1>div:nth-child(3) {
padding: 0 0vh;
}
.s1-img1>div:nth-child(4) {
padding: 0 0vh;
}
.s1-img1>div:nth-child(5) {
padding: 0 0vh;
}
.s1-img1>div {
height: 20vh;
display: flex;
justify-content: space-between;
align-items: center;
}
.s1-img1>div>div {
width: 19vh;
height: 19vh;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
border: 5px solid #000;
}
.s1-img1-1>div:first-child {
background-image: url(https://source.unsplash.com/500x500?moon);
}
.s1-img1-1>div:last-child {
background-image: url(https://source.unsplash.com/500x500?moonlight);
}
.s1-img1-2>div:first-child {
background-image: url(https://source.unsplash.com/500x500?mikyway);
}
.s1-img1-2>div:last-child {
background-image: url(https://source.unsplash.com/500x500?galaxy);
}
.s1-img1-3>div:first-child {
background-image: url(https://source.unsplash.com/500x500?Moon);
}
.s1-img1-3>div:last-child {
background-image: url(https://source.unsplash.com/500x500?Moonlight);
}
.s1-img1-4>div:first-child {
background-image: url(https://source.unsplash.com/500x500?Milkyway);
}
.s1-img1-4>div:last-child {
background-image: url(https://source.unsplash.com/500x500?Galaxy);
}
.s1-img1-5>div:first-child {
background-image: url(https://source.unsplash.com/500x500?sky);
}
.s1-img1-5>div:last-child {
background-image: url(https://source.unsplash.com/500x500?Moonsky);
}
scrollTop
: scrollTop 요소에 대한 스타일을 정의한다.
position: fixed는 요소가 고정된 위치에 있음을 나타내며, left: 10px와 top: 10px는 요소가 뷰포트에서 왼쪽과 위쪽에서 10픽셀 떨어져 있음을 나타낸다.z-index: 1000은 요소가 다른 요소 위에 놓이는 우선 순위를 나타내며, 숫자가 높을수록 요소가 위에 나타난다.width: 40px와 height: 40px는 요소의 너비와 높이를 40픽셀로 설정한다.
background-color: rgba(0, 0, 0, 0.5)는 요소의 배경색상을 반투명한 검정색으로 설정한다.
text-align: center는 요소 내부의 텍스트를 중앙 정렬한다.
font-size: 14px는 요소 내부의 글꼴 크기를 14픽셀로 설정한다.
line-height: 40px는 요소 내부의 줄 높이를 40픽셀로 설정한다.
color: #fff는 요소 내부의 글자색을 흰색으로 설정한다.
.fixed
: fixed 클래스의 요소에 대한 스타일을 정의한다.
position: fixed는 요소가 고정된 위치에 있음을 나타내며, left: 50%와 top: 50%는 요소가 뷰포트에서 가로와 세로로 각각 중앙에 위치함을 나타낸다.
transform: translate(-50%, -50%)는 요소를 가운데 정렬하기 위해 위치를 조정하는 데 사용된다.
z-index: 1은 요소가 다른 요소 위에 놓이는 우선 순위를 나타내며, 숫자가 높을수록 요소가 위에 나타낸다.
.s1-text1~4
: 스타일링이 적용되는 요소의 클래스명이 .s1-text1~4이다.
font-size: 30vw는 요소 내부의 글꼴 크기를 viewport width(뷰포트 너비)의 30%로 설정한다.
color: #fff는 요소 내부의 글자색을 흰색으로 설정한다.
text-align: center는 요소 내부의 텍스트를 중앙 정렬한다.
.s1-img1
: 스타일링이 적용되는 요소의 클래스명이 .s1-img1 이다.
width: 200vw는 요소의 너비를 viewport width(뷰포트 너비)의 200%로 설정한다. (즉, 화면보다 2배 넓다.)
height: 100vh는 요소의 높이를 viewport height(뷰포트 높이)의 100%로 설정한다. (즉, 화면 전체를 차지한다.)
.s1-img1>div:nth-child(1~5)
:.s1-img1 요소의 첫 번째 자식부터 다섯번째 자식 요소에 대한 스타일을 정의한다.
padding: 0 0vh는 요소의 상하좌우 여백을 모두 0으로 설정한다. (즉, 여백이 없다.)
코드 보기 / HTML
<div class="scrollTop"></div>
<section id="section1">
<div class="s1-text1 fixed" data-0="font-size: 0vw; opacity:1" data-1000="font-size: 30vw; opacity:1"
data-2000="font-size: 0vw; opacity:1" data-3000="font-size: 0vw; opacity:0">HELLO
</div>
<div class="s1-text2 fixed" data-2500="font-size: 0vw; transform: translate(-50%, -50%) rotate(0deg);"
data-3000="font-size: 30vw; transform: translate(-50%, -50%) rotate(1080deg);"
data-8500="font-size: 0vw;">MOON
</div>
<div class="s1-img1 fixed"
data-3500="width: 200vw;"
data-4000="width: 20vw;"
data-5000="width: 90vw;">
<div class="s1-img1-1" data-3500="transform: rotate(270deg);" data-5000="transform: rotate(0deg);">
<div></div>
<div></div>
</div>
<div class="s1-img1-2"
data-4000="margin:0 auto; width: 200vw;"
data-5000="width: 20vw; transform: rotate(360deg);"
data-6000="width: 200vw; transform: rotate(0deg); width: 90vw;">
<div data-3500="display: none;" data-5000="display: block;"></div>
<div data-3500="display: none;" data-5000="display: block;"></div>
</div>
<div class="s1-img1-3" data-6000="width: 20vw; transform: rotate(360deg);"
data-7000="margin:0 auto; width: 200vw; transform: rotate(0deg); width: 90vw;">
<div data-3500="display: none;" data-6000="display: block;"></div>
<div data-3500="display: none;" data-6000="display: block;"></div>
</div>
<div class="s1-img1-4"
data-7000="margin:0 auto; width: 20vw; transform: rotate(360deg);"
data-8000="width: 200vw; transform: rotate(0deg); width: 90vw;">
<div data-3500="display: none;" data-7000="display: block;"></div>
<div data-3500="display: none;" data-7000="display: block;"></div>
</div>
<div class="s1-img1-5"
data-8000="margin:0 auto; width: 20vw; transform: rotate(360deg);"
data-9000="width: 200vw; transform: rotate(0deg); width: 90vw;">
<div data-3500="display: none;" data-8000="display: block;"></div>
<div data-3500="display: none;" data-8000="display: block;"></div>
</div>
<div class="s1-text3 fixed" data-8500="font-size: 0vw; transform: translate(-50%, -50%) rotate(0deg);"
data-10000="font-size: 10vw; transform: translate(-50%, -50%) rotate(1080deg);"
data-11000="font-size: 0vw;"
> A SKY FULL OF STARS
</div>
<div class="s1-text4 fixed" data-11000="font-size: 0vw; transform: translate(-50%, -50%) rotate(0deg);"
data-12000="font-size: 3vw; transform: translate(-50%, -50%) rotate(1080deg);">
The moon shows us itself without changing, <br> providing us with an opportunity to search for ourselves. <br>- Hiroshi Matsumoto.
</div>
</div>
</section>
.s1-text1 fixed
data-0="font-size: 0vw; opacity:1" : 해당 요소가 초기에 표시될 때의 스타일을 정의한다. 글꼴 크기는 0vw (즉 보이지 않음), 투명도는 1이다.
data-1000="font-size: 30vw; opacity:1"는 스크롤을 1000px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 30vw(뷰포트의 30%), 투명도는 1이다.
data-2000="font-size: 0vw; opacity:1"는 스크롤을 2000px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 0vw, 투명도는 1이다.
data-3000="font-size: 0vw; opacity:0"는 스크롤을 3000px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 0vw, 투명도는 0이다. (요소가 화면에서 사라집니다.)
HELLO는 요소 내부의 텍스트이다.
s1-text2 fixed
data-2500="font-size: 0vw; transform: translate(-50%, -50%) rotate(0deg);": 스크롤을 2500px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 0vw, 요소의 위치를 중앙으로 이동시키는 transform: translate(-50%, -50%), 요소의 회전 각도를 0도로 설정하는 rotate(0deg)을 적용한다.
data-3000="font-size: 30vw; transform: translate(-50%, -50%) rotate(1080deg);": 스크롤을 3000px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 30vw, 요소의 위치를 중앙으로 이동시키는 transform: translate(-50%, -50%)를 사용하여 요소를 가운데 정렬하기 위해 위치를 조정하는 데 사용된다.
data-8500="font-size: 0vw; : 스크롤을 8500px만큼 내렸을 때의 스타일을 정의한다. 글꼴 크기는 0vw으로 점점 작아지면서 요소의 텍스트가 사라지게 하는 역할을 한다.
.s1-img1
: s1-img1이라는 선택자를 가진 div 박스 안의 모든 요소에 같은 효과를 주기 위해 CSS 선택자를 사용한다.
fixed 클래스는 이미지가 화면에 고정되도록 한다.
data-3500, data-4000, data-5000 속성은 이미지 요소가 화면에서 어떻게 변화할지를 정의한다.
data-3500은 이미지 요소가 처음에 화면에 나타나면서(화면의 3500px인 위치) 너비가 200vw로 설정된다.
data-4000은 스크롤이 4000px에 도달했을 때 이미지 요소의 너비가 20vw로 설정된다는 것을 의미한다.
data-5000은 스크롤이 5000px에 도달했을 때 이미지 요소의 너비가 90vw로 설정됩니다.
.s1-img1-1
: .s1-img1-1 클래스를 가진 요소에 대한 애니메이션을 설정하기 위해 .s1-img1-1 CSS 선택자를 사용한다.
data-3500은 이미지 요소가 처음에 화면에 나타날 때, .s1-img1-1 클래스의 회전이 270deg로 설정된다.
data-5000은 스크롤이 5000px에 도달했을 때 이미지 요소의 회전이 0deg로 설정된다.
이렇게 함으로써 이미지 요소의 자식 요소도 화면에 나타나면서 회전하게 된다.
.s1-img1-2~5
: 클래스를 사용하여 이미지 요소의 자식 요소를 정의한다.
data-nnnn 속성은 이미지 요소가 화면의 픽셀 값이 data 위에 오는 nnnn과 일치할 때 어떤 CSS 속성을 줄 지 설정하는 구문이다.
가로 길이(너비)가 200vw나 20vw, 90vw로 설정된다는 의미이다.
200vw는 화면 밖으로 요소가 나가 보이지 않으며 20vw는 너비가 줄어들면서 요소들이 서로 가까워진다. 90vw는 화면의 양측에 요소가 위치하도록 한다.
margin: 0 auto는 이미지가 수평 중앙에 위치하도록 한다.
tranform: rotare(nnn deg)는 일치하는 nnn값만큼 회전한다는 것을 의미한다.
data-3500 속성은 첫 번째와 두 번째 <div> 요소가 스크롤값이 3500px이 될 때부터 화면에서 나타나지 않도록 설정한다.
data-n000 속성은 그 값에 해당하는 픽셀 값이 되었을 때 첫 번째와 두 번째 <div> 요소가 화면에 나타나도록 display: block으로 설정한다.
코드 보기 / JAVASCRIPT
<script src="https://cdnjs.cloudflare.com/ajax/libs/skrollr/0.6.30/skrollr.min.js"></script>
<script type="text/javascript">
let s = skrollr.init();
window.addEventListener("scroll", () => {
let scrollTop = window.pageYOffset || window.scrollY
document.querySelector(".scrollTop").innerText = parseInt(scrollTop);
});
skrollr 라이브러리를 script src을 통해 로드하고 초기화한다.
skrollr은 스크롤 이벤트를 이용하여 웹사이트의 요소를 애니메이션화시키는 자바스크립트 라이브러리이다.
그 다음, window 객체에 scroll 이벤트 리스너를 등록한다.
스크롤 이벤트가 발생하면 이벤트 콜백 함수가 실행됩니다.
이벤트 콜백 함수는 window.pageYOffset 또는 window.scrollY 프로퍼티를 사용하여 현재 스크롤 위치를 가져와서, document.querySelector(".scrollTop")를 사용하여 .scrollTop 클래스를 가진 요소를 찾고, 그 요소의 innerText 값을 현재 스크롤 위치로 설정한다.
따라서, 스크롤을 할 때마다 페이지의 위쪽에서 현재 위치까지의 스크롤 거리가 .scrollTop 클래스를 가진 요소의 텍스트로 출력된다.