Home > Software engineering >  Animated pictures in JavaScript, problem: flickering screen and resizing
Animated pictures in JavaScript, problem: flickering screen and resizing

Time:11-17

As I mentioned in the title I have a problem properly embedding my animation in my Django project.

At some point, I decided to update the logo used by my web page built-in Django. Having small experience with JavaScript I was looking for approaches that fit my needs. I built an animation engine having some inspiration from this StackOverflow answer. (Thanks to user gilly3).

My approach is, though, different in this topic because I realised that if I would have a lot of pictures then sticking/concatenating them together in one file might be difficult. I've decided to use another approach and use a bunch of files instead of one. For that sake, I built a function with a generator which I could call in another function to display all pictures in order. This animation engine looks like this:

function* indexGenerator() {
    let index = 1;
    while (index < 28) {
        yield index  ;
    }
    if (index = 28)
        yield* indexGenerator();
  };

var number = indexGenerator();


setInterval(function animationslider()
{
    var file = "<img src=\"../../../static/my_project/logos/media/slides_banner_f/slide_"   number.next().value   ".jpg\" />";
    document.getElementById("animation-slider").innerHTML = file;
    
    $("#animation-slider").fadeIn(1000);
    
    
}, 100);

$("#animation-slider").fadeIn(1000); doesn't do the trick with values from 10-1000. I record what this looks like: https://youtu.be/RVBtLbBArh0

I suspect that the solution to the first relocation problem can be solved using CSS, but I don't know how to do it, yet.

The blinking/flickering of the animation is probably caused by loading all these images one by one. In the example video above, there are 28 of them. I wonder if this content would be loaded asynchronously (e.g. using Ajax) would it solve the problem? Is it possible to load all and after all is loaded, then display the animation (some sort of preloading)? I will be grateful for all suggestions and hints.

I'm aware that in the topic mentioned by me before there is a solution. But I'm curious about other approaches.

CodePudding user response:

At the moment, from what I checked, the best method would be to convert pictures to the format:

Having that kind of file, there is no problem with loading and flickering.

CodePudding user response:

The flickering is the time it takes to create the dom element, insert it into your page, make the web request to download the image, and final render the image. That's too much work to do in the moment you want to animate the next frame! It would look even worse running from a client with a poor connection to the server.

To solve this, preload all of the images. This is the benefit of a sprite - it loads all at once by its very nature. But, if you have individual images, you can still preload them. Just hide them all at first, and show them one by one.

One way you can show them one at a time, is to set up a style that hides all but the first child image. Then, to animate, move the first image to the end of the list.

#animation-slider img ~ img {
    display: none;
}
const animationContainer = document.getElementById("animation-slider");
for (let i = 0; i < 28; i  ) {
    const img = document.createElement("img");
    img.src = `../../../static/my_project/logos/media/slides_banner_f/slide_${i}.jpg`;
    animationContainer.appendChild(img);
}

setInterval(() => animationContainer.appendChild(animationContainer.children[0]), 100);

Here's a working example, using my own image:

const animationContainer = document.getElementById("animation-slider");
for (let i = 1; i < 16; i  ) {
    const img = document.createElement("img");
    img.src = `https://jumpingfishes.com/dancingpurpleunicorns/charging${i.toString().padStart(2, "0")}.png`;
    animationContainer.appendChild(img);
}

setInterval(() => animationContainer.appendChild(animationContainer.children[0]), 100);
#animation-slider img ~ img {
    display: none;
}
<div id="animation-slider"></div>

  • Related