6

The problem I have is that when the page is loaded sometimes it displays all the images, sometimes just 2 images and sometimes all. I don´t know why this is happening.

Any ideas?

    $('#banners .box img').each(function(index){
        var randval = (index+1)*100;
        var _this = $(this)
        setTimeout(function(){
            _this.attr('id' , 'banner' + index);
            to_canvas('banner' + index, 300, 223);
        }, randval)
    });

to_canvas function:

    function to_canvas(im,w,h){
        var canvas;
        var imageBottom;
        var im_w = w;
        var im_h = h;
        var imgData;
        var pix;
        var pixcount = 0;
        var paintrow = 0;
        var multiplyColor = [70, 116, 145];
        var x_offset = Math.floor(($('#'+im).attr('width') - im_w)/2);
        var y_offset = Math.floor(($('#'+im).attr('height') - im_h)/2);
        imageBottom = document.getElementById(im);
        canvas = document.createElement('canvas');
        canvas.width = im_w;
        canvas.height = im_h;
        imageBottom.parentNode.insertBefore(canvas, imageBottom);
        ctx = canvas.getContext('2d');
        ctx.drawImage(imageBottom, -x_offset , -y_offset);
        imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        pix = imgData.data;
        for (var i = 0 ; i < pix.length; i += 4) {
            if(pixcount > im_w - (im_h - paintrow) ){
                pix[i  ] = multiply(multiplyColor[0], pix[i  ]);
                pix[i+1] = multiply(multiplyColor[1], pix[i+1]);
                pix[i+2] = multiply(multiplyColor[2], pix[i+2]);
            }
            if(pixcount < im_w-1){
                pixcount++;
            }else{
                paintrow++;
                pixcount = 0;
            }
        }
        ctx.putImageData(imgData, 0, 0);
        $('#'+im).remove();
    }
    function multiply(topValue, bottomValue){
        return topValue * bottomValue / 255;
    }

I'm using the canvas function to add a triangle with multiply effect (like Photoshop).

  • 2
    Sadly I don't have an answer for you, but have you tried monitoring your website traffic to see whether the images are being called or not? In Firebug the 'NET' tab will show you all the traffic as a page loads - you'll be able to see whether the images are being called, or are loading (or failing), or are being called and loaded successfully, in which case it's a bug somewhere in the way you're displaying it. – johnkavanagh May 13 '13 at 13:27
  • I have just noted, that images don't show, when I refresh page without caching (ctrl+f5). But that are downloaded successfully (checked in firebug). When you just refresh page and allow browser to just cache (just F5), images are visible. Maybe it will help you – Jakub Matczak May 13 '13 at 13:32
  • 1
    You're sure you should'nt wait until the images are loaded, i.e. somewhow use the onload event of the images, before you start using them for something ? – adeneo May 13 '13 at 13:36
  • It takes some time to load the images, that is why they show up correctly when you reload the page (cached version). – RST May 13 '13 at 13:37
  • When are you kicking this process off? My guess would be that the images aren't fully loaded before you're kicking off the canvas code (it works when the images are cached from the first time through, because *then* they load fast enough that they're ready before your code runs.) Try something like Paul Irish's "images loaded" plugin, as mentioned in [this question](http://stackoverflow.com/questions/910727/jquery-event-for-images-loaded) to kick things off, rather than `ready`. – Matt Gibson May 13 '13 at 13:39
  • But the images are just like 100kb each, why would it take too much time to load them? –  May 13 '13 at 13:40
  • You can optimize your code a little by changing the for-loop to `for (var i = 0, j = pix.length; i < j ; i += 4) {` – RST May 13 '13 at 13:57
  • @fxg Even if the images are 10kb each, you might still find that a dozen lines of JavaScript can run before they travel across a network. It's not that loading the images is *slow*, it's just that it's slow*er* than the time between the document being ready and your Javascript running. – Matt Gibson May 15 '13 at 11:07

2 Answers2

1

Make sure the images are loaded :

$('#banners .box img').each(function(index, elem){
    var randval = (index+1)*100,
           self = this,
            img = new Image();    // create image object

    img.onload = function() {     // wait until it's loaded
        setTimeout(function(){
            self.id = 'banner' + index;
            to_canvas('banner' + index, 300, 223);
        }, randval)
    }
    img.src = elem.src;          // set source to same as elem
});
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • This works too but I think @derek_duncan answer its much more simple solution. What advantage would I have using it this way? –  May 13 '13 at 13:54
  • You would'nt have to wait for window.onload, but instead just make sure each image has completely loaded. – adeneo May 13 '13 at 13:57
  • Ok, this is a better way I think. Thanks –  May 13 '13 at 13:59
0

Wrap it all in this code to make sure the images are loaded before you execute your script. When you initially load your page, it caches the images(stores them in temp memory), but not before all your elements are rendered. When you reload, it reads the images from the cache–which is much faster than refetching the images again from the server–and therefore the images load about the same time everything else does. This results in visible images.

Like I said, to get your page to work, make sure everything is loaded, then run your script.

$(window).load(function(){
    ...your scripts(you can exclude functions definitions from this scope)
}
derek_duncan
  • 1,377
  • 1
  • 13
  • 22