0

I've got a question in regards to javascript and dynamically displaying images to form an animation. The pictures I have are around 1360x768 in size and quite big despite being .png pics.

I've come up with a code for switching out the pics dynamically, but even run on a local webserver it is too slow (thus sometimes I see the pic being built).

So my question is: is there a better way to do this than dynamically switching out the "src" part of the image tag, or is there something else that could be done in combination with that, to make sure that the user doesn't have any strange phenomenons on the client?

<script>
var title_index = 0;

function display_title()
{
    document.getElementById('picture').src=
        "pics/title_" + title_index + '.png';
    if (title_index < 100) {
            title_index = title_index + 5;
            setTimeout(display_title,3000);
        }

}
</script>
<body onload="setTimeout(display_image,3000)">
    <image  id="picture" src="pic/title_0.png"/>
</body>

Thanks.

Thomas
  • 2,886
  • 3
  • 34
  • 78

2 Answers2

2

I've had this problem too, even when preloading the images into the cache,

Google's The Hobbit experiment does something interesting. They do low resolution while animating and switch it for a hiresolution if you "pause" (stop scolling in the case of The Hobbit experiment). They also use the HTML5 canvas tag to smooth out the animation.

Here's their blog post about their method:

http://www.html5rocks.com/en/tutorials/casestudies/hobbit-front-end/

Their end product:

http://middle-earth.thehobbit.com

Edit: Pre loading example:

<!Doctype html>
  <head>
    <title>test</title>
  </head>
<body>

<canvas id="myCanvas" width="1360" height="768"></canvas>
<script type="text/javascript">
      var images = {};
      var loadedImages = 0;
      var numImages = 0;
      var context = '';
      function loadImages(sources, callback)
      {
        // get num of sources
        for(var src in sources)
        {
          numImages++;
        }
        for(var src in sources)
        {
          images[src] = new Image();
          images[src].onload = function()
          {
            if(++loadedImages >= numImages)
            {
              callback(images);
            }
          };
          images[src].src = sources[src];
        }
      }

      var canvas = document.getElementById('myCanvas');
      context = canvas.getContext('2d');
      var sources =
      {
        frame0: 'http://piggyandmoo.com/0001.png',
        frame1: 'http://piggyandmoo.com/0002.png',
        frame2: 'http://piggyandmoo.com/0003.png',
        frame3: 'http://piggyandmoo.com/0004.png',
        frame4: 'http://piggyandmoo.com/0005.png',
        frame5: 'http://piggyandmoo.com/0006.png',
        frame5: 'http://piggyandmoo.com/0007.png',
        frame5: 'http://piggyandmoo.com/0008.png',
        frame5: 'http://piggyandmoo.com/0009.png' 
      };
      var width = 1360;
      var height = 768;
      var inter = '';
      var i = 0;
      function next_frame()
      {
        if(numImages > i)
        {
          context.drawImage(images['frame' + (i++)], 0, 0);
        } 
        else
        {
           clearInterval(inter);
        }
      }

      loadImages(sources, function(images)
      {
        //animate using set_timeout or some such...
          inter = setInterval(function()
          {
            next_frame();
          }, 1000);
      });

</script>
</body>

Code modified from: www.html5canvastutorials.com/tutorials/html5-canvas-image-loader/

J. A. Streich
  • 1,683
  • 10
  • 13
  • Tested it: Principially it functions, only the next_frame is called immediately for every picture (thus the last pic of the frames shown immediately). does it function with the waiting for each picture for you? – Thomas Feb 28 '14 at 20:27
  • @ThomasE. Just fixed it. Somehow I missed those changes when I moved it to stackoverflow. The demo at http://piggyandmoo.com/test.html already had those changes. (dunno how I missed them when I moved it) – J. A. Streich Feb 28 '14 at 20:51
  • on piggyandmoo.com/test.html I see the final pic only. when I use your example and run it locally I see the first frame and the final frame, but none of the ones in between. – Thomas Feb 28 '14 at 21:00
  • Ah, you are right. I forgot to take out the loop. I'm accidentally setting up as many intervals as frames. Take out the loop, and limit running off the end of the image array in the next_frame function. It's working on the piggyandmoo.com/test page. I'll edit my answer again. – J. A. Streich Feb 28 '14 at 21:15
1

You could overcome this issue by preloading the images on page load. This means that the images would then be stored in memory and immediately available to you. Take a look at the following:

JavaScript Preloading Images

http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Community
  • 1
  • 1
gimg1
  • 1,121
  • 10
  • 24