My Melody Kawaii

JAVASCRIPT/슬라이드 이펙트

슬라이드 이펙트 01 - 이미지를 하나씩 보이는 트렌지션 효과를 줬어요!

younajeong 2023. 4. 10. 18:31

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90

슬라이드 이펙트 01 : 트렌지션 효과

 

이미지 여러장을 하나씩 보일 수 있는 트렌지션 효과를 만들어 봤습니다! 

 

<완성본>

 

 

reset

/* reset */
@import url('https://webfontworld.github.io/hallym/Hallym.css');
@import url('https://webfontworld.github.io/suncheon/Suncheon.css');
@import url('https://webfontworld.github.io/Poppins/Poppins.css');
@import url('https://webfontworld.github.io/kt/YUniverse.css');
@import url('https://webfontworld.github.io/TheJamsil/TheJamsil.css');
@import url('https://webfontworld.github.io/NanumBarunGothic/NanumBarunGothic.css');
@import url('https://webfontworld.github.io/busan/Busan.css');
@import url('https://webfontworld.github.io/GothicA1/GothicA1.css');
@import url('https://webfontworld.github.io/jeju/JejuGothic.css');
@import url('https://webfontworld.github.io/amore/AritaBuri.css');

* {
    margin: 0;
    padding: 0;
    color: #fff;
}

*,*::before, *::after {
    box-sizing: border-box;
}
a{
    text-decoration: none;
    color: #222;
}
h1,h2,h3,h4,h5,h6 {
    font-weight: normal;
}
li, ul, ol {
    list-style: none;
}
img {
    vertical-align: top;
    width: 100%;
}
em {
    font-style: normal;
}
.font01 {
    font-family: 'Hallym';
}
.font02 {
    font-family: 'Suncheon';
}
.font03 {
    font-family: 'Poppins';
}
.font04 {
    font-family: 'YUniverse';
}
.font05 {
    font-family: 'TheJamsil';
}
.font06 {
    font-family: 'NanumBarunGot';
}
.font07 {
    font-family: 'Busan';
}
.font08 {
    font-family: 'GothicA1';
}
.font09 {
    font-family: 'JejuGothic';
}
.font10 {
    font-family: 'AritaBuri';
}
body {
    width: 100%;
    height: 100vh;
    overflow: hidden;
    background-position: center center;
    background-size: cover;
}
body.img01 {
    background-image: url(../img/sliderEffect01-min.jpg);
}
body.img02 {
    background-image: url(../img/sliderEffect02-min.jpg);
}
body.img03 {
    background-image: url(../img/sliderEffect03-min.jpg);
}
body.img04 {
    background-image: url(../img/sliderEffect04-min.jpg);
}
body.img05 {
    background-image: url(../img/sliderEffect05-min.jpg);
}
body.img06 {
    background-image: url(../img/sliderEffect06-min.jpg);
}
body.img07 {
    background-image: url(../img/sliderEffect07-min.jpg);
}
body.img08 {
    background-image: url(../img/sliderEffect08-min.jpg);
}
body.img09 {
    background-image: url(../img/sliderEffect09-min.jpg);
}
body.img10 {
    background-image: url(../img/sliderEffect10-min.jpg);
}
body::after {
    content: '';
    position: absolute;
    left: 0; top: 0;
    width: 100%;
    height: 100vh;
    background-color: rgba(63, 14, 30, 0.87);
    z-index: -1;
}
body.bg01::after {
    background-color: rgba(17, 97, 79, 0.65);
}
body.bg02::after {
    background-color: rgba(76, 102, 124, 0.87);
}
body.bg03::after {
    background-color: rgba(107, 131, 130, 0.947);
}
body.bg04::after {
    background-color: rgba(228, 185, 201, 0.87);
}
body.bg05::after {
    background-color: rgba(68, 12, 12, 0.87);
}
body.bg06::after {
    background-color:  rgba(12, 54, 68, 0.87);
}
body.bg07::after {
    background-color: rgba(14, 54, 61, 0.87);
}
body.bg08::after {
    background-color: rgba(14, 61, 22, 0.87);
}
body.bg09::after {
    background-color: rgba(14, 19, 48, 0.87);
}
body.bg10::after {
    background-color: rgba(63, 14, 30, 0.87);
}

CSS

/* header */
#header {
    position: absolute;
    left: 50%;
    top: 20px;
    transform: translateX(-50%);
    text-align: center;
}
#header h1 {
    margin-top: 0.3em;

}
#header ul {
    margin-top: 0.6em;
}
#header li {
    display: inline-block;
}
#header li a{
    color: #fff;
    border: 1px solid #fff;
    width: 30px;
    height: 30px;
    line-height: 30px;
    display: inline-block;
    border-radius: 50%;
}
#header li.active a {
    background-color: #fff;
    color: #000;
}

/* footer */
#footer {
    position: absolute;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    
}
#footer a {
    color: #fff;
    font-size: 14px;
}
#footer a:hover {
    text-decoration: underline;
}

 

전체적으로 reset부분은 저번 마우스 이펙트에서 했던 font와 body 전체 색상 부분을 가지고 왔습니다.

 

CSS는 슬라이드 이펙트와 어울리게끔 다시 만들어 주었습니다.

 

HTML & CSS

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>01. 슬라이드 이펙트</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/slider.css">
    <style>
        /* slider__wrap */
        .slider__wrap {
            width: 100%;
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .slider__img {
            position: relative;
            width: 800px;
            height: 450px;
            overflow: hidden;
        }
        .slider {
            position: absolute;
            left: 0;
            top: 0;
            transition: all 0.5s;
        }
        .slider::before {
            position: absolute;
            left: 5px;
            top: 5px;
            background-color: rgba(0,0,0,0.4);
            color: #fff;
            padding: 5px 10px;
        }
        .slider:nth-child(1)::before {content: '이미지1';}
        .slider:nth-child(2)::before {content: '이미지2';}
        .slider:nth-child(3)::before {content: '이미지3';}
        .slider:nth-child(4)::before {content: '이미지4';}
        .slider:nth-child(1)::before {content: '이미지1';}
        .slider:nth-child(1){z-index: 5;}
        .slider:nth-child(2){z-index: 4;}
        .slider:nth-child(3){z-index: 3;}
        .slider:nth-child(4){z-index: 2;}
        .slider:nth-child(5){z-index: 1;}
    </style>
</head>

    <!-- //header -->
<body class="img01 bg01 font01">
    <header id="header">
    <h1>Javascript sliderEffect01</h1>
    <p>슬라이드 이펙트 01</p>
    <ul>
        <li class="active"><a href="sliderEffect01.html">1</a></li>
        <li><a href="sliderEffect02.html">2</a></li>
        <li><a href="sliderEffect03.html">3</a></li>
        <li><a href="sliderEffect04.html">4</a></li>
        <li><a href="sliderEffect05.html">5</a></li>
        <li><a href="sliderEffect06.html">6</a></li>
    </ul>
    </header>

    <main id="main">
        <div class="slider__wrap">
            <div class="slider__img">
                <div class="slider"><img src="./img/sliderEffect01-min.jpg" alt="이미지1"></div>
                <div class="slider"><img src="./img/sliderEffect02-min.jpg" alt="이미지2"></div>
                <div class="slider"><img src="./img/sliderEffect03-min.jpg" alt="이미지3"></div>
                <div class="slider"><img src="./img/sliderEffect04-min.jpg" alt="이미지4"></div>
                <div class="slider"><img src="./img/sliderEffect05-min.jpg" alt="이미지5"></div>
            </div>
        </div>

    </main>
    <!-- //main -->

    <footer id="footer">
        <a href="mailto:jeongyouna_@naver.com">jeongyouna_@naver.com</a>
    </footer>  
    <!-- //footer -->

HTML

슬라이드 이펙트 HTML에서 01번째에 active를 준 후 main에 slider__wrap을 만든 후 그 안에 img를 만들어서 img 5개를 만들어 주었습니다.

CSS

slider__wrap과 img 그리고 slider와 slider에 before효과를 넣어주었습니다.

 

Javascript

<script>
        //선택자

        const sliderWrap = document.querySelector(".slider__wrap");
        const sliderImg = sliderWrap.querySelector(".slider__img");
        const slider = sliderWrap.querySelectorAll(".slider");

        let currentIndex = 0;               //현재 보이는 이미지 
        let sliderCount = slider.length;    //전체 이미지 갯수
        let sliderInterval = 3000;          //이미지 변경 간격 시간

        setInterval(() => {
            // 0 1 2 3 4 0 1 2 3 4 0   //courrentIndex 현재이미지
            // 1 2 3 4 0 1 2 3 4 0 1   //nextIndex 다음이미지
            
            let nextIndex = (currentIndex + 1) % sliderCount;       

            slider[currentIndex].style.opacity = "0"
            slider[nextIndex].style.opacity = "1";

            currentIndex = nextIndex;
            
            console.log(currentIndex)

        }, sliderInterval);
        
        //opacity: 사라지게 하는 효과 1이면 보이게 0이면 안보이게 이미지에서 많이 씀

        // slider[0].style.opacity = "0";      //첫번째 이미지를 안보이게
        // slider[1].style.opacity = "1";     //두번째 이미지를 보이게

        // slider[1].style.opacity = "1";      //두번째 이미지를 안보이게
        // slider[2].style.opacity = "2";     //세번째 이미지를 보이게

        // slider[2].style.opacity = "0";      //세번째 이미지를 안보이게
        // slider[3].style.opacity = "1";     //네번째 이미지를 보이게

        // slider[3].style.opacity = "0";      //네번째 이미지를 안보이게
        // slider[4].style.opacity = "1";     //다섯번째 이미지를 보이게

        // slider[4].style.opacity = "0";      //다섯번째 이미지를 안보이게
        // slider[0].style.opacity = "1";     //첫번째 이미지를 보이게

    </script>

javascript

  • 먼저 const로 선택자로 sliderWrap과 sliderImg, slider로 선택자를 만들어 줍니다.
  • 그리고 현재 보이는 이미지 currentIndex = 0 으로 설정하고 전체 보이는 이미지 갯수를 입력해 줍니다.
  • sliderInterval을 3000으로 주어 이미지 변경 시간을 3초로 지정해 줍니다.
  • 첫번째 이미지가 사라지고 두번째 이미지가 보이게 하기위해 slider[0].styley.opacity = "0";으로 설정 해주고 두번째 이미지 를 1로 선택해 주면 opactiy로 인해 사라지는 효과가 완성됩니다.
  • 차례대로 순서를 보면 0,1,2,3,4,0,1,2,3,4라는 알고리즘을 찾아 볼 수 있습니다.
  • 현재 이미지가 0,1,2,3,4 로 늘어 날때 다음 이미지가 하나씩 더해져서 1,2,3,4,0으로 나타낼 수 있습니다.
  • 그리하여 변수 let 을 선언해서 nextIndex= 현재 이미지에서 + 1 씩 되는데 전체 이미지 갯수의 나머지 값을 구하면 nextIndex값이 나올 수 있습니다.
  • slider[0].styley.opacity = "0"; slider[1].styley.opacity = "1"; 에 [0],[1]안에 currentIndex라는 현재의 값과 nextIndex라는 다음 값을 나타내는 변수명을 넣어준 후 currentIndex=nextIndex로 넘겨주면 슬라이드가 넘어갈 수 있는 효과를 완성할 수 있습니다.

GSAP

 setInterval(() => {
            let nextIndex = (currentIndex + 1) % sliderCount;

            gsap.to(slider[currentIndex], { // 현재 이미지를 서서히 사라지게 함
                opacity: 0,
                duration: 1,
                ease: "power1.out"
            });

            gsap.to(slider[nextIndex], { // 다음 이미지를 서서히 나타나게 함
                opacity: 1,
                duration: 1,
                ease: "power1.out",
                delay: 1 // 현재 이미지가 사라지는 애니메이션이 끝나고 1초 후에 시작됨
            });

                currentIndex = nextIndex;
        }, sliderInterval);

 

gsap

  • gsap.to()함수를 사용해서  opactiy:0 현재 이미지를 서서히 사라지게 하고  opactiy:1 로 다음이미지가 나타나게 합니다.
  • duration 속성은 애니메이션의 지속시간 ease 속성은 애니메이션의 이징 함수르르 지정합니다.
  • delay 속성은 현재 이미지가 서서히 사라지는 애니메이션이 끝난 후에 다음 이미지로 서서히 나타나게 하는데 사용됩니다.

 

jQuery

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
    <script>
        setInterval(() => {
        let nextIndex = (currentIndex + 1) % sliderCount;

        $(slider[currentIndex]).animate({ // 현재 이미지를 서서히 사라지게 함
        opacity: 0
        }, 1000, "easeInOutQuad");

        $(slider[nextIndex]).animate({ // 다음 이미지를 서서히 나타나게 함
        opacity: 1
        }, 1000, "easeInOutQuad");

        currentIndex = nextIndex;
    }, sliderInterval); 
    </script>

jQuery

  • setInterval 함수를 사용하여 일정한 간격으로 이미지가 바뀔 수 있습니다.
  • jQuery의 animate 함수를 사용하여 현재 이미지를 서서히 사라지게 하고 슬라이더가 깜빡이거나 부자연스럽게 바뀌는 것을 방지하고자 효과를 부여합니다.