2011-01-25 31 views
69

Vì vậy, tôi đã có -webkit-animation quy tắc này:Làm cách nào để kích hoạt lại hoạt ảnh CSS WebKit qua JavaScript?

@-webkit-keyframes shake { 
    0% { 
     left: 0; 
    } 
    25% { 
     left: 12px; 
    } 
    50% { 
     left: 0; 
    } 
    75% { 
     left: -12px; 
    } 
    100% { 
     left:0; 
    } 
} 

Và một số CSS xác định một số các quy tắc hình ảnh động trên của tôi box:

#box{ 
    -webkit-animation-duration: .02s; 
    -webkit-animation-iteration-count: 10; 
    -webkit-animation-timing-function: linear; 
} 

tôi có thể shake các #box như thế này:

document.getElementById("box").style.webkitAnimationName = "shake"; 

Nhưng tôi không thể lắc lại sau.

này chỉ lắc hộp một lần:

someElem.onclick = function(){ 
    document.getElementById("box").style.webkitAnimationName = "shake"; 
} 

Làm thế nào tôi có thể kích hoạt lại một hình ảnh động CSS qua JavaScript mà không sử dụng timeout hoặc nhiều hình ảnh động?

+0

là thư viện jQuery hoặc một thư viện tương tự? Bạn có thể thấy hỗ trợ trình duyệt tốt hơn. –

+0

jQuery có sẵn nhưng không thực sự áp dụng trong trường hợp của tôi. Tôi không cần hỗ trợ trình duyệt khác vì điều này sẽ chỉ chạy trong Adobe Air. Tôi đang cố gắng để gắn bó với hình ảnh động css thay vì javascript. –

+1

Có liên quan: [Firmin - Thư viện hoạt ảnh JavaScript sử dụng chuyển đổi CSS và chuyển tiếp] (http://extralogical.net/projects/firmin/) –

Trả lời

90

Tôi tìm thấy câu trả lời dựa trên mã nguồn và các ví dụ tại CSS3 transition tests github page.

Về cơ bản, hoạt ảnh CSS có sự kiện animationEnd được kích hoạt khi hoạt ảnh hoàn tất.

Đối với trình duyệt webkit, sự kiện này được đặt tên là “webkitAnimationEnd”. Vì vậy, để thiết lập lại một hình ảnh động sau khi nó được gọi là bạn cần phải thêm một event-listener vào phần tử cho sự kiện animationEnd.

Trong plain vanilla javascript:

var element = document.getElementById('box'); 

element.addEventListener('webkitAnimationEnd', function(){ 
    this.style.webkitAnimationName = ''; 
}, false); 

document.getElementById('button').onclick = function(){ 
    element.style.webkitAnimationName = 'shake'; 
    // you'll probably want to preventDefault here. 
}; 

và với jQuery:

var $element = $('#box').bind('webkitAnimationEnd', function(){ 
    this.style.webkitAnimationName = ''; 
}); 

$('#button').click(function(){ 
    $element.css('webkitAnimationName', 'shake'); 
    // you'll probably want to preventDefault here. 
}); 

Các mã nguồn cho CSS3 transition tests (nêu trên) có support đối tượng sau đây có thể hữu ích cho chéo chuyển đổi CSS, chuyển đổi và hoạt ảnh CSS.

Đây là mã hỗ trợ (định dạng lại):

var css3AnimationSupport = (function(){ 
    var div = document.createElement('div'), 
     divStyle = div.style, 
     // you'll probably be better off using a `switch` instead of theses ternary ops 
     support = { 
      transition: 
       divStyle.MozTransition  === ''? {name: 'MozTransition' , end: 'transitionend'} : 
       // Will ms add a prefix to the transitionend event? 
       (divStyle.MsTransition  === ''? {name: 'MsTransition' , end: 'msTransitionend'} : 
       (divStyle.WebkitTransition === ''? {name: 'WebkitTransition', end: 'webkitTransitionEnd'} : 
       (divStyle.OTransition  === ''? {name: 'OTransition'  , end: 'oTransitionEnd'} : 
       (divStyle.transition  === ''? {name: 'transition'  , end: 'transitionend'} : 
       false)))), 
      transform: 
       divStyle.MozTransform  === '' ? 'MozTransform' : 
       (divStyle.MsTransform  === '' ? 'MsTransform'  : 
       (divStyle.WebkitTransform === '' ? 'WebkitTransform' : 
       (divStyle.OTransform  === '' ? 'OTransform'  : 
       (divStyle.transform  === '' ? 'transform'  : 
       false)))) 
      //, animation: ... 
     }; 
    support.transformProp = support.transform.name.replace(/([A-Z])/g, '-$1').toLowerCase(); 
    return support; 
}()); 

Tôi chưa thêm mã để phát hiện “hoạt hình” thuộc tính cho mỗi trình duyệt. Tôi đã đưa ra câu trả lời “wiki cộng đồng” và để lại câu trả lời đó cho bạn. :-)

+0

mã nguồn được trích dẫn đã được chuyển đến https://github.com/louisremi/jquery.transition.js/ –

+0

cảm ơn, liên kết cố định. –

+2

Lưu ý: mã trong repo github đã thay đổi kể từ câu trả lời này; mã ở đó và mã ở đây hoàn toàn khác. –

11

Trước tiên, bạn phải xóa hoạt ảnh, sau đó thêm lại. Ví dụ:

document.getElementById("box").style.webkitAnimationName = ""; 
setTimeout(function() 
{ 
    document.getElementById("box").style.webkitAnimationName = "shake"; 
}, 0); 

Để làm điều này mà không setTimeout loại bỏ các hình ảnh động trong onmousedown, và thêm nó trong onclick:

someElem.onmousedown = function() 
{ 
    document.getElementById("box").style.webkitAnimationName = ""; 
} 
someElem.onclick = function() 
{ 
    document.getElementById("box").style.webkitAnimationName = "shake"; 
} 
+0

Yah, điều này giống như những gì tôi nghĩ ra. Nhưng tôi muốn làm mà không có setTimeout nếu có thể. –

+1

Tôi đã cập nhật câu trả lời của mình bằng một giải pháp thay thế không sử dụng setTimeout. – gilly3

0

Với javascript của bạn, bạn cũng có thể thêm (và sau đó xóa) một lớp CSS trong đó hoạt ảnh được khai báo. Hiểu ý tôi chứ ?

#cart p.anim { 
    animation: demo 1s 1; // Fire once the "demo" animation which last 1s 
} 
6

Một lựa chọn đơn giản nhưng hiệu quả:

HTML:

<div id="box"></div> 
<button id="shake-the-box">Shake it!</button>​ 

css:

#box{ 
    background: blue; 
    margin:30px; 
    height:50px; 
    width:50px; 
    position:relative; 
    -moz-animation:shake .2s 0 linear 1; 
    -webkit-animation:shake .2s 0 linear 1; 
} 
#box.trigger{ 
    display:table; 
} 
@-webkit-keyframes shake { 
    0% { 
     left: 0; 
    } 
    25% { 
     left: 12px; 
    } 
    50% { 
     left: 0; 
    } 
    75% { 
     left: -12px; 
    } 
    100% { 
     left:0; 
    } 
} 
@-moz-keyframes shake { 
    0% { 
     left: 0; 
    } 
    25% { 
     left: 12px; 
    } 
    50% { 
     left: 0; 
    } 
    75% { 
     left: -12px; 
    } 
    100% { 
     left:0; 
    } 
}​ 

jQuery:

$('#shake-the-box').click(function(){ 

    $('#box').toggleClass('trigger'); 

});​ 

Demo:
http://jsfiddle.net/5832R/2/

vấn đề:
Tôi không biết nếu nó hoạt động trên Firefox, bởi vì các hình ảnh động dường như không làm việc ở đó ...

+0

Công trình này, nhưng vì lý do nào đó, quy tắc tràn bị bỏ qua..Tôi đã đặt chế độ này thành ẩn nhưng sau khi tràn hoạt ảnh hiển thị – Snowman

0

1) Thêm tên phim hoạt hình đến #box.trigger trong css

#box.trigger{ 
    display:table; 
    animation:shake .2s 0 linear 1; 
    -moz-animation:shake .2s 0 linear 1; 
    -webkit-animation:shake .2s 0 linear 1; 
} 

2) trong java script bạn không thể loại bỏ các lớp trigger.

3) Xóa tên lớp bằng cách sử dụng phương pháp setTimeOut.

$(document).ready(function(){ 
    $('#shake-the-box').click(function(){ 

    $('#box').addClass('trigger'); 
    setTimeout(function(){ 
     $("#box").removeClass("trigger")},500)   
    }); 
}); 

4) Dưới đây là DEMO.

1

Sao chép hoạt động khá tốt khi tạm dừng Karaoke: Trên IE11 đã buộc phải chỉnh lại (phiên bản ngắn hơn của R. Krupiński).

$('#lyrics').text("Why does it hurt when I pee?"); 
changeLyrics('3s'); 

function changeLyrics(sec) { 
    str = 'lyrics '+ sec + ' linear 1'; 
    $('#lyrics').css('animation', str); 
    $('#lyrics').css('animation-play-state', 'running'); 
    $('#lyrics').replaceWith($('#lyrics').clone(true)); 
} 

hoặc bạn có thể sử dụng như sau:

function resetAnimation(elm) { 
    $('#'+elm).replaceWith($('#'+elm).clone(true)); 
} 
5

Tiếp theo gợi ý từ https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Tips, loại bỏ và sau đó thêm các lớp hình ảnh động, sử dụng requestAnimationFrame để đảm bảo rằng các quá trình công cụ rendering cả thay đổi. Tôi nghĩ rằng điều này là sạch hơn bằng cách sử dụng setTimeout, và xử lý phát lại một hình ảnh động trước khi chơi trước đó đã hoàn thành.

$('#shake-the-box').click(function(){ 
    $('#box').removeClass("trigger"); 
    window.requestAnimationFrame(function(time) { 
    window.requestAnimationFrame(function(time) { 
     $('#box').addClass("trigger"); 
    }); 
    });  

});

http://jsfiddle.net/gcmwyr14/5/

1

Đặt lại giá trị trước. Sử dụng quy trình ngược để áp dụng các thay đổi mà không sử dụng thời gian chờ:

function shake() { 
 
    var box = document.getElementById("box"); 
 
    box.style.animationName = null; 
 
    box.offsetHeight; /* trigger reflow */ 
 
    box.style.animationName = "shake"; 
 
}
@keyframes shake { 
 
    0% { left: 0; } 
 
    25% { left: 12px; } 
 
    50% { left: 0; } 
 
    75% { left: -12px; } 
 
    100% { left: 0; } 
 
} 
 

 
#box { 
 
    position: absolute; 
 
    width: 75px; height: 75px; 
 
    background-color: black; 
 
    animation-duration: .02s; 
 
    animation-iteration-count: 10; 
 
    animation-timing-function: linear; 
 
} 
 

 
button { 
 
    position: absolute; 
 
    top: 100px; 
 
}
<div id="box"></div> 
 
<button onclick="shake()">Shake</button>

Ngược lại với câu trả lời chấp nhận rằng khuyến cáo animationEnd, phương pháp này resets các hình ảnh động ngay cả khi nó vẫn được tiến hành. Điều này có thể là hoặc có thể không phải là những gì bạn muốn.


Một thay thế sẽ là để tạo ra một bản sao @keyframes hoạt hình và chuyển đổi giữa hai:

function shake() { 
 
    var box = document.getElementById("box"); 
 
    if (box.style.animationName === "shake") 
 
     box.style.animationName = "shake2"; 
 
    else 
 
     box.style.animationName = "shake"; 
 
}
@keyframes shake { 
 
    0% { left: 0; } 
 
    25% { left: 12px; } 
 
    50% { left: 0; } 
 
    75% { left: -12px; } 
 
    100% { left: 0; } 
 
} 
 

 
@keyframes shake2 { 
 
    0% { left: 0; } 
 
    25% { left: 12px; } 
 
    50% { left: 0; } 
 
    75% { left: -12px; } 
 
    100% { left: 0; } 
 
} 
 

 
#box { 
 
    position: absolute; 
 
    width: 75px; height: 75px; 
 
    background-color: black; 
 
    animation-duration: .02s; 
 
    animation-iteration-count: 10; 
 
    animation-timing-function: linear; 
 
} 
 

 
button { 
 
    position: absolute; 
 
    top: 100px; 
 
}
<div id="box"></div> 
 
<button onclick="shake()">Shake</button>

+0

lưu ý: theo https://stackoverflow.com/questions/21664940/force-browser-to-trigger -reflow-while-changing-css, nó có thể tốt hơn để sử dụng ví dụ 'void (box.offsetHeight);' thay vào đó, bởi vì câu lệnh có truy cập var và không có hiệu lực có thể được tối ưu hóa (và sẽ kích hoạt linters để phát ra các cảnh báo như 'Biểu thức bất ngờ '.' trong vị trí lệnh.' - biếu không của JSLint) – vaxquis

+0

Ngoài ra, lưu ý rằng các hoạt động reflows khá "nặng" (tính toán chuyên sâu) hoạt động. – vaxquis

0

Có một vấn đề với việc sử dụng setTimeout() để loại bỏ các lớp và sau đó đọc 5ms sau đó?

svg.classList.remove('animate'); 
setTimeout(function() { 
    svg.classList.add('animate'); 
}, 10); 
Các vấn đề liên quan