-2

This is a specific problem but I believe the pattern here may be general enough to be useful to the audience here.

I'm working on an offline JS application. In my JS application, I would like to run programmatically generated reports. No problem. I can render to canvas and then convert to pdf (oh the wonders of JS libraries these days). But there's one nagging problem: image rendering.

I do not know (and in some cases, cannot know) the images necessary to load until the report is being generated. I have access to the images encoded in Base 64, so they are not remote and are more or less guaranteed to load. However, loading an image is not guaranteed to be synchronous - even for an already in-memory string. Additionally, it is not possible to say "I'll just draw the picture once loaded" because painting order matters. Right now I'm resorting to pre-loading my whole image library (yuck!), but about the only other method I can see to make this work is a refactor to have a "gather resources" pre-step per report instance and some very not fun callback work. I can't load resources upfront (other than my current method) because resources aren't known at startup time, which seems to partially rule out the usual AMD approach.

Sigh - I wish in-memory resources loaded synchronously. So do I just need to buckle down and make the refactor or is there a better way?

J Trana
  • 1,369
  • 9
  • 17
  • The "very not fun callback work" is drastically simplified when you make use of promises. – zzzzBov Jul 02 '15 at 16:27
  • This seems like a bit of strange use case, so a couple questions (my reputation isn't high enough to comment): Why do you need to load this stuff asynchronously in the first place? If this application is offline, then I assume the files are local or accessible through a representable local path. Why are they in memory when you could just point them at a path? it seems like you're over complicating this, or perhaps you could clarify better why you need to do this? – Graham Bass Jul 24 '15 at 16:22
  • The images are not accessible via a path, because there is no traditional path - they literally only exist as Base-64 encoded images that get imported via zip files and decoded in memory. The use case is that plugins for content can get added to the system and the contents stored in local storage. – J Trana Jul 26 '15 at 05:40

2 Answers2

0

Regular html image tags hard coded on the page, but do not give them an src attribute.

after everything on the page is loaded, use jquery and add an src attribute to each image tag you want, and it will automatically go out and grab that image.

write some code to figure out what image you want based on what has loaded, then

$(document).ready(function () {
 $('#somethingunique').attr('src', 'urlOfTheDesiredImage');
});
  • This sounds like it necessitates all images being loaded on the page itself upfront. Am I understanding this right? Or is there something more selective? – J Trana Jul 03 '15 at 03:36
0

It's 2020 and you can easily wrap it in a Promise so you can await it with no polyfills. You can even make a decoding hint of sync if you want but not needed. Callback purgatory is avoided!

const loadImagePromise = url => new Promise( resolve => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.decoding = 'sync';
    img.src = url;
});

and then:

let img = await loadImagePromise(url);
J Trana
  • 1,369
  • 9
  • 17