2023. 1. 3. 23:39ㆍWeb
일반 웹사이트에서 쉽게 볼 수 있는
이미지 슬라이드 효과를 만들어 보았다.
아무래도 스크롤보다는 대부분 웹사이트는
이미지 슬라이드 효과를 많이 사용한다는 것을 알 수 있다.
저는 슬라이드쇼를 만드는 데에
html, css, js 이렇게 3가지를 사용했고
자동과 수동 슬라이드 구현을 모두 적용해보았다.
[HTML]
<head>태그에는 css와 js 그리고 아이콘을 사용하기 위해
각각의 외부소스들을 연동해주었다.
<body>태그에는
가장 부모 <div>태그로 slide_background 클래스를 생성했다.
(<body>태그 안에 onload="call_js()"는 내가 js에서 생성한 함수를
<body> 전체에 적용시켜주기 위해 작성해놓은 것이다.)
그 안에 이미지, 네비, 인디케이터 역할을 할 <div>태그를 각각 만들었다.
먼저 .slideshow 클래스에는 아래의 4개의 자동차 이미지를 넣어줄 것이다.
그래서 <a>태그 안에 <img>태그를 4개를 생성하고,
src=" " 인에 각각의 파일경로 및 파일명, 확장명을 넣어주었다.
그리고 각각의 alt=""에는 이미지에 대한 설명으로 간단하게
car-1, car-2, car-3, car-4로 적용해 주었다.
그리고 이전 이미지와 다음이미지를 수동으로
클릭하여 화면을 전환시켜줄 <div>태그를 하나 더 생성했다.
네비게이션 역할의 slideshow_nav 클래스로 fontawesome에서
아이콘을 가져와 <a>태그에 각각 적용해주었다.
마지막으로 이미지의 순서와 위치를 보여주는
indicator역할을 하는 <div> 태그를 생성했고,
slideshow_indicator 클래스로 적용해주었습니다.
이미지는 총 4개이므로 마찬가지로 <a>태그를
총 4개를 생성하였고 아이콘을 적용해주었습니다.
첫번째 <a>태그에만 'active'클래스를 적용한 이유는
js에서 indicator 클래스에 <a>태그들을 활성화주기 위해
가장 첫번째 앵커에만 적용해 놓은 것이다.
(한 개만 적용하면 나머지 <a>태그들도 적용이 됩니다.)
[CSS]
CSS에서 슬라이드 효과를 만들어낸 중요한 부분이 있다.
바로 position이다.
슬라이드의 <div>태그들의 가장부모인 slideshow_background 클래스에
position:relative;를 적용해주었다.
그리고 부모 안에 배치할
이미지와 네비게이션 및 인디케이터 역할을 하는 아이콘들은
position:absolute; 로 적용을 해주었다.
그 이유는 부모 클래스에 따로 position:relative;를 설정해 놓지 않으면
absolute로 설정한 요소들은 html을 기준으로 위치가 배치가 되기 때문이다.
고로 나는 slidwshow_background 클래스 안에서 슬라이드 쇼를
구현할 것이기 때문에 나머지 클래스들의 부모인
slidwshow_background 클래스에 relative를 설정해준 것이다.
그리고 부드러운 이미지 슬라이드를 위해
slideshow 클래스에 transition:all 1s;을 적용해주었다.
transition은 이미지가 전환될 때
설정한 시간동안 지속되는 효과를 나타내준다
즉, slideshow에 모든요소(all) 1초(1s)의 시간동안 지속하면서
전환해주기 때문에 시각적으로 이미지가 변환되는 것이 보여지게 된다.
마지막 코드에 indicator에 이미지의 위치에 맞게
표시가 되도록 active 클래스에 color를 적용해주었다. (js에서 함수적용)
[JavaScript]
먼저 전체 js코드를 앞에 html의 <body>태그에 적용해주었던
함수 전체를 포괄할 call_js() 선언적함수를 생성했다.
그리고 각각의 요소들을 document.querySelector로 불러와
각각의 변수를 생성해주었다.
이미지들을 각각의 인덱스에 left : i * 100%를 적용해서
아래 이미지 처럼 오른쪽으로 나열해주었다.
이 부분이 옆으로 슬라이드가 되는 효과를 보여주는 배치이다
위에 배치된 이미지를 이번에
index * -100%를 적용해주어서 이미지가 왼쪽으로
하나씩 보여지게 해주었다.
CSS에서 마지막에 설정한 indicator에 active클래스에
색상효과를 이미지[인덱스]에 맞게 적용이
되도록 적용해주었다.
startTimer() 함수를 만들어 타이머함수인
setInterval을 적용해 일정시간마다
이미지가 전환이 반복 실행이 되도록 설정해주었다.
slideshow 위에 마우스를 올려놓았을 때,
'mouseenter' 이벤트를 사용해 타이머 함수를
제거하는데 사용하는 cleanInterval로
반복 전환을 멈추어 주었고,
반대로 마우스 포인터가 slideshow위를 벗어났을 때,
다시 이미지 반복 전환이 되도록 startTImer() 함수를
호출해 주었다.
그리고 nav(= .slideshow_nav)도 이전과 다음화면을 수동으로 전환할 때
화면이 자동전환이 되면 안되니 똑같이 함수를 적용해주었다.
prev(이전버튼)을 'click'했을 때,
preventDefault()로 앵커의 기본효과를 막아주었다.
그리고 클릭시 현재 인덱스에서 -1을 적용하고,
인덱스[0]에서 인덱스[-1]로 넘어가는 시점에는
마지막 이미지인 인덱스[3]으로
넘어갈 수 있도록 조건을 걸어주었다.
그리고 다시 자동 슬라이드가 이어서 되도록
moveSlide()함수를 호출해주었다.
next(다음버튼)함수도 동일한 방법으로 적용해주었다.
indicator에도 마찬가지로 forEach를 사용해서 각각의 객체에 마우스포인터를 올려놓을 경우,
타이머 함수인 clearInterval()을 적용시켜
화면전환이 멈추도록 적용해주었다.
그리고 반복문으로 indicator의 인덱스를 클릭하면 해당 인덱스의 이미지로 전환되게 적용해주었다.
여기까지 웹페이지 안에서 이미지 슬라이드를 구현하는 방법을 알아보았다.
이미지를 슬라이드에 적용할 때 한 가지 TIP을 알려주자면
서로 다른 여러 이미지를 가져오게 되면, 각각의 이미지의 원본 사이즈가 달라서 슬라이드 안에서의
이미지 사이즈들이 제각각일 가능성이 많다.
쉽게 맞추는 Tip으로는 그림판에서 각각의 이미지를 불러와서 크기조정 도구로
픽셀을 동일하게 맞추어주고 html의 img src에 넣어주면 간단하게 해결된다.
< HTML 전체코드 >
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://kit.fontawesome.com/4c16673fd2.js" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css2?family=Abril+Fatface&family=Crete+Round&family=PT+Serif&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Abril+Fatface&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./css/home.css">
<script src="./js/page.js" defer></script>
</head>
<body>
<nav>
<div class="nav_logo">
<i class="fa-brands fa-html5"></i>
<a href="#">HTML5</a>
</div>
<div class="nav_menu">
<ul>
<a href="#">
<li>Support</li>
</a>
<a href="#">
<li>Tutorials</li>
</a>
<a href="#">
<li>References</li>
</a>
<a href="#">
<li>Exercises</li>
<a href="#">
<li>Videos</li>
</ul>
</div>
<a class="sign_in" href="#">SIGN IN</a>
<a href="#" class="nav_toggle"><i class="fa-solid fa-bars"></i></a>
</nav>
<main>
<div class="main_title">
<h1>HTML5 is?</h1>
</div>
<div class="sub_title">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores, accusantium ad quis provident obcaecati ex necessitatibus nobis similique non iure, commodi fugit quae animi odio autem repellendus neque facilis Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque consequuntur eum dolorem, tempora excepturi dolore corporis fugiat. Illum sunt, eum, voluptatum velit asperiores itaque impedit, distinctio deleniti exercitationem ea eaque?
</div>
<section>
<article class="section_item">
<div class="item_subject">Free</div>
<div class="item_price">$0<span> / mo</span></div>
<div class="item_content">
<ul>
<p>
<li>10 users included</li>
</p>
<p>
<li>2 GB of storage</li>
</p>
<p>
<li>Email support</li>
</p>
<p>
<li>Help center access</li>
</p>
</ul>
</div>
<a href="#" class="item_enter">Sign up for free</a>
</article>
<article class="section_item">
<div class="item_subject">Free</div>
<div class="item_price">$0<span> / mo</span></div>
<div class="item_content">
<ul>
<p>
<li>10 users included</li>
</p>
<p>
<li>2 GB of storage</li>
</p>
<p>
<li>Email support</li>
</p>
<p>
<li>Help center access</li>
</p>
</ul>
</div>
<a href="#" class="item_enter active">Sign up for free</a>
</article>
<article class="section_item">
<div class="item_subject">Free</div>
<div class="item_price">$0<span> / mo</span></div>
<div class="item_content">
<ul>
<p>
<li>10 users included</li>
</p>
<p>
<li>2 GB of storage</li>
</p>
<p>
<li>Email support</li>
</p>
<p>
<li>Help center access</li>
</p>
</ul>
</div>
<a href="#" class="item_enter active">Sign up for free</a>
</article>
</section>
</main>
<footer>
<div class="logo">
<i class="fa-brands fa-html5"></i>
<a href="">© 2007-2023</a>
</div>
<div class="feature">
<ul>
<li><p>Top Tutorials</p></li>
<li><p>HTML Tutorial</p></li>
<li><p>CSS Tutorial</p></li>
<li><p>JavaScript Tutorial</p></li>
<li><p>PHP Tutorial</p></li>
</ul>
</div>
<div class="feature">
<ul>
<li><p>HTML Reference</p></li>
<li><p>CSS Reference</p></li>
<li><p>JavaScript Reference</p></li>
<li><p>Java Reference</p></li>
<li><p>PHP Reference</p></li>
</ul>
</div>
<div class="feature">
<ul>
<li><p>HTML Examples</p></li>
<li><p>CSS Examples</p></li>
<li><p>JavaScript Examples</p></li>
<li><p>How To Examples</p></li>
<li><p>PHP Examples</p></li>
</ul>
</div>
</footer>
</body>
</html>
< CSS 전체코드 >
:root{
--text-color: rgb(238, 107, 107);
}
body{
margin: 0;
font-family: 'Abril Fatface', cursive;
font-family: 'Crete Round', serif;
font-family: 'PT Serif', serif;
}
a{
text-decoration-line: none;
color: var(--text-color);
}
nav{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: baseline;
padding: 20px;
border-bottom: 5px solid var(--text-color);
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
nav .nav_logo i{
font-size: 40px;
}
nav .nav_logo a{
font-family: 'Abril Fatface', cursive;
margin-left: 10px;
font-size: 40px;
color: var(--text-color)
}
nav .nav_logo a:hover{
color: rgb(201, 25, 69)
}
nav .nav_menu{
font-size: 20px;
margin: 0 auto;
font-weight: 900;
}
nav .nav_menu ul{
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
}
nav .nav_menu ul li{
padding: 8px 20px;
}
nav .nav_menu ul li:hover{
color: rgb(201, 25, 69);
}
nav .sign_in{
margin-left: 10px;
border: 3px solid var(--text-color);
border-radius: 20px;
padding: 15px;
font-size: 20px;
font-weight: 900;
}
nav .sign_in:hover{
background-color: var(--text-color);
color: white;
}
nav .nav_toggle{
display: none;
}
/* main area */
main .main_title{
padding: 10px 200px 10px 200px;
text-align: center;
font-size: 30px;
}
main .sub_title{
padding: 20px 200px 10px 200px;
text-align: center;
}
main section{
display: flex;
padding: 20px 200px 10px 200px;
justify-content: center;
margin: 20px auto;
}
main section .section_item{
border: 2px solid black;
border-radius: 20px;
height: 350px;
margin: 20px 40px;
text-align: center;
}
main section .item_subject{
width: 200px;
text-align: center;
border-bottom: 1px solid gray;
padding: 10px;;
font-size: 30px;
}
main section .item_price{
text-align: center;
padding: 10px;
font-size: 30px;
}
main section .item_price span{
font-size: 20px;
color: gray;
}
main section .item_content{
margin-bottom: 30px;
}
main section .item_content ul{
list-style-type: none;
text-align: center;
padding: 0;
margin: 0;
}
main section .item_enter{
border: 2px solid var(--text-color);
border-radius: 30px;
font-size: 20px;
font-weight: 800;
margin: 15px;
padding: 10px;
}
main section .item_enter:hover{
background-color: var(--text-color);
color: white;
}
main section .item_enter.active{
background-color: var(--text-color);
color: white;
}
main section .item_enter.active:hover{
background-color: rgb(235, 130, 81);
border: 2px solid rgb(235, 130, 81);
color: white;
}
/* footer area */
footer{
display: flex;
justify-content: space-around;
margin: 30px 20px;
border-top: 4px solid gray;
border-top-left-radius: 50px;
border-top-right-radius: 50px;
}
footer .logo{
display: flex;
flex-direction: column;
margin-top: 30px;
}
footer .feature ul{
list-style-type: none;
}
footer .feature ul li:first-child{
font-size: 20px;
font-weight: 700;
margin-bottom: 10px;
}
footer .feature ul li p{
margin: 0;
}
@media screen and (max-width:1000px){
body{
flex-direction: column;
align-items: center;
align-content: center;
}
nav{
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 60px;
}
nav .nav_logo{
position: absolute;
left: 10px;
top: 12px;
}
nav .nav_menu{
display: none;
text-align: center;
}
nav .nav_menu ul{
flex-direction: column;
margin-top: 20px;
padding: 0;
}
nav .sign_in{
display: none;
margin: 0;
}
main .main_title{
display: flex;
justify-content: center;
}
main section{
flex-direction: column;
align-items: center;
padding: 0;
}
main section .section_item{
width: 250px;
}
main section .section_item .item_subject{
width: 230px;
}
footer{
flex-direction: row;
align-items: center;
}
footer .feature ul{
padding: 0;
}
/* 토글키 활성화 기능 */
nav .nav_toggle{
display: block;
font-size: 30px;
padding: 8px 12px;
position: absolute;
right: 10px;
top: 12px;
}
nav .nav_menu.active{
display: flex;
margin: 50px 0;
}
nav .sign_in.active{
display: block;
}
}
< JavaScript 전체코드 >
const toggle = document.querySelector('.nav_toggle');
const menu = document.querySelector('.nav_menu');
const sign_in = document.querySelector('.sign_in');
toggle.addEventListener('click', ()=>{
menu.classList.toggle('active');
sign_in.classList.toggle('active');
})
'Web' 카테고리의 다른 글
[HTML/CSS] 간단한 반응형 웹(헤더) 만들기 + Toggle 이벤트 기능 (JavaScript활용) (0) | 2023.01.03 |
---|---|
[HTML/CSS] 간단한 웹페이지 만들기 - 3 <footer> (0) | 2022.12.30 |
[HTML/CSS] 간단한 웹페이지 만들기 - 2 <main> (0) | 2022.12.27 |
[HTML/CSS] 간단한 웹페이지 만들기 - 1 <nav> (0) | 2022.12.26 |