2

I got a problem with GIFs and Javascript. I got different GIF-animations which are all the same format and I want them to change randomly after they are played one time.

I tried to solve this with Javascript but I only could make it work with an exact time to make the change and not when each GIF-animation is finished (they are all finishing at different times).

<html>
<head>
<script type="text/javascript">
<!--
var ima = [];

ima[0] = 'bilder/bild1.gif';
ima[1] = 'bilder/bild2.gif';
ima[2] = 'bilder/bild3.gif';
ima[3] = 'bilder/bild4.gif';

function BildWechsel()
{
    var num = Math.random();
    var ran = Math.floor((ima.length - 1) * num);

    document.images['wechsel'].src = ima[ran];
}

onload = function ()
{
    window.setInterval(function () { BildWechsel(); }, 10000);
}
//-->
</script>

</head>
<body>

<img id="wechsel" src="bilder/bild1.gif" border="0" alt="">

</body>
</html>

Is there any possibility to make this work? And if not in a browser, how else can you maybe make it work?

JabberwockyDecompiler
  • 3,318
  • 2
  • 42
  • 54
Manuel Bug
  • 43
  • 4
  • I think you have to save the individual times for each `gif` in an object. – Ismael Miguel May 08 '15 at 18:26
  • Will it be to cumbersome to add "running times" as a second dimension to your `ima` array? – PM 77-1 May 08 '15 at 18:26
  • In the end it will be around 40 different gif which should be played and I don't think it's possible to include all their running times... – Manuel Bug May 08 '15 at 18:35
  • Here's a clever (if inefficient) bit of js that may help you. From what I've found, the DOM does not expose individual frames of animated GIFs to js. So this bit of code grabs the raw GIF data through XHR and manipulates it. http://slbkbs.org/jsgif/ – Jonathan M May 08 '15 at 18:35
  • Looks interesting, I just not really into javascript so I don't really understand how to do this. It took me quite some time to get the above code together, so something simpler or something finished would help me really out... – Manuel Bug May 08 '15 at 18:52
  • @ManuelBug, understood, but you've chosen a task that requires js, and is very, very unusual (read "difficult"). Take a bit of time to get used to js, then dive into jsgif. It's pretty clever. – Jonathan M May 08 '15 at 18:54

2 Answers2

1

I would rewrite the Javascript like this:

window.onload = function () {

    var images = [
            {src:'bilder/bild1.gif',delay:3000},
            {src:'bilder/bild2.gif',delay:2000},
            {src:'bilder/bild3.gif',delay:1500},
            {src:'bilder/bild4.gif',delay:4000}
        ],
        element = document.images['wechsel'],
        change_image = function () {
            var image = images[ Math.floor( Math.random() * images.length ) ];
            // (Math.random()*images.length)>>0 would be a lot faster

            element.src = image.src;

            setTimeout(change_image, image.delay);
        };

    setTimeout(change_image, 10000);

};

The delay would change based on the image you currently have.

This has a few speed improvements and the code is as simple as it can get.

This was untested!

Here is a (slightly) changed version to change the text color:

window.onload = function () {

 var colors = [
   {name:'red',delay:3000},
   {name:'yellow',delay:1000},
   {name:'green',delay:2300},
   {name:'blue',delay:2600},
   {name:'pink',delay:1300},
   {name:'purple',delay:500},
  ],
  element = document.getElementById('span'),
  change_color = function () {
   var color = colors[ ( Math.random() * colors.length )>>0 ];

   element.style.color = color.name;
   
   setTimeout(change_color, color.delay);
  };
  
 setTimeout(change_color, 2000);
 
};
<span id="span" style="background:black;font-family:sans-serif;font-size:20px;font-weight:bold;padding:10px;">I change color!</span>
Ismael Miguel
  • 4,185
  • 1
  • 31
  • 42
  • This isn't a bad idea and I think this can work, but how can I get to know the correct delay for each gif? If I need to do it with trial and error I'll get crazy with all those different gifs... – Manuel Bug May 08 '15 at 20:21
  • 1
    @ManuelBug There are tons of GIF editors. Also, if you open the GIFs with Mplayer or VLC or Windows Media Player or GIMP, they all can tell you how long is the GIF. As an alternative, you can use an online convertion service to convert the GIF into a MP4 and check the size. – Ismael Miguel May 08 '15 at 20:54
  • Got another problem with this GIF animation. Would be great if someone could take a look: http://stackoverflow.com/questions/30155019/gif-changing-transition – Manuel Bug May 11 '15 at 08:40
  • Hey there, I just wanted to know if I can change the width and height of each GIF inside the Javascript? Is this possible? – Manuel Bug May 20 '15 at 10:53
  • @ManuelBug Yes, it is possible. You can either use the same way that you did for the `src`. And store it in the object. But, once again, you will need to know the `gif` dimentions. There are a few codes to get the original/natural width and height of the gif. – Ismael Miguel May 20 '15 at 11:08
  • Ok, but I need it for each GIF individually. So the first give should have this width and the second GIF another... – Manuel Bug May 20 '15 at 11:10
  • @ManuelBug For each gif, instead of `{src:'bilder/bild1.gif',delay:3000}`, use `{src:'bilder/bild1.gif',width:123,height:321,delay:3000}`, and on `element.src = image.src;`, you can use `element.style.width = image.width+'px';element.style.height = image.height+'px';`. – Ismael Miguel May 20 '15 at 11:17
0

Well, first off, there are many considerations here.

You first need to understand that you can have a multi-dimensional array consisting of a series of objects, instead of plain strings (which is what you have now). I suggest you do some reading on this here: (take a look at Mozilla's Developer Network, or google for it).

Now, you cannot do that with an interval, because intervals happen at a preset, well, interval. You need a timeout - but timeouts happen only once.

You can see where this is going, right? So you need to call the timeout again once the previous timeout has finished - that goes to a concept of "callback" (google "javascript callbacks").

In any case, I've put up a very simple example for you in JSFiddle - it doesn't solve your problem 100%, because I think it would be cool if you'd put some thinking into how this all works, but this should get you at least something to work with (also on JSFiddle - http://jsfiddle.net/Nitrium/kyvbnxfv/)

imab = []; 

imab[0] = {
    image: 'bilder/bild1.gif', 
    time: 1000
}

imab[1] = {
    image: 'bilder/bild2.gif', 
    time: 500
}

imab[2] = {
    image: 'bilder/bild3.gif', 
    time: 2500
}

imab[3] = {
    image: 'bilder/bild4.gif', 
    time: 100
}

function BildWechselB() {
    var num = Math.random();
    var ran = Math.floor((imab.length - 1) * num);

    return imab[ran];
}

var interval;

function callBack (imageSrc) {

    printImage(imageSrc);

    clearInterval(interval);

    var newRandomImage = BildWechselB();
    interval = window.setTimeout(callBack, newRandomImage.time, newRandomImage.image)
}

function printImage (src) {
    var imageSrc = document.createTextNode(src);
    var bodyTag = document.getElementsByTagName('body');
    bodyTag[0].appendChild(imageSrc);
}

var firstRandomImage = BildWechselB();

interval = window.setTimeout(callBack, firstRandomImage.time, firstRandomImage.image);

Hope it helps!

Giliar Perez
  • 106
  • 2