2017-07-27 21 views
1

我目前正在一個網站,其中舞臺/英雄有一套與循環背景圖像(文字圖像)divs,我使用jQuery動畫他們的定位讓圖像在屏幕上移動的「海洋」出現。錯誤和jQuery的背景定位vs CSS動畫定位的效率

var position = 0; 
 

 
setInterval(function() { 
 
    position -= 1; 
 
    $(".sub-image-1").css({ "background-position":+ position +"px 0px" }) 
 
}, 20); 
 

 
setInterval(function() { 
 
    position -= 1; 
 
    $(".sub-image-2").css({ "background-position":+ position +"px 0px" }) 
 
}, 140); 
 

 
setInterval(function() { 
 
    position -= 1; 
 
    $(".sub-image-3").css({ "background-position":+ position +"px 0px" }) 
 
}, 200);
.stage-image { 
 
    width:100vh; 
 
    height:30vh; 
 
} 
 

 
.stage-sub-image { 
 
    position:absolute; top:0; 
 
    width:100%; 
 
    height:100%; 
 
    background-repeat:repeat-x; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="stage-image"> 
 
    <div class="stage-sub-image sub-image-1" style="background:url(https://upload.wikimedia.org/wikipedia/commons/c/ca/Triple-Spiral-4turns_green_transparent.png)"></div> 
 
    <div class="stage-sub-image sub-image-2" style="background:url(https://upload.wikimedia.org/wikipedia/commons/b/be/Blender3D_Lisc_lipy-Transparent.png)"></div> 
 
    <div class="stage-sub-image sub-image-3" style="background:url(https://cdn0.iconfinder.com/data/icons/ball/256/transparent.png)"></div> 
 
</div>

我很好奇,如果有這樣的解決方案,是少的瀏覽器密集的更好方法。在這種情況下,我覺得setInterval會給網站帶來更多的開銷。有更好的方法來處理這樣的事情嗎?除了性能問題之外,通過JS完成的動畫非常不穩定,我希望獲得更平滑的效果。

這裏有一個CodePen什麼,我目前有上面:

https://codepen.io/stufu/pen/GvJdxq

UPDATE

@FuriousD給下面一個很好的建議,使用CSS來做到這一點,而這是在接近我期望的是,CSS動畫在擊中背景位置的末尾時會引起跳躍。

這裏有一個Codepen根據自己的答案,但以「跳樓」在動畫完成後的一個新問題:

codepen.io/stufu/pen/YxXaLR

回答

1

您可以使用CSS動畫。注意,圖像的寬度(-250px)需要被硬編碼到動畫,但可以動態生成:

var containers = $('.stage-sub-image'); 
 
var containerWidth = $(containers[0]).width(); 
 
var styleElem = document.createElement('style'); 
 
var animClass = 'animateMe'; 
 

 
document.body.append(styleElem); 
 

 
styleElem.innerHTML = 
 
    '@keyframes animBg {' + 
 
    'from { background-position: 0px top; }' + 
 
    'to { background-position: -' + containerWidth + 'px top }' + 
 
    '}' + 
 
    '.' + animClass + ' { animation: animBg 10s linear infinite; background-size: 100% auto; }'; 
 

 

 
containers.addClass(animClass);
.stage-sub-image { 
 
    width: 200px; 
 
    height: 130px; 
 
    background-color: #909; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="stage-image"> 
 
    <div class="stage-sub-image" style="background-image:url(http://via.placeholder.com/250x130)"></div> 
 
    <div class="stage-sub-image" style="background-image:url(http://via.placeholder.com/250x130)"></div> 
 
    <div class="stage-sub-image" style="background-image:url(http://via.placeholder.com/250x130)"></div> 
 
</div>

+0

感謝您的評論@FuriousD。我沒有足夠的解釋我的問題,不幸的是,上面的方法硬編碼的價值不會工作。一旦達到寬度的末端,就會出現「跳躍」 –

+0

有幾種方法可以將JS與CSS動畫組合使用 - 例如使用JS重新觸發動畫等。我不確定是否有一個簡單的解決方案,但不涉及硬編碼值。 – FuriousD

+0

我認爲這是問題的一部分。當你對寬度進行硬編碼時(即使它以vw爲單位),它會在最後跳過。我設置了一個codepen以顯示發生了什麼:https://codepen.io/stufu/pen/YxXaLR 純JS方法的優點是它「無限」地將背景位置改變爲無窮大,CSS將重啓它。但我很難吞下setInterval –

0

我要發佈一個更新,我能成功通過@FuriousD的回答獲得很多幫助,從而實現這一目標。最終他的見解導致了這一點,我接受了他的答案,但是我想提供我通過純CSS完成的工作版本。

基本上,這需要知道背景圖片的尺寸。將圖像編碼成CSS動畫將使其能夠平滑滾動並具有良好的可伸縮性。這裏是我的結果:

CSS:

@keyframes animBg1 { 
    from { 
    background-position: 0px top; 
    } 
    to { 
    background-position: -613px top; 
    } 
} 

@keyframes animBg2 { 
    from { 
    background-position: 0px top; 
    } 
    to { 
    background-position: -327px top; 
    } 
} 
@keyframes animBg3 { 
    from { 
    background-position: 0px top; 
    } 
    to { 
    background-position: -256px top; 
    } 
} 

.stage-image { 
    .stage-sub-image { 
    position:absolute; top:0; 
    width:100vw; 
    height:100vh; 
    background-repeat:repeat-x; 
    animation-fill-mode: forwards; 
    animation-iteration-count: infinite; 
    animation-timing-function: linear; 
    } 
    .sub-image-1 { 
    animation-name: animBg1; 
    animation-duration: 5s; 
    } 
    .sub-image-2 { 
    animation-name: animBg2; 
    animation-duration: 2s; 
    } 
    .sub-image-3 { 
    animation-name: animBg3; 
    animation-duration: 3s; 
    } 
} 

HTML

<div class="stage-image"> 
    <div class="stage-sub-image sub-image-1" style="background-image:url(https://upload.wikimedia.org/wikipedia/commons/c/ca/Triple-Spiral-4turns_green_transparent.png)"></div> 
    <div class="stage-sub-image sub-image-2" style="background-image:url(https://upload.wikimedia.org/wikipedia/commons/1/16/Rainbow_trout_transparent.png)"></div> 
    <div class="stage-sub-image sub-image-3" style="background-image:url(https://cdn0.iconfinder.com/data/icons/ball/256/transparent.png)"></div> 
</div> 

Codepen example