πŸ“„ μš°μ•„ν•œν˜•μ œλ“€

μ΅œμ€€ν˜„Β·2022λ…„ 7μ›” 26일
0
post-thumbnail
μ œμž‘κΈ°κ°„ 22.06.12 ~ 22.06.14 (3일 μ†Œμš”)
μ‚¬μš© μ–Έμ–΄ html, css, jquery
μ‚¬μš© ν”ŒλŸ¬κ·ΈμΈ gsap, swiper
λΆ„λ₯˜ pc, mobile, 클둠코딩


βœ” 메인 μŠ¬λΌμ΄λ“œ

πŸ’¬ μž‘μ—…ν•˜κΈ° μ „ μš°μ•„ν•œν˜•μ œλ“€ νŽ˜μ΄μ§€ 메인 μŠ¬λΌμ΄λ“œλ₯Ό μ‚΄νŽ΄λ³Έ κ²°κ³Ό, μŠ¬λΌμ΄λ“œ 17κ°œκ°€ μƒˆλ‘œκ³ μΉ¨ ν•  λ•Œ λ§ˆλ‹€ μŠ¬λΌμ΄λ“œ 5개λ₯Ό μ„ νƒν•˜μ—¬ 보여주고 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ–Š 17개 μŠ¬λΌμ΄λ“œ 쀑 랜덀으둜 5개λ₯Ό 뽑아 μŠ¬λΌμ΄λ“œ λ§Œλ“€κΈ°

πŸ“Œ 17개 μŠ¬λΌμ΄λ“œλ₯Ό html에 μž‘μ„±

<section class="swiper sc-mainSlide">
            <h2 class="blind">메인 μŠ¬λΌμ΄λ“œ</h2>
            <div class="swiper-wrapper">
                <div class="swiper-slide">
                    <a href="" class="link-slide slide-intro01">
                        <div class="img-box left"><img src="./assets/images/slide_intro01.jpg" alt="λˆ„κ΅°κ°€ μ§€μΌœλ³΄κ³  μžˆλ‹€?"></div>
                        <div class="txt-box">
                            <span class="default-txt">μš°μ•„ν•œν˜•μ œλ“€μ΄ μ•Œκ³  μ‹Άλ‹€</span>
                            <h3 class="desc">λˆ„κ΅°κ°€<span class="fiction">μ§€μΌœλ³΄κ³  μžˆλ‹€?</span></h3>
                            <span class="cate">νšŒμ‚¬ μ†Œκ°œ ></span>
                        </div>
                    </a>
                </div>
              .
              .
              .
              .
              .
              <div class="swiper-slide">
                    <a href="" class="link-slide slide-more01">
                        <div class="img-box small"><img src="./assets/images/slide_more01.jpg" alt="이게 무슨 일이야! 컨퍼런슀"></div>
                        <div class="txt-box black">
                            <span class="default-txt">μš°μ•„ν•œν˜•μ œλ“€μ΄ μ•Œκ³  μ‹Άλ‹€</span>
                            <h3 class="desc">이게 무슨 일이야!<br><span class="fiction">컨퍼런슀</span></h3>
                            <span class="cate">μžμ„Ένžˆ 보기 ></span>
                        </div>
                    </a>
                </div>
            </div>
            <div class="swiper-pagination"></div>
        </section>

πŸ“Œ λ°°μ—΄ 생성

var numArray = [];
var slideArray = [];

πŸ’¬ 5개의 λ‚œμˆ˜λ₯Ό λ„£μ–΄ 쀄 λ°°μ—΄ numArray와 5개의 μŠ¬λΌμ΄λ“œλ₯Ό λ„£μ–΄ 쀄 μŠ¬λΌμ΄λ“œ λ°°μ—΄ slideArrayλ₯Ό μƒμ„±ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ μŠ¬λΌμ΄λ“œ 배열에 랜덀으둜 μŠ¬λΌμ΄λ“œ λ„£κΈ°

('.sc-mainSlide .swiper-slide').each(function(){
      var randomSlide = Math.floor(Math.random() * 17) + 1;
      if(!numArray.includes(randomSlide)) {
          numArray.push(randomSlide);
          slideArray.push($('.sc-mainSlide .swiper-slide:nth-child('+randomSlide+')').html());
      }

πŸ’¬ λ°˜λ³΅λ¬Έμ„ μ΄μš©ν•˜μ—¬ μŠ¬λΌμ΄λ“œ 17κ°œμ— 맞좰 1~17κΉŒμ§€ λ‚œμˆ˜ 값을 μƒμ„±ν•˜μ—¬ randomSlide λ³€μˆ˜μ— λ„£μ–΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ’¬ 쀑볡체크λ₯Ό ν•΄μ£ΌκΈ° μœ„ν•΄ numArray λ³€μˆ˜ μ•ˆμ— 방금 μƒμ„±ν•œ randomSlide 값이 ν¬ν•¨λ˜λŠ”μ§€ 쑰건문을 κ±Έμ–΄μ£Όκ³  μ—†λ‹€λ©΄, numArray 배열에 randomSlide 값을 pushλ₯Ό μ΄μš©ν•˜μ—¬ λ„£μ–΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ’¬ λ§ˆμ°¬κ°€μ§€λ‘œ html상 randomSlide κ°’ 번째 μŠ¬λΌμ΄λ“œλ₯Ό μ°Ύμ•„ κ·Έ html을 ν†΅μ§Έλ‘œ SlideArray 배열에 λ„£μ–΄μ€λ‹ˆλ‹€.

πŸ“Œ 5개의 μŠ¬λΌμ΄λ“œλ₯Ό λ„£μ—ˆλ‹€λ©΄?

$('.sc-mainSlide .swiper-slide').each(function(){
      if(numArray.length == 5) {
          $('.sc-mainSlide .swiper-wrapper').empty();
          $(numArray).each(function(i){
              $('.sc-mainSlide .swiper-wrapper').append('<div class="swiper-slide"></div>')
              $('.sc-mainSlide .swiper-slide:last-child').append(slideArray[i]);
          })
      }
  })

πŸ’¬ λ§Œμ•½ numArray에 λ“€μ–΄μžˆλŠ” λ‚œμˆ˜κ°€ 5κ°œκ°€ λœλ‹€λ©΄, html에 λ“€μ–΄μžˆλŠ” 17개의 μŠ¬λΌμ΄λ“œλ₯Ό empty()을 μ΄μš©ν•˜μ—¬ μ „λΆ€ λΉ„μ›Œμ£Όκ³ , numArray의 길이만큼 λ°˜λ³΅λ¬Έμ„ 돌렀 μƒˆλ‘œμš΄ μŠ¬λΌμ΄λ“œ μ˜μ—­μ„ μƒμ„±ν•˜κ³  μ €μž₯ν•΄λ‘” SlideArray의 μŠ¬λΌμ΄λ“œλ“€μ„ appendλ₯Ό μ΄μš©ν•˜μ—¬ ν•˜λ‚˜μ”© μ±„μ›Œ λ„£μ—ˆμŠ΅λ‹ˆλ‹€.

πŸ”˜ μ΅œμ’…μ½”λ“œ

var numArray = [];
var slideArray = [];
$('.sc-mainSlide .swiper-slide').each(function(){
    var randomSlide = Math.floor(Math.random() * 17) + 1;
    if(!numArray.includes(randomSlide)) {
        numArray.push(randomSlide);
        slideArray.push($('.sc-mainSlide .swiper-slide:nth-child('+randomSlide+')').html());
    }
    if(numArray.length == 5) {
        $('.sc-mainSlide .swiper-wrapper').empty();
        $(numArray).each(function(i){
            $('.sc-mainSlide .swiper-wrapper').append('<div class="swiper-slide"></div>')
            $('.sc-mainSlide .swiper-slide:last-child').append(slideArray[i]);
        })
    }
})

πŸ–Š ν…μŠ€νŠΈλ₯Ό ν•˜λ‚˜μ”© 잘라 순차적으둜 λ‚˜νƒ€λ‚΄κΈ°

πŸ’¬ μš°μ•„ν•œν˜•μ œλ“€ 메인 μŠ¬λΌμ΄λ“œ 제λͺ© 쀑 λ‘˜μ§Έμ€„λΆ€ν„° ν•œ κΈ€μžμ”© 순차적으둜 λ‚˜νƒ€λ‚˜λŠ” λͺ¨μŠ΅μ„ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ ν•œ κΈ€μžμ”© λ³΄μ—¬μ§ˆ λΆ€λΆ„ 클래슀 μ£ΌκΈ°

<h3 class="desc">λˆ„κ΅°κ°€<span class="fiction">μ§€μΌœλ³΄κ³  μžˆλ‹€?</span></h3>
.sc-mainSlide .txt-box .desc .fiction {
  display: none;
}

πŸ’¬ λͺ¨λ“  μŠ¬λΌμ΄λ“œλ§ˆλ‹€ ν•œ κΈ€μžμ”© λ³΄μ—¬μ§ˆ 뢀뢄을 class="fiction으둜 μ„€μ •ν•˜μ—¬ λ”°λ‘œ κ΅¬λΆ„ν•˜μ˜€κ³ , display:none을 ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

πŸ“Œ ν•œ κΈ€μžμ”© μž˜λΌμ„œ html에 λ„£κΈ°

var text = $('.swiper-slide-active').find('.fiction').text().split("");
$('.swiper-slide-active').find('.desc').append('<span class="fade"></span>')
$(text).each(function(i){
    $('.swiper-slide-active').find('.fade').append('<i class="fade-txt'+i+'">'+text[i]+'</i>');
})

πŸ’¬ htmlμ—μ„œ fiction 클래슀λ₯Ό μ°Ύμ•„ ν…μŠ€νŠΈλ₯Ό split("")을 μ΄μš©ν•˜μ—¬ ν•œ κΈ€μžμ”© 잘라 textλ³€μˆ˜μ— λ„£μ–΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ’¬ κ·Έ ν›„, ν™œμ„±ν™”λœ μŠ¬λΌμ΄λ“œ .swiper-slide-activeμ—μ„œ 제λͺ© λΆ€λΆ„ 뒀에 fade 클래슀λ₯Ό 가진 span νƒœκ·Έλ₯Ό append을 μ΄μš©ν•˜μ—¬ λ„£μ–΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ’¬ 자λ₯Έ text의 길이 만큼 λ°˜λ³΅λ¬Έμ„ 돌렀 fade클래슀λ₯Ό 가진 span νƒœκ·Έμ— fade-txt클래슀λ₯Ό 가진 iνƒœκ·Έλ‘œ κΈ€μž ν•˜λ‚˜ν•˜λ‚˜ μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

πŸ“Œ setInterval둜 opacity μ‘°μ •ν•˜κΈ°

var i = 0;
setInterval(function(){
    if(i < text.length) {
        $('.swiper-slide-active').find('.fade-txt'+i+'').animate({opacity: "1"});
            i++;
        } else {
            return false;
        }
    }, 200)

πŸ’¬ fade-txt의 μˆœμ„œλ₯Ό μž‘μ•„μ£ΌκΈ° μœ„ν•΄ i λ³€μˆ˜λ₯Ό μƒμ„±ν•˜μ—¬ 0으둜 μ΄ˆκΈ°ν™” ν•΄μ£Όκ³ , 0.2s둜 μž‘λ™ν•˜λŠ” setInterval을 생성, text의 길이만큼 fade-txt의 i번째 μš”μ†Œλ₯Ό opacity:1둜 λ³€κ²½ν•΄ μ€€ ν›„ i++을 ν•΄μ£Όμ—ˆκ³ , iκ°€ text의 길이보닀 λ†’μ•„μ§€κ²Œ 되면 setInterval을 μ’…λ£Œν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ μŠ¬λΌμ΄λ“œκ°€ λ„˜μ–΄κ°ˆ λ•Œλ§ˆλ‹€ μž‘λ™

 function fadeText() {
      $('.swiper-slide .fade').remove();
      var text = $('.swiper-slide-active').find('.fiction').text().split("");
      $('.swiper-slide-active').find('.desc').append('<span class="fade"></span>')
      $(text).each(function(i){
          $('.swiper-slide-active').find('.fade').append('<i class="fade-txt'+i+'">'+text[i]+'</i>');
      })
      var i = 0;
      setInterval(function(){
              if(i < text.length) {
                  $('.swiper-slide-active').find('.fade-txt'+i+'').animate({opacity: "1"});
                  i++;
              } else {
                  return false;
              }
      }, 200)
  }

πŸ’¬ μ΅œμ’…μ μœΌλ‘œ μ™„μ„±ν•œ 이 μ½”λ“œλ₯Ό fadeText()λΌλŠ” λ³€μˆ˜λͺ…μœΌλ‘œ ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ£Όκ³ , μŠ¬λΌμ΄λ“œκ°€ 변경될 λ•Œλ§ˆλ‹€ fade 클래슀λ₯Ό 가진 spanνƒœκ·Έκ°€ μƒμ„±λ ν…Œλ‹ˆ ν•¨μˆ˜ μ‹œμž‘ν•˜μžλ§ˆμž remove둜 μ΄ˆκΈ°ν™”λ₯Ό ν•΄μ£ΌλŠ” μ½”λ“œλ₯Ό μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

on: {
    slideChange: function(){
        setTimeout(function(){
            fadeText();
        })
    }
},                    

πŸ’¬ λ©”μΈμŠ¬λΌμ΄λ“œ swiperμ•ˆμ— SlideChange λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ setTimeout으둜 fadeText() ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ˜€μŠ΅λ‹ˆλ‹€.


❗ 문제점 λ°œμƒ

πŸ’¬ μ΄λ ‡κ²Œ ν•œ κ²°κ³Ό μŠ¬λΌμ΄λ“œκ°€ λ„˜μ–΄κ°ˆ λ•Œ μ›ν•˜λŠ” λŒ€λ‘œ 잘 μž‘λ™ν•˜μ§€λ§Œ λΉ λ₯΄κ²Œ λ„˜κΈΈ λ•Œ 이미 μ‹€ν–‰λœ fadeText()와 μŠ¬λΌμ΄λ“œκ°€ λ„˜μ–΄κ°€μ„œ μ‹€ν–‰λœ fadeText()κ°€ κ²Ήμ³μ„œ μ μš©λ˜λŠ” 문제점이 λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.

πŸ“Œ μˆ˜μ •

πŸ’¬ 이λ₯Ό μˆ˜μ •ν•˜κΈ° μœ„ν•΄μ„œ μŠ¬λΌμ΄λ“œκ°€ λ„˜μ–΄κ°ˆ λ•Œ 이미 μ‹€ν–‰λ˜κ³  μžˆλŠ” fadeText()ν•¨μˆ˜λ₯Ό μ’…λ£Œν•˜λŠ” λ©”μ„œλ“œλ₯Ό λ„£μ–΄μ•Ό ν•œλ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

var isStop = false;
var textAni = setInterval(function(){
          if(!isStop) {
              if(i < text.length) {
                  $('.swiper-slide-active').find('.fade-txt'+i+'').animate({opacity: "1"});
                  i++;
              } else {
                  return false;
              }
          } else {
              clearInterval(textAni);
              isStop = false;
              fadeText();
          }
      }, 200)
--------------------------------------------------------------------------------------------
on: {
	slideChange: function(){
		isStop = true;
	}
},

πŸ’¬ κ·Έλž˜μ„œ isStopμ΄λΌλŠ” λ³€μˆ˜λ₯Ό μƒμ„±ν•˜μ—¬ false둜 λ‹΄κ³ , opacityκ°€ μ‘°μ •λ˜λŠ” setInteval을 λ³€μˆ˜ textAni둜 μ„€μ •ν•΄ μ€€ ν›„, isStop이 false인 경우 ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜κ²Œ μ μš©ν•˜κ³  true인 경우 textAniκ°€ μ’…λ£Œλ˜κ²Œ clearInterval을 μ‚¬μš©ν•˜κ³ , isStop = false둜 λ³€κ²½ν•œ ν›„ fadeText()λ₯Ό μ μš©ν•˜κ²Œ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

πŸ’¬ swiper에 slideChange λ©”μ„œλ“œμ—λŠ” μŠ¬λΌμ΄λ“œκ°€ 변경될 λ•Œ isStop = true둜 λ³€κ²½ν•˜μ—¬ κ·Έ μ¦‰μ‹œ fadeText() ν•¨μˆ˜κ°€ μ’…λ£Œλ˜κ²Œ λ§Œλ“€μ–΄μ„œ λ¬Έμ œμ μ„ ν•΄κ²°ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€!

πŸ”˜ μ΅œμ’…μ½”λ“œ

var isStop = false;
  function fadeText() {
      $('.swiper-slide .fade').remove();
      var text = $('.swiper-slide-active').find('.fiction').text().split("");
      $('.swiper-slide-active').find('.desc').append('<span class="fade"></span>')
      $(text).each(function(i){
          $('.swiper-slide-active').find('.fade').append('<i class="fade-txt'+i+'">'+text[i]+'</i>');
      })
      var i = 0;
      var textAni = setInterval(function(){
          if(!isStop) {
              if(i < text.length) {
                  $('.swiper-slide-active').find('.fade-txt'+i+'').animate({opacity: "1"});
                  i++;
              } else {
                  return false;
              }
          } else {
              clearInterval(textAni);
              isStop = false;
              fadeText();
          }
      }, 200)
  }
----------------------------------------------------------------------------------------------------
var mainSlide = new Swiper(".sc-mainSlide", {
      pagination: {
          el: ".swiper-pagination",
      },
      autoplay: {
          delay: 7000,
      },
      on: {
          slideChange: function(){
              isStop = true;
          }
      },
      loop: true
  });



βœ” keyframeκ³Ό clone을 μ΄μš©ν•œ λ¬΄ν•œ 둀링

πŸ’¬ μš°μ•„ν•œν˜•μ œλ“€ νŽ˜μ΄μ§€ ν•˜λ‹¨ κΈ€κΌ΄ λΆ€λΆ„μ—μ„œ 컨텐츠듀이 λŠμ΄μ§€ μ•Šκ³  κ³„μ†ν•΄μ„œ μ˜†μœΌλ‘œ λ‘€λ§λ˜λŠ” λͺ¨μŠ΅μ„ λ³Ό 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ slide-font html μž‘μ„±

<div class="slide-font">
	<ul class="font-area">
		<li class="font-item hanna11"><h3 class="font-title">ν•œλ‚˜λŠ”μ—΄ν•œμ‚΄μ²΄</h3></li>
		<li class="font-item jua"><h3 class="font-title">주아체</h3></li>
		<li class="font-item dohyeon"><h3 class="font-title">λ„ν˜„μ²΄</h3></li>
		<li class="font-item yeonsung"><h3 class="font-title">연성체</h3></li>
		<li class="font-item kiranghaerang"><h3 class="font-title">κΈ°λž‘ν•΄λž‘μ²΄</h3></li>
		<li class="font-item hannaAir"><h3 class="font-title">ν•œλ‚˜μ²΄ Air</h3></li>
		<li class="font-item hannaPro"><h3 class="font-title">ν•œλ‚˜μ²΄ Pro</h3></li>
		<li class="font-item euljiro"><h3 class="font-title">μ„μ§€λ‘œμ²΄</h3></li>
		<li class="font-item euljiro10year"><h3 class="font-title">μ„μ§€λ‘œ 10년후체</h3></li>
		<li class="font-item euljiroorae"><h3 class="font-title">μ„μ§€λ‘œ 였래였래체</h3></li>
	</ul>
</div>

πŸ’¬ htmlμ—λŠ” script둜 λ³΅μ œν•˜κΈ° μœ„ν•΄μ„œ ν•œ λ©μ–΄λ¦¬λ§Œ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

πŸ“Œ font-area clone()을 μ΄μš©ν•˜μ—¬ 볡제/μΆ”κ°€

var fontItemClone = $('.font-area').clone();
  fontItemClone.addClass('dup');
  $('.slide-font').append(fontItemClone);

πŸ’¬ fontItemClone λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄ font 컨텐츠듀을 clone()을 μ΄μš©ν•˜μ—¬ λ³΅μ œν•΄ λ„£μ–΄μ£Όμ—ˆκ³  dup 클래슀λ₯Ό μΆ”κ°€ν•˜μ—¬ μ΅œμ’… λΆ€λͺ¨μΈ slide-font 뒀에 μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€

πŸ“Œ keyframe을 μ΄μš©ν•˜μ—¬ λ¬΄ν•œλ‘€λ§

.sc-font .font-area {
    display: inline-flex;
    animation: fontSlide 40s linear infinite;
}
.sc-font .font-area.dup {
    animation: fontSlideDup 40s linear infinite;
}
----------------------------------------------------------------------
@keyframes fontSlide {
    0% {
        transform: translateX(0);
    }
    50% {
        transform: translateX(-100%);
    }
    50.01%{
        transform: translateX(100%);
    }
    100%{
        transform: translateX(0);
    }
}
@keyframes fontSlideDup {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(-200%);
    }
}

πŸ’¬ μ›λž˜ 있던 font-areaλŠ” fontSlide keyframe으둜 μ• λ‹ˆλ©”μ΄μ…˜μ— μ ˆλ°˜λ™μ•ˆ XμΆ•μœΌλ‘œ -100%둜 μ΄λ™ν•˜κ²Œ ν•˜μ—¬ 화면에 μ•ˆλ³΄μ—¬μ§ˆ λ•Œ λ°”λ‘œ XμΆ• 100%둜 μ΄λ™ν•˜μ—¬ λ‹€μ‹œ 0으둜 μ„€μ •ν•΄ 제자리고 λŒμ•„μ˜€κ²Œ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.


πŸ’¬ 볡제된 .dup은 fontSlideDup keyfram으둜 XμΆ• -200%둜 μ„€μ •ν•˜μ—¬ μžμ—°μŠ€λŸ½κ²Œ λ¬΄ν•œλ‘€λ§μ΄ λ˜λ„λ‘ μ™„μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€!

0개의 λŒ“κΈ€