jQuery背景定位与CSS动画定位的错误和效率

时间:2017-07-27 02:50:32

标签: javascript jquery html performance

我目前正在制作一个网站,其中舞台/英雄有一组带有循环背景图像的div(文字图像),我正在使用jQuery来动画他们的位置,以给出“海洋”的外观在屏幕上移动的图像。

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

更新

@FuriousD在下面给出了一个很好的建议,使用CSS来实现这一点,虽然这更接近我所希望的,但CSS动画在击中背景位置的末尾时会引起跳跃。

以下是基于答案的Codepen,但在动画完成后出现了“跳跃”的新问题:

codepen.io/stufu/pen/YxXaLR

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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