2011-09-27 96 views
16

是否可以重新啓動動畫GIF,用作background-image重新啓動動畫GIF作爲背景圖

考慮這個HTML:

<div id="face"> 
    <div id="eyes"></eyes> 
</div> 

而且這一款式:

#eyes.blink { 
    background-image:url('blink.gif'); 
} 

我想blink.gif動畫打我每次添加類blink#eyes,不只是第一次的時間。

我預計這個工作:

function startBlink() { 
    $('#eyes').addClass('blink'); 
} 

function stopBlink() { 
    $('#eyes').removeClass('blink'); 
} 

的問題是,Firefox和WebKit瀏覽器都不會再次播放背景圖像的GIF動畫一旦播放一次。添加/刪除類閃爍只能在第一次使用。

+0

不要GIF動畫循環? –

+0

@NoufalIbrahim只有當它們被設置爲循環。 – JJJ

+1

@Noufal Ibrahim - 他們*可以做到,它取決於圖像中設置的循環選項。 – Quentin

回答

14

您可以通過重新載入動畫gif來重放它。這對帶寬並不理想,特別是如果圖像很大,但會強制重新啓動動畫。

在我的例子,我添加和刪除它的<div id="animated">onclick

$('#animated').click(function() { 

    /* Reference to the clicked element and toggle the .go class */ 
    var $div = $(this); 
    $div.toggleClass('go'); 

    /* Start the animated gif */ 
    if ($div.hasClass('go')) { 

     /* Create an <img> element and give it the animated gif as a src. To 
      force a reload we add a date parameter to the URL */ 
     var img = document.createElement('img'); 
     img.src = "http://yoursite.com/animated.gif?p" + new Date().getTime(); 

     /* Once the image has loaded, set it as the background-image */ 
     $(img).load(function(){ 
      $div.css({backgroundImage: "url("+img.src+")"}); 
     }); 

    /* Remove the background-image */   
    } else { 
     $div.css({backgroundImage: "none"}); 
    } 
}) 

在行動Demo of it

+0

爲什麼你添加隨機數到文件路徑?趨於落後** ? - 只需重新設置'src'就足以讓動畫重啓。 http://jsfiddle.net/Lqx2V/ – c69

+1

@ c69它強制它不使用瀏覽器緩存。沒有這個Webkit就不會重新啓動動畫。 – Pat

+2

omg .. webkit sux then :( – c69

1

你有沒有考慮過兩次使用相同的圖像blink.gif和blink2.gif,爲它們添加兩個類並在類之間切換?

<div id="face"> 
    <div id="eyes"></eyes> 
</div> 

.blink { 
    background-image:url('blink.gif'); 
} 

.blink2 { 
    background-image:url('blink2.gif'); 
} 

function MakeBlink() 
{ 
    if ($('#eyes').hasClass('blink')) 
    { 
     $('#eyes').removeClass('blink').addClass('blink2'); 
    } else 
    { 
    $('#eyes').removeClass('blink2').addClass('blink'); 
    } 
} 
+0

這將是兩幀動畫(「眨眼」)的方式。點擊鍵盤上的Esc按鈕即可取消Gif動畫。 – Lekensteyn

+0

是否真的需要有不同的圖像?我無法看到爲什麼* $('#eyes')。removeClass('blink')。addClass('blink'); *不起作用的原因 – Ivan

+0

@Ivan - 據推測,OP希望眼睛閃爍,眼瞼閉合,而不是消失。 – Quentin

5

我發現你也可以添加一個?+Math.random()到圖片src的結尾,它會重新加載.gif文件。

+0

尼斯!良好的建議,工程!:) – podeig

+2

更好,你可以將'#'+ Math.random()添加到URL中,然後大概瀏覽器不必重新加載它。我已經在Chrome中測試了它,並且它可以工作(它從緩存中檢索)。 – Abram

+2

@Abram ,在URL中添加'#'而不是'?'似乎不再有效FWIW –

0

出於某種原因,這個工程:

// Append the image to the page 
var i = new Image(); 
i.src = 'some.gif'; 
document.body.appendChild(i); 

// Now execute this line and the gif will restart 
// (anywhere it appears on the page, including CSS backgrounds) 
i.src = 'some.gif'; 

這需要附加到頁面中的實際圖像的DOM元素,但你可以visibility: hidden隱藏它。這要求圖像通過網絡多次下載。

我只在Firefox和Chrome中測試過。不確定其他瀏覽器。

1

僅僅因爲我現在仍然需要這個東西,我認爲我使用的純JS功能可能對別人有幫助。這是一個純JS的重新啓動GIF動畫的方式,無需重新加載。您可以通過鏈接和/或文檔加載事件調用此功能。

<img id="img3" src="../_Images/animated.gif"> 

<a onClick="resetGif('img3')">reset gif3</a> 

<script type="text/javascript"> 

// reset an animated gif to start at first image without reloading it from server. 
// Note: if you have the same image on the page more than ones, they all reset. 
function resetGif(id) { 
    var img = document.getElementById(id); 
    var imageUrl = img.src; 
    img.src = ""; 
    img.src = imageUrl; 
}; 

</script> 

在某些瀏覽器上,您只需要將img.src重置爲自身並且工作正常。在IE上,您需要清除它,然後重置它。這resetGif()從圖像ID中挑選圖像名稱。如果您更改給定ID的實際圖像鏈接,這很方便,因爲您不必記住更改resetGiF()調用。

--Nico

3

我結合溶液的幾部分,使一個整體解決方案,解決了(希望)的所有問題:

  • 確定的元件(的背景圖像的URL從CSS background-image
  • 觸發該圖像而無需從網絡
  • 重裝它在所有的地方重新啓動它重新啓動(不接觸每個單獨)
  • 確保目標被重新啓動動畫

在我的解決方案後,沒有任何瑕疵粉刷我創建了被添加到身體,但隱藏的,所以他們仍然在瀏覽器呈現,但不會進行交互的輔助圖像與頁面視覺使用position: absolute; left: -5000px;

對我們的幫助圖片的引用被緩存在resetHelperImages中,因此我們可以在隨後的調用中重用它們以用於相同的圖像。

我爲我的例子使用jQuery,但它可以適應沒有jQuery的工作。

在測試:鉻(版本43.0.2357.130米)

var resetHelperImages = {}; 
 

 
function restartAnimation(elem) { 
 
    elem = $(elem); 
 
    for (var i = 0; i < elem.length; i++) { 
 
    var element = elem[i]; 
 
    // code part from: http://stackoverflow.com/a/14013171/1520422 
 
    var style = element.currentStyle || window.getComputedStyle(element, false); 
 
    // var bgImg = style.backgroundImage.slice(4, -1).replace(/"/g, ''); 
 
    var bgImg = style.backgroundImage.match(/url\(([^\)]+)\)/)[1].replace(/"/g, ''); 
 
    // edit: Suggestion from user71738 to handle background-images with additional settings 
 

 
    var helper = resetHelperImages[bgImg]; // we cache our image instances 
 
    if (!helper) { 
 
     helper = $('<img>') 
 
     .attr('src', bgImg) 
 
     .css({ 
 
      position: 'absolute', 
 
      left: '-5000px' 
 
     }) // make it invisible, but still force the browser to render/load it 
 
     .appendTo('body')[0]; 
 
     resetHelperImages[bgImg] = helper; 
 
     setTimeout(function() { 
 
     helper.src = bgImg; 
 
     }, 10); 
 
     // the first call does not seem to work immediately (like the rest, when called later) 
 
     // i tried different delays: 0 & 1 don't work. With 10 or 100 it was ok. 
 
     // But maybe it depends on the image download time. 
 
    } else { 
 
     // code part from: http://stackoverflow.com/a/21012986/1520422 
 
     helper.src = bgImg; 
 
    } 
 
    } 
 
    // force repaint - otherwise it has weird artefacts (in chrome at least) 
 
    // code part from: http://stackoverflow.com/a/29946331/1520422 
 
    elem.css("opacity", .99); 
 
    setTimeout(function() { 
 
    elem.css("opacity", 1); 
 
    }, 20); 
 
}
.myBgImageClass { 
 
    background-image: url('http://i410.photobucket.com/albums/pp184/OllieMarchant/Countup.gif'); 
 
    width: 100px; 
 
    height: 150px; 
 
    background-size: 100%; 
 
    background-repeat: no-repeat; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div class="myBgImageClass"></div> 
 
<button onclick="restartAnimation($('.myBgImageClass'))">restart</button>

+0

在ie中不起作用。 – jnkb

+0

@jnkb是的,你是對的,它在IE中不起作用。也許所有瀏覽器的通用解決方案都是下載和緩存圖像的原始數據,然後創建一個'data:'-url來重新開始動畫。也許'數據:'-url緩存失效......可能嗎? –

0

有不重新加載每次和浪費帶寬的GIF的替代方案。

它涉及在內存中存儲GIF作爲Base64(繞過瀏覽器緩存),並使用FileReader API(似乎是supported in all modern browsers)。需要注意的是加載圖像這種方式受到跨域政策

看到它在行動(不像形象重裝的解決方案。):http://jsfiddle.net/jcward/nknLrtzL/2/

下面是它如何工作的。此函數將圖像作爲Base64編碼的字符串加載。

function toDataUrl(url, callback) { 
    var xhr = new XMLHttpRequest(); 
    xhr.onload = function() { 
    var reader = new FileReader(); 
    reader.onloadend = function() { 
     callback(reader.result); 
    } 
    reader.readAsDataURL(xhr.response); 
    }; 
    xhr.open('GET', url); 
    xhr.responseType = 'blob'; // IE11, set responseType must come after .open() 
    xhr.send(); 
} 

然後,你要重新啓動的GIF動畫任何時候,background-image屬性更改爲none,然後以base64字符串(在某些瀏覽器,你需要重新添加子觸發更新沒有的setTimeout ):

$div.css({backgroundImage: "none"}); 
$div.parent().add($div); // Some browsers need this to restart the anim 
$div.css({backgroundImage: "url("+img_base64+")"}); 

在一些情況下,觸發

由於this answertoDataURL函數(修正爲IE11)

。 210
0

關於this answer發佈者Frederic Leitenberger,我發現它工作非常好。

然而,它打破了,如果你的背景圖片有多種,分層的部分,像這樣:

background-image: url(https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg), 
    radial-gradient(ellipse at center, 
     rgba(255,255,255,1) 0%, 
     rgba(255,255,255,1) 50%, 
     rgba(255,255,255,0) 80%); 

爲了繞過這個限制,我修改了發現背景圖像的URL,像這樣的一行:

var bgImg = style.backgroundImage.match(/url\(([^\)]+)\)/)[1].replace(/"/g, ''); 

這使用正則表達式來提取背景圖像的URL部分。

我會添加這個作爲linked answer的評論,但我是一個沒有聲望的noob,所以被阻止這樣做。那些有足夠的代表可能想要添加行到實際的答案。

+0

我將您的改進添加到了我的解決方案中。謝謝! –