[원본 읽 기] 애 니 메 해석 (JS 애니메이션 라 이브 러 리) 핵심 (2)

이번 해석 은 두 편의 문장 으로 나 뉘 는데, 지금 은 두 번 째 편 이 고, 첫 번 째 편 은 여기에 있다.
또한 이 라 이브 러 리 를 잘 이해 하기 위해 개인 적 으로 이 라 이브 러 리 의 압축 판 을 써 서 핵심 적 인 기능 (주로 핵심 기능 을 잘 이해 하기 위해 서) 을 실현 했다. 내용 이 더욱 적 고 읽 기 편 하 며 주 소 는 여기에 있다.
전편 을 계속 하고 먼저 구조 도 를 끌 어 옵 니 다.
// anime  
function anime(params){
  
  //   instance        
  let instance = createNewInstance(params);
  
  //   API            
  instance.play = function() {}
  
  //    startTime   engineTime(  )
   instance.tick = function(t) {}
   
  //    engineTime    ,      (  )
  function setInstanceProgress(engineTime) {}
  
  //              (  )
  function setAnimationsProgress(insTime){}

  //       time        
  instance.seek = function(time) {}
  //   API   
  instance.pause = function() {}
  //   API   
  instance.reverse = function() {}
  //   API reset
  instance.reset = function() {}
  //   API     
  instance.restart = function() {}
  /*...*/
  return instance
}
  • setAnimations Progress (일부 설정 의 정 의 를 생략)
  • 이 함수 가 매개 변 수 를 받 아들 이 는 것 은 현재 위치 에 소모 되 는 시간 (애니메이션 시작 점) 입 니 다. 그 다음 에 모든 애니메이션 목표 의 위 치 를 계산 하고 값 을 부여 하 는 것 입 니 다.
    //              
    function setAnimationsProgress(insTime) {
      /* ... */
      //   while                   (       )
      while (i < animationsLength) {
          /* ... */
        //                       
        const elapsed = minMaxValue(insTime - tween.start - tween.delay, 0, tween.duration) / tween.duration;
        //           
        const eased = isNaN(elapsed) ? 1 : tween.easing(elapsed, tween.elasticity);
        /* ... */
        //           
        for (let n = 0; n < toNumbersLength; n++) {
          let value;
          const toNumber = tween.to.numbers[n];
          const fromNumber = tween.from.numbers[n];
          if (!tween.isPath) {
            //         
            value = fromNumber + (eased * (toNumber - fromNumber));
          } else {
            //   SVG path  
            value = getPathProgress(tween.value, eased * toNumber);
          }
          /* ... */
          numbers.push(value);
        }
             /* ... */
            if (!isNaN(n)) {
              //      '135.546'+'px'
              if (!b) {
                progress += n + ' ';
              } else {
                progress += n + b;
              }
            }
        /* ... */
        //      'translateX('+'135.546px'+')`
        setTweenProgress[anim.type](animatable.target, anim.property, progress, transforms, animatable.id);
        anim.currentValue = progress;
        i++;
      }
      //     ,  target  
      const transformsLength = Object.keys(transforms).length;
      if (transformsLength) {
        for (let id = 0; id < transformsLength; id++) {
          if (!transformString) {
            const t = 'transform';
            //      
            transformString = (getCSSValue(document.body, t) ? t : `-webkit-${t}`);
          }
          //   style
          instance.animatables[id].target.style[transformString] = transforms[id].join(' ');
        }
      }
      //             
      instance.currentTime = insTime;
      //     
      instance.progress = (insTime / instance.duration) * 100;
    }

    나머지 는 조작 함수 입 니 다.
  • instance.seek
  • //       time        
    instance.seek = function(time) {
      setInstanceProgress(adjustTime(time));
    }
  • instance.pause
  • //   API   
    instance.pause = function() {
      const i = activeInstances.indexOf(instance);
      //   activeInstances   engine         
      if (i > -1) activeInstances.splice(i, 1);
      instance.paused = true;
    }
  • instance.reverse
  • //   API   
    instance.reverse = function() {
      toggleInstanceDirection();
      startTime = 0;
      lastTime = adjustTime(instance.currentTime);
    }
  • instance.restart
  • //   API     
    instance.restart = function() {
      instance.pause();
      instance.reset();
      instance.play();
    }
  • instance.reset
  • //   API reset
    instance.reset = function() {
      const direction = instance.direction;
      const loops = instance.loop;
      //     ,     
      instance.currentTime = 0;
      instance.progress = 0;
      instance.paused = true;
      instance.began = false;
      instance.completed = false;
      instance.reversed = direction === 'reverse';
      instance.remaining = direction === 'alternate' && loops === 1 ? 2 : loops;
      setAnimationsProgress(0);
      for (let i = instance.children.length; i--; ){
        instance.children[i].reset();
      }
    }

    총결산
  • requestAnimateFrameCSS 애니메이션 을 사용 하여 유창 도 를 높 였 다.
  • 완 동 함 수 를 사 용 했 습 니 다. 를 통 해 다른 정 의 된 설정 항목 을 조합 하면 현재 애니메이션 의 구체 적 인 위 치 를 계산 할 수 있 습 니 다.

  • 이번 해석 은 여기까지 입 니 다. 오류 가 있 으 면 지적 해 주 십시오. 감사합니다!

    좋은 웹페이지 즐겨찾기