2013-02-03 39 views
6

Có thể thay đổi duration của hoạt ảnh jQuery đang chạy giữa hai giá trị khác nhau không?Thay đổi thời lượng hoạt ảnh của jQuery trong khi hoạt ảnh

Tôi đã cố gắng để thay đổi duration qua giao trực tiếp, nhưng không thành công:

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

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

... và thậm chí, thay đổi fx.options.duration trong step -method không ảnh hưởng đến hình ảnh động chạy:

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 
    } 
}); 

Đây là số fiddle để phát xung quanh. Bất kỳ ý tưởng nào có thể thực hiện điều này?

+0

Nếu bạn chuyển từ jQuery 2.0 sang jQuery> = 1.7.2 nó (phần nào) hoạt động. Tôi đoán nó đã làm với những thay đổi gần đây của đội jQuery đã làm trên các chức năng liên quan đến hoạt hình. – Mahn

+0

@Mahn Vâng, cảm ơn! Tôi đã nhận ra rằng ... Tôi đang ở trong lõi bây giờ, cố gắng tìm ra cách để giải quyết điều đó! – yckart

Trả lời

9

Thời lượng được chuyển theo giá trị, không phải theo tham chiếu. Vì vậy, animate không lưu trữ một tham chiếu đến duration. Ngay cả khi bạn cập nhật đối tượng tùy chọn (được chuyển qua tham chiếu), jQuery sử dụng options.duration nội bộ, có nghĩa là nó sẽ được truyền theo giá trị.

Để khắc phục nhanh, bạn có thể dừng hoạt ảnh và khởi động lại bằng thời lượng mới - điều chỉnh cho phần hoạt ảnh đã kết thúc.

Bạn cần cân nhắc cách bạn muốn ứng xử hoạt động, ví dụ: khi bạn tăng tốc hoạt ảnh 4 giây lên hoạt ảnh 2 giây sau 3 giây. Trong mã bên dưới, hoạt ảnh sẽ xuất hiện ngay lập tức. Suy nghĩ về nó, đó có lẽ không phải là những gì bạn muốn vì bạn có thể thực sự quan tâm đến tốc độ, không phải thời gian.

Đoạn mã dưới đây là bản phác thảo thô, tôi không chắc liệu nó có chính xác không, nếu nó hoạt động khi giảm giá trị hoạt ảnh hoặc cách xử lý nhiều giá trị hoạt ảnh. Bạn cũng có thể chỉ thay đổi thời lượng một lần.

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

Vâng, cảm ơn những suy nghĩ và lời giải thích của bạn! Ý tưởng là tuyệt vời, tuy nhiên tôi nghĩ rằng, chắc chắn có một giải pháp ngọt ngào ở đâu đó trong tự nhiên! – yckart

+0

@yckart Có tùy chọn 'nới lỏng', nhưng tôi không chắc chắn cách thức hoạt động và nếu bạn cần biết tốc độ hoạt ảnh trước khi bắt đầu hoạt ảnh. –

+0

Điều này thực sự có thể hoạt động tốt, miễn là animationCss mang giá trị tuyệt đối (ví dụ: không + = 50) và tùy thuộc vào cách bạn muốn nó hoạt động như @Matt đề cập trong câu trả lời của mình. Bạn có thể làm cho nó trông khá gói nó trong một plugin, mà nên được tương đối dễ dàng để làm. – Mahn

0

tôi có lẽ hơi muộn cho op nhưng kể từ khi tôi đã kết thúc ở đây trong khi cố gắng để làm điều tương tự, người khác có thể quá.

Trên đối tượng hoạt hình start() jQuery chuyển đối tượng hoạt ảnh làm đối số, vì vậy bạn chỉ cần giữ tham chiếu ở đâu đó và sau đó bạn có thể thay đổi nó trên gọi lại step().

Cái gì như:

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 
     } 
    } 
); 

Bây giờ là phần khó khăn là jQuery quyết định ngừng hoặc tiếp tục hoạt hình trước khi gọi các step() gọi lại. Vì vậy, thời gian được đặt cho lần đánh dấu tiếp theo và nếu nó không được đặt đủ lớn, hoạt ảnh của bạn có thể bị dừng lại.
Sử dụng jQuery setInterval() với khoảng thời gian 13 vì vậy về mặt lý thuyết step() nên được gọi mỗi 13ms nhưng vì không có gì được đảm bảo, tôi cho rằng thời lượng phải được tăng tối thiểu 30ms.
Cá nhân tôi thậm chí sẽ đi ít nhất 100. Tốt hơn có một hoạt ảnh chạy quá lâu (100ms gần như không đáng kể) thay vì phải dừng quá sớm.

Các vấn đề liên quan