7

Is there a way to create a gif like image with javascript based on some png or jpg?

Just a simple code that change one image for another, creating the impression of a animation, just like a gif.

The idea is to use for generating a banner, so ill upload the pictures (thats done) and i need a code for this animation.

klidebharrow
  • 157
  • 1
  • 1
  • 8
  • 1
    what did you come up with in your initial search? – Matt K Feb 28 '12 at 17:41
  • 1
    You can do animations by replacing images using `setInterval()` or `setTimeout()`. While this isn't a "gif" file, it gives the appearance of animation. – Tim Withers Feb 28 '12 at 17:42
  • You can also use http://stackoverflow.com/questions/2191367/php-create-simple-animated-gif-from-two-jpeg-images the answers here for a guide? – MyStream Feb 28 '12 at 17:45

2 Answers2

26

Stackoverflow used this technique for its unicorn animations last april fools day. I preserved the animations on my website. The animation code is my own - I didn't look at how stackoverflow was doing it.

The concept is to create a sprite, and then change the background position on an interval.

sprite

const frameHeight = 102;
const frames = 15;
const div = document.getElementById("animation");
let frame = 0;
setInterval(function () {
    const frameOffset = (++frame % frames) * -frameHeight;
    div.style.backgroundPosition = "0px " + frameOffset + "px";
}, 100);
#animation { 
    background-image: url(https://jumpingfishes.com/dancingpurpleunicorns/charging.png);
    background-repeat: no-repeat; 
    height: 102px; 
    width: 140px; 
}
<div id="animation"></div>

Edit: If you don't want to create a sprite, here's an alternate technique you can use. Put all of your animation frame images in a div and hide all but the first one. In your setInterval function, change which image is diplayed:

const frames = document.getElementById("animation").children;
const frameCount = frames.length;
let i = 0;
setInterval(function () { 
    frames[i % frameCount].style.display = "none";
    frames[++i % frameCount].style.display = "block";
}, 100);
#animation img {
    display: none;
}
#animation img:first-child {
    display: block;
}
<div id="animation">
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging01.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging02.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging03.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging04.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging05.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging06.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging07.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging08.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging09.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging10.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging11.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging12.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging13.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging14.png" />
    <img src="https://jumpingfishes.com/dancingpurpleunicorns/charging15.png" />
</div>
gilly3
  • 87,962
  • 25
  • 144
  • 176
  • 1
    I'd say to do so, but in this case he uploaded many different pictures. – ClayKaboom Feb 28 '12 at 17:57
  • 1
    @Clay - I'd still suggest he combine those images into a single sprite. Traditional image swaps are usually too slow for a decent animation. Other techniques are possible, but have some disadvantages. – gilly3 Feb 28 '12 at 18:04
  • You code is pretty usefull having a fixed number of images, which i have not, as they'll be changed from time to time. Anyway, i liked very much your code and i'll look forward to use it. – klidebharrow Feb 28 '12 at 18:57
  • I found this code on another question from stackoverflow after asking, and was prettey usefull for my case. Nevertheless, your code is better. :) function chg1() { $('#myimage').attr('src', 'image1src.jpg'); } function chg2() { $('#myimage').attr('src', 'image2src.jpg'); } function StartAnimation() { setTimeout(chg1, 1000); // img 1 after 1 seconds setTimeout(chg2, 2000); // img 2 after 2 seconds setTimeout(StartAnimation, 3000); // start again after 3 seconds } StartAnimation(); // start it off – klidebharrow Feb 28 '12 at 19:06
  • 1
    @klide - I don't recommend that approach - I've seen a delay in changing the `src` of an image, even if the image is preloaded. It would be better to include all of the images in the page, and hide all but one of them. I've updated my answer with a solution that uses that technique. – gilly3 Feb 28 '12 at 19:20
  • Yes, exactly @gilly3. Right now i am switching to your new approach. Thanks! – klidebharrow Feb 29 '12 at 12:18
  • @gilly3, first of all thank, you for your elegant solution (the last one will fit my needs). Do you have any idea how can I update the code in order to stop the animation after 1,2 etc numbers of cycles? Can you update the jsfiddle or create another example please? I appreciate it, – typo_ Jan 17 '16 at 13:11
  • 1
    @typo_78 `setInterval` returns an interval id. Store that id in a variable and, when you want to stop the animation, pass the id to `clearInterval()`. – gilly3 Jan 17 '16 at 17:35
  • @gilly3 Sounds easy but unfortunately I am a pure noob especially in js; can you please expose ur answer into a fiddle with link? I am interested in the last solution (edited version) – typo_ Jan 17 '16 at 18:02
  • Hi gilly3 I will be grateful for your insight on https://stackoverflow.com/questions/74465300/animated-pictures-in-javascript-problem-flickering-screen-and-resizing I wonder do you have the same position on this topic, or maybe there are some new ways that you discovered and that you can share. – Paweł Pedryc Nov 16 '22 at 18:14
2

You can use setInterval or setTimeout to call a function which would replace the source of an image with another. Giving it an animated look.

The problem in this case is that, if the images do not pre-exist on the page, they will flicker. Since the browser will have to load them in just like any other image. So you would have to preload your images.

A better solution may be to use a spritemap. This means that you would have all of the different steps of the animation in one image (so no flicker). You would then use the CSS background-position (again, within a setInterval or setTimeout function) to change the position of the image.

Marshall
  • 4,716
  • 1
  • 19
  • 14
  • Thanks for the answer. I would use the idea of sprites if i have a fixed conjunt of images, but they'll change from time to time, preserving some and other not. Anyway, thanks for the tip! – klidebharrow Feb 28 '12 at 18:59