안녕하세요, 김선진입니다.
이번에 회사에서 기능 소개 랜딩 페이지를 만들면서,
디자이너 분께 parallax scrolling으로 해줬으면 한다는 부탁을 받았는데요!
솔직히 처음 들어본 이름이라 생소했는데, (14년도 쯤에는 유행이었다고 합니다.)
애플의 제품소개 페이지에서 사용된 기능을 parallax라고 칭한다는 걸 알았습니다.
어쨌든, 이번에는 이 parallax scrolling을 pure css로 구현하는 방법에 대해 써보겠습니다.
(opacity가 변경되는 trigger 형식의 애니메이션 같은 경우는... 따로 구현했습니다)
0. 서론
먼저, Parallax란? 직역하면 '시차'다.
천문학에서 가까이 있으면 빠르게 움직이고 멀리있으면 느리게 움직인다고 하는 그 개념이다.
시차
(Parallax)는 고정된 먼 배경이 존재하는 상황에서 한 물체를 서로 다른 위치에 있는 두 관측자가 관측했을 때 발생하는 겉보기 위치의 차이 또는 변위이다.
고전게임을 생각하면 쉽다. 마리오 같은 게임은 배경을 고정하고 다른 사물의 움직이는 속도를 설정해서 시차 스크롤링을 하고 있다. 어쨌든, 우리는 이미 시차 스크롤링이 뭔지 알고 있었다. (정확히 무슨 개념인지 몰랐을 뿐이다.)
1. background 로 parallax 구현하기
위의 정의에서 알 수 있듯, parallax의 기본 원리는 '고정된 먼 배경'이다.
즉, 우리는 css에서 background 속성을 이용해 고정된 먼 배경을 만들어줄 수 있다.
그리고 이걸 하면 스크롤 할 때 파워포인트에서 닦아내기 한 효과 비슷한 걸 줄 수 있다.
이건 그냥 CSS 프로퍼티만으로 설정이 가능하다.
.parallax-background{
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
2. transform으로 parallax 구현하기
근데, 배경만 고정해서는 내가 원한 느낌과는 다르다.
좀 더 가까이에 있는 녀석은 빨리 움직이는 효과를 줘야한다.
그렇다면 CSS만으로 어떻게 원근을 줄까?
답은 간단하다. z축을 이용하면 된다.
이 그림을 보면 알 수 있다시피, z축으로 가까워 질수록 점점 크기가 커질 것을 예상해볼 수 있다.
그럼 transform을 써보자! 아래 두 개 코드를 예시로 쓴다.
.element {
height: 100px;
width: 100px;
background: pink;
transform: translateZ(0px);
}
<body>
<div class="element">커져라 네모네모!</div>
</body>
CSS에서 translateZ를 바꿔서 앞으로 밀어보자. 결과는?
무엇이 바뀌었는지 확인해보면 아무것도 일어나지 않는다.
perspective속성이 빠졌기 때문이다.
원근 속성을 주지 않으면 아무리 Z축으로 움직여도 아무 일도 일어나지 않는다는 점을 명심해야 한다.
perspective는 사용자의 시점 위치를 말한다.
값이 커질수록 사용자가 멀리 있음을 의미한다.
주의할 점은 값을 잘 생각해서 결정해야 하는 것이다.
예를 들어 perspective: 4px로 주고 z축 4px 이상을 이동해버리면 사용자를 지나쳐 가버렸기 때문에 더이상 물체가 보이지 않는 상태가 된다. 당연한 얘기겠지만 음수로 주면 멀어진다.
이런 것을 염두에 두고 잘 설정하도록 하자.
더불어 알면 좋은 것은 perspective-origin이다.
이 속성의 기본값은 50%50%지만, center로 주면 보통 원하는 위치로 이동한다고 보면 된다. 투시 원점을 나타낸다.
마지막으로, backface-visibility 속성으로 뒷면도 보여줄지 말지 정할 수 있다.
그럼 위 코드를 수정해보자.
<body>
<div class="parallax container">
<div class="background">
<div>
<div class="foreground">
빨라...
</div>
<div class="foreground fast">
더빨라...
</div>
</div>
</div>
</div>
</body>
body {
display: flex;
justify-content: center;
align-items: center;
height: 500px;
}
.parallax.container {
position: relative;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
perspective: 8px;
perspective-origin: 0%;
}
.parallax: {
position: absolute;
transform-origin: 0 50%;
width: 420px;
height: 420px;
}
.background:before {
position: relative;
content: '느려';
color: white;
display: flex;
justify-content: center;
align-items: center;
transform: translateZ(0px) scale(1);
background: red;
height: 800px;
width: 100%;
}
.foreground {
position: absolute;
height: 100px;
width: 100px;
background: pink;
top: 300px;
transform: translateZ(4px) scale(0.5);
}
.foreground.fast {
background: yellow;
top: 250px;
transform: translateZ(6px) scale(0.25);
}
위 코드를 실행 해 보면 배경은 느리고, 빠른 놈은 빠르고,
더 빠른 놈은 더 빠르게 움직이는 것을 확인할 수 있다.
계산은 귀찮으면 따로 css함수로 빼도 된다.
그리고 z축을 움직일 때는 크기가 커지는 것을 감안해서 스케일 작업을 잊지 말고 해줘야 한다.
스케일 식은 다음과 같다.
스케일 = 1 - (z축 깊이/원근 시야)
보시다시피 빠른녀석은 0.5, 더 빠른 녀석은 0.25로 크기를 조절해주고 있는데,
위 식에 따른 것이다.
빠른 녀석 스케일(0.5) = 1 - (z축 깊이(4)/원근 시야(8))
더 빠른 녀석 스케일(0.25) = 1 - (z축 깊이(6)/원근 시야(8))
그럼 이만~.
Referances
https://ko.wikipedia.org/wiki/%EC%8B%9C%EC%B0%A8_(%EC%B2%9C%EB%AC%B8%ED%95%99)
https://www.w3schools.com/howto/howto_css_parallax.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
'뚱땅뚱땅' 카테고리의 다른 글
[HTML5/JavaScript] 직소퍼즐 만들기 4(完) : 퍼즐 게임으로 만들기 (0) | 2020.10.26 |
---|---|
[HTML5/Javascript] 직소퍼즐 만들기 3: 퍼즐 조각 무작위로 섞기 (0) | 2020.10.24 |
[HTML5/JavaScript] 직소퍼즐 만들기 - 2: 드래그드롭으로 퍼즐넣기 (0) | 2020.09.28 |
[HTML5/JavaScript] 직소퍼즐 만들기 - 1 : 파일 입력 (0) | 2020.09.28 |