0

I'm trying to write a function that merges 2 images and then returns the Data URL of the merged image. On image2.onload I am setting mergedUrl to c.toDataUrl() and trying to return mergedUrl in the main function; however, since return mergedUrl is getting called before image2.onload, it is always empty.

async function mergeImages(source1, source2, currentPageNumber){
    let image1 = new Image();
    image1.src = source1;
    var c = document.createElement('canvas');
    var ctx = c.getContext("2d");
    let mergedUrl = ''
    image1.onload = async function (){
        c.width = image1.width;
        if(currentPageNumber > 1){
            c.height = image1.height + (image1.height/(currentPageNumber));
        } else {
            c.height = image1.height;
        }
        ctx.drawImage(image1, 0, 0);

        let image2 = new Image();
        image2.src = source2;
        image2.onload = async function (){
            ctx.drawImage(image2, 0, image1.height);
            mergedUrl = c.toDataUrl();
        };
    };
    await return mergedUrl;
}

Davidm113021
  • 81
  • 1
  • 6
  • you're mixing asynchronous and synchronous code. Fundamentally the approach will never work as it is. You could either a) instead of trying to return a value from mergeImages directly, require the caller to supply a callback function (as an input parameter) which can be executed by your onload function (so they have a way to receive the URL once it's ready), or b) wrap the onload in a Promise and return the Promise from mergeImages - the caller can then handle the events emitted by the Promise (e.g. "done", etc) and execute their own callbacks to access the data. – ADyson Apr 27 '20 at 15:46
  • @AlonEitan Do you mind taking a look at the updated code? I tried using await/async like in the answer to that question, but the same thing is still happening.. – Davidm113021 Apr 27 '20 at 17:51
  • There's a bit more to it than that, try reading [Making asynchronous programming easier with async and await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await), you'll learn some cool stuff :) – Alon Eitan Apr 27 '20 at 18:08

1 Answers1

0

What about

imgCount=0;

image1.onload=function(){
   imgCount++;
   if (imgCount==2){
      imgCount=0;
      return mergeImageFunction();
   }
   else return false;
}

image2.onload=function(){
   imgCount++;
   if (imgCount==2){
      imgCount=0;
      return mergeImageFunction();
   }
   else return false;
}

The functions only do the image merging once for every pair of images loaded. This is obviously not a cut n paste answer but this is how I would solve it if it was just two static images that wont flicker onto a third onload event on the same element.

Stephen Duffy
  • 467
  • 2
  • 14
  • 2
    I'm sorry but this Spaghetti code is not recommended - OP should use a [promise based](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) solution – Alon Eitan Apr 27 '20 at 16:02