Javascript30 - Flex Panels Image Gallery
Flex Panels Image Gallery
요구사항
1. 패널을 클릭하면 패널이 확장되고 확장이 완료되면 위아래에서 문구가 들어온다.
2. 확장된 패널을 클릭하면 패널이 축소되고 문구가 위아래로 나간다.
1. HTML 구성
- 패널박스 panels 안에 패널 5개가 들어가 있고 각 패널은 p태그 3개로 이루어져 있다.
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
2. CSS 구성
- body
margin: 0으로 해서 화면에 꽉 차게 한다.
- panels클래스
display: flex로 가로정렬, min-height:100vh로 사용자 화면에 꽉차게, overflow:hidden으로 빠져나온 부분 안보이게 한다.
- panel클래스
패널의 트랜지션을 설정하고 flex-direction:column으로 세로 방향으로 쌓이게 변경.
- panel > *:first-child
패널의 첫번째 p태그는 클릭 전에는 y값을 마이너스로 해서 안보이게 한다.
- panel.open-actice > *:first-child
open-active상태일 때 첫번째 p태그의 y값을 0으로 한다.
- panel.open
패널을 클릭했을 때 flex:5, font-size:40px으로 변경해서 커지는 모션을 준다.
<style>
body {
margin: 0;
}
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel {
flex: 1;
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
.panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
.panel > * {
margin: 0;
width: 100%;
transition: transform 0.5s;
flex: 1 0 auto;
display: flex;
align-items: center;
justify-content: center;
}
.panel > *:first-child {
transform:translateY(-100%);
}
.panel.open-active > *:first-child {
transform:translateY(0);
}
.panel > *:last-child {
transform:translateY(100%);
}
.panel.open-active > *:last-child {
transform:translateY(0);
}
.panel.open {
flex: 5;
font-size: 40px;
}
</style>
3. Javascript 구성
- 패널 클릭을 감지하는 이벤트리스너 만들기
- open클래스를 토글하기
- 패널의 변화가 끝나는걸 감지하는 이벤트리스너 만들기
- propertyName이 'flex'를 포함하고 있는 패널의 클래스에 open-active클래스를 토글하기
<script>
const panelbox = document.querySelector('.panels');
const panels = panelbox.querySelectorAll('.panel');
function extendit() {
this.classList.toggle('open');
}
function comeinout(e) {
console.log(e.propertyName);
if (e.propertyName.includes('flex')) {
e.target.classList.toggle('open-active');
}
}
panels.forEach(panel => panel.addEventListener('click',extendit));
panels.forEach(panel => panel.addEventListener('transitionend',comeinout));
</script>
이번 회차는 자바스크립트보다 CSS에서 트렌지션과 플렉스를 어떻게 설정할 건지가 더 어려웠다. transform:translateY()로 y값을 바꾸면 화면에서 안보이게도 가능하다는 것도 배웠다.