2013-02-03 5 views
6

현재 실행중인 jQuery 애니메이션의 duration을 두 가지 다른 값으로 변경할 수 있습니까?애니메이션 도중 jQuery의 애니메이션 지속 시간 변경

내가 직접 할당을 통해 duration를 변경하려고했으나했습니다에는 성공하지 :

var timing = { duration: 4000 }; 
$(document).click(function (e) { 
    timing.duration = 1000; 
}); 

$('#foo').animate({top:200, left:200}, timing); 

... 심지어, 실행중인 애니메이션에 영향을주지 않습니다 fx.options.durationstep에서 -method 변경 :

var state = false, 
$(document).click(function (e) { 
    state = true; 
}); 

$('#foo').animate({top:200, left:200}, { 
    duration: 4000, 
    step: function(now, fx){ 
    if(state) fx.options.duration = 1000; 
    console.log(fx.options.duration); // 1000 
    } 
}); 

여기 주위에 재생 fiddle입니다. 어떻게 할 수 있습니까?

+0

jQuery 2.0에서 jQuery> = 1.7.2로 전환하면 다소 효과가 있습니다. jQuery 팀이 애니메이션 관련 기능에 수행 한 최근 변경 사항과 관련이 있다고 생각합니다. – Mahn

+0

@Mahn 그래, 고마워! 나는 그것을 알아 차 렸습니다 ... 나는 지금 당장 중핵에 있고, 그것을 어떻게 만들어 내는지 알아 내려고 노력합니다! – yckart

답변

9

기간은 참조가 아닌 값으로 전달됩니다. 따라서 animateduration에 대한 참조를 저장하지 않습니다. 참조로 전달 된 옵션 객체를 업데이트하더라도 jQuery는 내부적으로 options.duration을 사용하므로 값으로 전달됩니다.

빠른 수정으로 애니메이션을 멈추고 새로운 재생 시간으로 다시 시작하여 이미 끝난 애니메이션 부분을 조정할 수 있습니다.

3 초 후에 4 초 애니메이션을 2 초 애니메이션으로 빠르게 할 때와 같이 어떻게 동작 시킬지 고려해야합니다. 아래의 코드에서 애니메이션은 즉각적입니다. 그것에 대해 생각해 보면, 아마도 당신이 원하는 것이 아니기 때문에 아마도 당신은 스피드가 아닌 스피드에 관심을 가질 것입니다.

아래 코드는 대략적인 스케치입니다. 애니메이션 값을 줄이거 나 여러 애니메이션 값을 처리하는 방법이 정확한지 확신 할 수 없습니다. 기간을 한 번만 변경할 수도 있습니다.

var state = false, 
    duration = 8000; 

$(document).click(function (e) { 
    state = true; 
    duration = 1000; 
}); 
var animationCss = {top:200, left:200}; 
$('#foo').animate(animationCss, { 
    duration: duration, 
    step: function(now, fx){ 
     if(state) { 
      $("#foo").stop(); 
      var percentageDone = (fx.now - fx.start)/(fx.end - fx.start) 
      var durationDone = fx.options.duration * percentageDone; 
      var newDuration = duration - durationDone; 
      if (newDuration < 0) 
      { 
       newDuration = 0; 
      } 
      $("#foo").animate(animationCss, { duration: newDuration}) 

     } 
    } 
}); 

http://fiddle.jshell.net/5cdwc/3/

+0

네 생각과 설명에 감사드립니다. 아이디어는 훌륭하지만, 어딘가에 야생에서 좀 더 달콤한 해결 방법이 있다고 생각합니다. – yckart

+0

@yckart'easing' 옵션이 있는데 어떻게 동작하는지, 그리고 애니메이션을 시작하기 전에 애니메이션 속도를 알아야하는지 잘 모르겠습니다. –

+0

animationCss가 절대 값 (예 : + 50 = 아니요)을 가지고 있고 답변에서 @Matt가 언급하는 방식에 따라 실제로 잘 작동 할 수 있습니다. 상대적으로 쉽게 할 수있는 플러그인으로보기 쉽게 만들 수 있습니다. – Mahn

0

나는 찍기 위해 늦게 아마 조금 해요하지만 같은 일을하는 동안 나는 여기 끝난 이후, 다른 사람도 할 수있다.

start() 콜백에서 jQuery는 애니메이션 객체를 인수로 전달하므로 참조를 어딘가에 유지해야하며 step() 콜백에서 변경할 수 있습니다. 같은

뭔가 :

var animEnd = false; //this will be updated somewhere else 
var animObj; 
$().animate({ 
     width: '100%' 
    }, 
    { 
     start: function(animation){ 
      animObj = animation; 
     }, 
     step: function(now, tween){ 
      if(!animEnd) 
       //jquery set an interval of 13 but let's be safe 
       animObj.duration += 30; 

      //you can change the value of tween.pos aswell 
     } 
    } 
); 

이제 까다로운 부분은 jQuery를 중지하거나 step() 콜백을 호출하기 전에 애니메이션을 계속하기로 결정한다는 것입니다. 따라서 지속 시간은 다음 틱에 대해 설정되며 애니메이션이 충분히 크게 설정되지 않은 경우 애니메이션이 중지 될 수 있습니다.
jQuery는 13의 간격으로 setInterval()을 사용하므로 이론적으로는 step()을 13ms마다 호출해야하지만 아무 것도 보장되지 않기 때문에 최소 30ms만큼 시간을 늘려야한다고 생각합니다.
개인적으로 나는 적어도 100 이상을 갈 것입니다. 너무 빨리 멈추는 것보다는 오히려 너무 길게 (100ms가 거의 눈에 띄지 않습니다) 실행하는 것이 좋습니다.

관련 문제