원생 JS 모 바 일 웹 윤방송 도 상세 설명 실현(Tween 알고리즘 과 결합 하여 바퀴 만 들 기)

머리말
모두 가 알 고 있 을 것 이 라 고 믿 습 니 다.이동 단의 윤 방 도 는 우리 가 흔히 볼 수 있 는 수요 입 니 다.우리 의 가장 빠 른 실현 방식 은 흔히 제3자 의 코드 를 사용 합 니 다.예 를 들 어 swiper 입 니 다.그러나 비교적 복잡 한 윤 방 도 수 요 를 만 났 을 때 속수무책 이 고 어떻게 고 쳐 야 할 지 모 릅 니 다.      
그래서 우 리 는 각종 복잡 하고 변화 가 많은 수요 에 적응 하기 위해 스스로 바퀴 를 만들어 야 한다.  또 하 나 는 자신 이 쓴 코드 에 bug 가 있 으 면 쉽게 복구 되 고 자신 에 대한 향상 도 크다.
swiper 소스 코드 를 읽 지 않 는 과정 에서 저 는 간단 하면 서도 실 용적 이지 않 은 모 바 일 엔 드 윤 방 도 를 실현 하려 고 했 습 니 다.몇 시간 동안 의 사고 와 실천 을 통 해 드디어 실현 되 었 습 니 다(그림 참조).

모 바 일 엔 드 의 윤 방 도 를 실현 하 는 것 은 pc 보다 복잡 하 며 주로 다음 과 같은 몇 가지 측면 에 나타난다.
     1.윤파 도 는 너비/dpr 의 화면 에 적응 해 야 한다. 
     2.touch 관련 이벤트 사용 
     3.기종 에 따라 터치 이벤트 에 대한 지원 이 다 르 기 때문에 호환성 문제 가 있 을 수 있 습 니 다. 
     4.손가락 으로 그림 의 일부 거 리 를 이동 하고,남 은 거 리 는 자동 완성 
     5.자동 완성 거 리 는 ease 시간 곡선 이 있어 야 합 니 다. 
그러나 프로 그래 밍 으로 문 제 를 해결 하 는 사고방식 은 많 지 않다.
우 리 는 윤 방 도 를 사용 할 때 자세히 관찰 할 수 있 고 현상 을 통 해 본질 을 볼 수 있다.
  • 우 리 는 윤 방 도 를 사용 할 때 자세히 관찰 할 수 있 고 현상 을 통 해 본질 을 볼 수 있다. 
  • 손가락 을 그림 에 놓 고 손가락 을 왼쪽으로 또는 오른쪽으로 이동 하면 그림 도 이에 따라 이동한다. 
  • 손가락 이동 거리 가 적 을 때 그림 은 자동 으로 위 치 를 복원 합 니 다.손가락 이동 거리 가 길 면 자동 으로 다음 으로 전환 합 니 다. 
  • 손가락 이 왼쪽으로 이동 하거나 오른쪽으로 빨리 이동 할 때 다음 으로 전환 합 니 다. 
  • 사진 윤 방 은 무한 순환 이 므 로 우 리 는 사용 해 야 한다.  3,1,2,3,1 의 방식 으로 N+2 장의 그림 을 통 해 N 장의 그림 을 무한 순환 순환 재생 할 수 있 습 니 다. 
  • 우 리 는 현상 을 분석 함으로써 기본 적 인 실현 방안 을 제시 할 수 있다.
         1.손가락 터치 이 벤트 는 터치 스타트 터치 모 브 터치 엔 드 3 개 이 벤트 를 통 해 가능 
         2.손가락 터치 스타트 를 할 때 우 리 는 손가락 의 x 좌 표를 기록 해 야 한다.  touch 의 pageX 속성 사용 하기;그리고 이 시간 에... 
         3.손가락 터치 모 브 를 할 때 도 pageX 를 기록 하고 누적 이동 거 리 를 기록 해 야 합 니 다 moveX 
         4.손가락 이 떠 날 때 시간 점 을 기록 하고 앞의 두 단계 로 계 산 된 x 방향 으로 이동 하 는 거리,시간 점 의 차이 
         5.x 방향 이동 거 리 를 비교 하여 이동 방향 과 다음 그림 으로 전환 해 야 하 는 지 판단 한다.시간 에 따라 사용자 가 좌우 스 캔 을 했 는 지 여 부 를 판단 하 다. 
         6.모 바 일 이미 지 는 translate3d 를 사용 하여 구현 할 수 있 으 며 하드웨어 가속 을 켤 수 있 습 니 다. 
         7.거 리 를 이동 하려 면 easeOut 효과 가 필요 합 니 다.저 희 는 Tween 알고리즘 중의 easeOut 을 사용 하여 매번 이동 하 는 거 리 를 실현 할 수 있 습 니 다.물론 js 설정 transition 애니메이션 도 사용 할 수 있 습 니 다. 
    원본 코드 구현(참고 만 제공):
    헤드 스타일
    
    <head> 
     <meta charset="UTF-8"> 
     <meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5"> 
     <title>      </title> 
     <style> 
     * { 
     box-sizing: border-box; 
     margin: 0; 
     padding: 0 
     } 
     .banner { 
     overflow: hidden; 
     width: 100%; 
     height: 300px 
     } 
     .banner .img-wrap { 
     position: relative; 
     height: 100% 
     } 
     .banner img { 
     display: block; 
     position: absolute; 
     top: 0; 
     width: 100%; 
     height: 100% 
     } 
     </style> 
    </head> 
    HTML 구조
    
    <div class="banner"> 
     <div class="img-wrap" id="imgWrap"> 
     <img src="images/banner_3.jpg" data-index="-1"> 
     <img src="images/banner_1.jpg" data-index="0"> 
     <img src="images/banner_2.jpg" data-index="1"> 
     <img src="images/banner_3.jpg" data-index="2"> 
     <img src="images/banner_1.jpg" data-index="3"> 
     </div> 
    </div> 
    JS 코드 1,easeOut 애니메이션 이동,
    여기   HTML Element.prototype.tweenTranslateXAnimate 는 모든 HTML 요소 류 를 확장 하 는 tweenTranslateXAnimate 방법 입 니 다.
    거 리 를 이동 하려 면 타이머 로 우리 가 완성 할 수 있 도록 도와 야 합 니 다.이 반복 되 는 작업 은
    
    <script> 
     HTMLElement.prototype.tweenTranslateXAnimate = function (start, end, callback) { 
     var duration = 50; 
     var t = 0; 
     var vv = end - start; 
     var Tween = { 
     Quad: { 
     easeOut: function (t, b, c, d) { 
      return -c * (t /= d) * (t - 2) + b; 
     } 
     } 
     }; 
     
     this.timer = setInterval(function () { 
     var dis = start + Tween.Quad.easeOut(++t, 0, vv, duration); 
     this.style.transform = 'translate3d(' + dis + 'px, 0, 0)'; 
     if (vv > 0 && parseInt(this.style.transform.slice(12)) >= end) { 
     this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; 
     clearInterval(this.timer); 
     callback && callback(); 
     } 
     if (vv < 0 && parseInt(this.style.transform.slice(12)) <= end) { 
     this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; 
     clearInterval(this.timer); 
     callback && callback(); 
     } 
     }.bind(this), 4); 
     } 
    </script> 
    터치 이벤트 부분
    
    <script> 
     ~function () { 
     var lastPX = 0; //         x  ,                   
     var movex = 0; //     move x    
     var imgWrap = document.getElementById('imgWrap'); 
     var startX = 0; //          x   
     var endX = 0; //           x     
     var imgSize = imgWrap.children.length - 2; //      
     var t1 = 0; //           
     var t2 = 0; //           
     var width = window.innerWidth; //        
     var nodeList = document.querySelectorAll('#imgWrap img'); //           NodeList 
     
     //         left ,    querySelectorAll   NodeList,    forEach   
     nodeList.forEach(function (node, index) { 
     node.style.left = (index - 1) * width + 'px'; 
     }); 
     
     /** 
     *          tIndex       
     * @param {number} tIndex           
     * */ 
     function toIndex(tIndex) { 
     var dis = -(tIndex * width); 
     var start = parseInt(imgWrap.style.transform.slice(12)); 
     //      
     imgWrap.tweenTranslateXAnimate(start, dis, function () { 
     setTimeout(function () { 
      movex = dis; 
      if (tIndex === imgSize) { 
      imgWrap.style.transform = 'translate3d(0, 0, 0)'; 
      movex = 0; 
      } 
      if (tIndex === -1) { 
      imgWrap.style.transform = 'translate3d(' + width * (1 - imgSize) + 'px, 0, 0)'; 
      movex = -width * (imgSize - 1); 
      } 
     }, 0); 
     }); 
     } 
     
     /** 
     *          ,   touchstart, touchend, touchmove, touchcancel 
     * @param {Event} evt            js      
     * */ 
     function touch(evt) { 
     var touch = evt.targetTouches[0]; 
     var tar = evt.target; 
     var index = parseInt(tar.getAttribute('data-index')); 
     if (evt.type === 'touchmove') { 
     var di = parseInt(touch.pageX - lastPX); 
     endX = touch.pageX; 
     movex += di; 
     imgWrap.style.webkitTransform = 'translate3d(' + movex + 'px, 0, 0)'; 
     lastPX = touch.pageX; 
     } 
     if (evt.type === 'touchend') { 
     var minus = endX - startX; 
     t2 = new Date().getTime() - t1; 
     if (Math.abs(minus) > 0) { //       
      if (Math.abs(minus) < width * 0.4 && t2 > 500) { //       ,  ! 
      toIndex(index); 
      } else { //     ,    
      console.log(minus); 
      if (Math.abs(minus) < 20) { 
      console.log('    ' + minus); 
      toIndex(index); 
      return; 
      } 
      if (minus < 0) { // endX < startX,    ,     
      toIndex(index + 1) 
      } else { // endX > startX ,    ,      
      toIndex(index - 1) 
      } 
      } 
     } else { //       
     
     } 
     } 
     if (evt.type === 'touchstart') { 
     lastPX = touch.pageX; 
     startX = lastPX; 
     endX = startX; 
     t1 = new Date().getTime(); 
     } 
     return false; 
     } 
     
     imgWrap.addEventListener('touchstart', touch, false); 
     imgWrap.addEventListener('touchmove', touch, false); 
     imgWrap.addEventListener('touchend', touch, false); 
     imgWrap.addEventListener('touchcancel', touch, false); 
     
     }(); 
     
    </script> 
    터치 이벤트 에서 가장 중요 한 매개 변 수 는?  pageX 매개 변수,x 의 위 치 를 기록 합 니 다.
    물론 이것 은 demo 일 뿐 이 고 우리 가 실제 프로젝트 에 사용 할 수 있 도록 더욱 최적화 되 고 포장 해 야 한다.
    이 demo 는 단지 문 제 를 해결 하 는 방향 을 제 공 했 을 뿐 입 니 다.이런 방향 이 있 으 면 각종 복잡 한 수요 도 해결 할 수 있 을 것 이 라 고 믿 습 니 다.
    본 고 에서 사용 한 트 위 터 알고리즘 은 ease-out 효 과 를 실현 할 수 있 고 transtion 애니메이션 으로 실현 할 수 있 으 며 코드 가 더욱 간결 합 니 다.윤 방도 최적화 편 참조:https://www.jb51.net/article/123304.htm
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기