Reputation: 5129
I'm stacking 5 images by attributing to all of them an absolute position with the same top and left coordinates and a different z-index.
My goal is to rotate, translate and turn to 0 the opacity of the image having the highest z-index and increasing by 1 the z-index of all the other images. I'm animating the image having the highest index with CSS transfomations and I change the z-index of the other images with jquery. My code is the following:
var i = 1;
function swypeStyle(){
var imageLength = $('.my-image').length;
$('.my-image').each(function(){
$(this).removeClass('rotated');
});
$("#image"+i).addClass('rotated');
setTimeout(function(){
for(var j = 1; j <= imageLength; j++){
var currentZindex = $('#image'+j).css('z-index');
if(currentZindex == imageLength){
currentZindex = 1;
}else{
currentZindex++;
}
$('#image'+j).css('z-index',currentZindex);
}
}, 1100);
if(i == imageLength){
i = 1;
}else{
i++;
}
}
window.setInterval(function () {
swypeStyle();
}, 3000);
.my-image{
width: 144px;
left: 0px;
top: 0px;
position: absolute;
}
.my-image.rotated {
left: -150px;
top: 25px;
-webkit-transform: rotate(-30deg);
opacity: 0;
-webkit-transition: all 1s ease-in-out;
}
<img src="https://www.otop.sg/retailer/images/image1.jpg" class="my-image" id="image1" style="z-index: 5;">
<img src="https://www.otop.sg/retailer/images/image2.jpg" class="my-image" id="image2" style="z-index: 4;">
<img src="https://www.otop.sg/retailer/images/image3.jpg" class="my-image" id="image3" style="z-index: 3;">
<img src="https://www.otop.sg/retailer/images/image4.jpg" class="my-image" id="image4" style="z-index: 2;">
<img src="https://www.otop.sg/retailer/images/image5.jpg" class="my-image" id="image5" style="z-index: 1;">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
My animation works well, the problem is when I switch and spend some time on an other chrome tab and when I go back on my script chrome tab there's a lag between my css animation and my jquery animation.
Upvotes: 0
Views: 104
Reputation: 68
If you really can't give up your jQuery animations, you could try wrapping your animations in a requestAnimationFrame()
loop.
As MDN explains:
Like CSS transitions and animations, requestAnimationFrame() pauses when the current tab is pushed into the background.
Here is an example:
Usage:
// Get element.
const elem = document.querySelector( '#elementID' )
// Get current size.
const startSize = elem.width
// Set end size.
const endSize = startSize * 2 // Double the size of the element.
// Set animation duration.
const duration = 1000 // 1000ms -> 1s
animate( ratio => {
setWidth( elem, lerp( startSize, endSize, ratio ))
}, duration )
Implementation:
// Resolves a promise once an animation is complete.
// Allows you to specify an animation duration, start and end values,
// and automatically handles frame interpolation.
function animate( callback, duration ) {
return new Promise( resolve => {
let
// Amount of time in ms since last frame
delta = 0,
// Used to calculate delta
lastTimestamp = 0,
// Ratio for use in linear interpolation.
// Passed through to the callback and incremented
// with respect to duration.
// The ratio determines how far along the start and end values we are.
ratio = 0,
// Speed is an inverse function of time, since ratio is normalized.
speed = 1 / duration
// Start the update loop
update( performance.now())
// Update loop
function update( timestamp ) {
if ( ratio < 1 ) {
// Calculate frame delta and update last frame's timeStamp.
// In the first frame, set lastFrame to this frame's timeStamp.
delta = timestamp - ( lastTimestamp || timestamp )
lastTimestamp = timestamp
// Update ratio as a function of speed and frame delta
ratio = clamp( ratio + ( speed * delta ))
// Execute callback
callback( ratio )
// Request next frame
requestAnimationFrame( update )
}
// Make good on the promise
else resolve()
}
})
}
/** Linear interpolation between two scalars */
function lerp( min, max, t ) {
/*
* Get difference, multiply by `t` and add min.
*
* The ratio `t` represents the percentage of that distance
* we add back to min, so that a fraction of 1 adds 100%
* of the distance, which equals the max value.
*
* Precise form of linear interpolation,
* ensures t=1 always equals max.
*/
return ( 1 - t ) * min + t * max
}
// Set width of an element
function setWidth( element, width ) {
element.style.width = `${ width }px`
}
More about requestAnimationFrame()
Upvotes: 1
Reputation: 5129
I used css to do my animation because you can't animate rotation with the jQuery animate function.
Thanks to this post CSS rotation cross browser with jquery.animate() I found a work around and now my animation is 100% jQuery and there is no lag anymore.
var i = 1;
function AnimateRotate(angle,elem) {
$({deg: 0}).animate({deg: angle}, {
duration: 700,
step: function(now) {
elem.css({
transform: 'rotate(' + now + 'deg)'
});
}
});
}
function swypeStyle(){
var imageLength = $('.my-image').length;
$('.my-image').each(function(){
$(this).css({
"left": 0,
"top": 0,
"opacity": 1,
WebkitTransform: 'rotate(0deg)',
'-moz-transform': 'rotate(0deg)'
})
});
AnimateRotate("-30",$("#image"+i));
$("#image"+i).animate({
"left": "-150px",
"top": "25px",
"opacity": 0
},700);
setTimeout(function(){
for(var j = 1; j <= imageLength; j++){
var currentZindex = $('#image'+j).css('z-index');
if(currentZindex == imageLength){
currentZindex = 1;
}else{
currentZindex++;
}
$('#image'+j).css('z-index',currentZindex);
}
}, 1100);
if(i == imageLength){
i = 1;
}else{
i++;
}
}
window.setInterval(function () {
swypeStyle();
}, 3000);
.my-image{
width: 144px;
left: 0px;
top: 0px;
position: absolute;
}
<img src="https://www.otop.sg/retailer/images/image1.jpg" class="my-image" id="image1" style="z-index: 5;">
<img src="https://www.otop.sg/retailer/images/image2.jpg" class="my-image" id="image2" style="z-index: 4;">
<img src="https://www.otop.sg/retailer/images/image3.jpg" class="my-image" id="image3" style="z-index: 3;">
<img src="https://www.otop.sg/retailer/images/image4.jpg" class="my-image" id="image4" style="z-index: 2;">
<img src="https://www.otop.sg/retailer/images/image5.jpg" class="my-image" id="image5" style="z-index: 1;">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 2261
The issue is that when your tab isn't active, Chrome will suspend items like animations, to reduce resource utilization.
My recommendation would be to do all of the transitions/animations in CSS only and use Javascript to only add/remove classes; this way the animations will remain synchronized.
Upvotes: 1