skip to Main Content

In short, I would like to create a lazy-loaded-mock-image-src-url in browser. This is in order to simulate the loading of an image, to see how it loads.

Here is how I would like the flow to work, all done in-browser.

  1. Create a URL using URL.createObjectURL, canvas.toDataURL or similar, where the actual image that the returned url refers to, is not loaded yet (just like a real scenario).
  2. Pass the returned url that refers to the unloaded image to an html-img-tag.
  3. The image does not (visibly) load in the html-img-tag.
  4. Trigger a load of the image (that the url refers to) (preferably using some JS function) after some delay.
  5. The actual image is (visibly) shown in the html-img-tag.

I have managed to create a src string in the browser that refers to an image, that is passed to an html-img-tag, BUT the image loads instantly.

const canvas = document.createElement('canvas');
// ...create the image using getContext, fillRect etc...
const url = canvas.toDataURL('image/png');

How can I make sure the image that the url refers to is not loaded initially?

Is it better to use URL.createObjectURL or some other method instead?

Is it at all possible?


PS. I don’t want to edit the html-img-tag, using onload method as the img is a 3rd party (react) component.

2

Answers


  1. You can try to progressively pass chunk of the url data to the img tag src attributes.

    const canvas = document.createElement('canvas');
    canvas.width = 300;
    canvas.height = 200;
    const ctx = canvas.getContext('2d');
    
    // Draw a blue rectangle
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 200);
    
    // Draw a red rectangle
    ctx.fillStyle = 'red';
    ctx.fillRect(200, 50, 100, 200);
    
    
    // Convert the canvas to a data URL
    const url = canvas.toDataURL('image/png');
    
    
    // Now use 'url' to progresively pass chunck of data
    // to img.src
    
    let inter = null;
    let counter = 4;
    
    function slowlyLoadImg(img, segment, time) {
        counter = 4;
        inter = setInterval(() => {
        img.src = url.slice(0, url.length / counter);
        counter -= segment;
        if(counter < 0){
            img.src = url;
             clearInterval(inter);
        }
    }, time);
    }
    
    window.onload = function() {
        const img = document.querySelector('img');
        slowlyLoadImg(img, 1, 800);
    }
    
    Login or Signup to reply.
  2. With modern internet speeds images load in milliseconds, to simulate the loading of an image one possibility is to "partially" draw the image in our canvas, and of course with a canvas we can add a lot of fancy animations, imagination is the limit…


    Here is a simple left to right animation we can use to simulate the loading of an image.

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var x = 0
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath()
      ctx.drawImage(image, 0, 0, x, image.height, 0, 0, x, image.height);
      x = x + 1
      if (x < image.width) {
        ctx.rect(x, 0, 1, canvas.height)
        ctx.stroke()
        setTimeout(draw, 50)
      }
    }
    
    var image = new Image();
    image.src = "http://i.stack.imgur.com/UFBxY.png";
    image.onload = draw;
    <canvas id="canvas" width=500></canvas>

    Here is another simple animation using blur

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var x = 50
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath()
      ctx.filter = 'blur(' + x + 'px)'
      ctx.drawImage(image, 0, 0, image.width, image.height);
      x = x - 0.5
      if (x >= 0) {
        setTimeout(draw, 50)
      }
    }
    
    var image = new Image();
    image.src = "http://i.stack.imgur.com/UFBxY.png";
    image.onload = draw;
    <canvas id="canvas" width=500></canvas>

    You can use the canvas directly as your image instead of an html-img-tag but if you really want to use an image <img src="." > the code is simple…
    after we draw in the canvas we select and add the output of toDataURL

      var img = document.querySelector('img')
      img.src = canvas.toDataURL('image/png')
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search