2017-07-27 1 views
1

Ich arbeite derzeit auf einer Website, wo die Bühne/Held hat eine Reihe von divs mit Schleifen Hintergrundbilder (Bilder von Text), und ich benutze jQuery zu animieren ihre Positionierung, um den Eindruck eines "Ozeans" von Bildern zu erwecken, die sich über den Bildschirm bewegen.Bugs und Effizienz in jQuery Hintergrund Positionierung vs CSS-Animation Positionierung

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>

Ich bin neugierig, ob es ein besserer Ansatz zu dieser Lösung ist, dass weniger Browser intensiv ist. Ich fühle, dass setInterval in diesem Fall der Website viel mehr Aufwand als nötig hinzufügt. Gibt es bessere Ansätze, um so etwas zu handhaben? Zusätzlich zu den Leistungsproblemen sind die Animationen, die durch JS gemacht werden, sehr abgehackt und ich hoffe auf einen glatteren Effekt.

Hier ist eine CodePen von dem, was ich habe zur Zeit oben:

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

UPDATE

@FuriousD unten einen guten Vorschlag gab CSS in Verwendung, dies zu erreichen, während das ist näher an Was ich mir erhofft habe, CSS-Animationen verursachen einen Sprung, wenn sie auf das Ende der Hintergrundposition treffen.

Hier ist eine Codepen auf der Grundlage ihrer Antwort, aber mit einem neuen Problem der "Springen", nachdem die Animation beendet:

codepen.io/stufu/pen/YxXaLR

Antwort

1

Sie CSS-Animation verwenden können. Beachten Sie, die Breite des Bildes (-250px) muss in die Animation fest einprogrammiert werden, aber dies kann dynamisch erzeugt werden:

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

Danke für den Kommentar @FuriousD. Ich habe meine Frage nicht genug erläutert und leider werden die Werte bei der oben beschriebenen Vorgehensweise nicht ganz funktionieren. Es gibt einen "Sprung", sobald er das Ende der Breite erreicht. –

+0

Es gibt ein paar Ansätze, die Sie verwenden könnten, indem Sie JS mit CSS-Animationen kombinieren - zum Beispiel mit JS, um Animationen neu auszulösen und so weiter. Ich bin mir nicht sicher, ob es eine triviale Lösung gibt, die keine harten Kodierungswerte beinhaltet. – FuriousD

+0

Ich denke, das ist ein Teil des Problems. Wenn Sie die Breite fest codieren (selbst wenn sie in vw ist), wird sie am Ende übersprungen.Ich stelle einen Codepen auf, um zu zeigen, was passiert: https://codepen.io/stufu/pen/YxXaLR Der Vorteil mit dem reinen JS-Ansatz ist es "unendlich" ändert die Hintergrundposition auf unendlich, CSS wird es neu starten. Aber ich habe es schwer, den setInterval –

0

Ich möchte ein Update schreiben, die ich in der Lage war erfolgreich erreichen Sie dies mit einer Menge Hilfe von der Antwort von @FuriousD. Letztendlich haben seine Einsichten dazu geführt und ich akzeptiere seine Antwort, aber ich wollte eine funktionierende Version dessen, was ich durch reines CSS erreicht habe, zur Verfügung stellen.

Grundsätzlich erfordert dies die Kenntnis der Abmessungen Ihres Hintergrundbildes. Durch das Codieren des Bildes mit der CSS-Animation kann es problemlos und mit einer guten Skalierbarkeit gescrollt werden. Hier ist mein Ergebnis:

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