Skip to content

Instantly share code, notes, and snippets.

@ivan-demchenko
Last active July 24, 2017 02:49
Show Gist options
  • Save ivan-demchenko/8ada89cf0d4868a8bb3df74c2c65f127 to your computer and use it in GitHub Desktop.
Save ivan-demchenko/8ada89cf0d4868a8bb3df74c2c65f127 to your computer and use it in GitHub Desktop.
Show the pre-loader when image loading takes more than X milliseconds
// just a helper
var $ = document.querySelector.bind(document);
// "show me the next image" button
var nextImage = Bacon.fromEvent($('#next'), 'click');
// this button simulated "onload" event for the img tag
var img = Bacon.fromEvent($('#loaded'), 'click').map(_ => 'image.jpg.' + Math.random());
// We need a stream that will be ended either on its own or by another stream.
// This is how we can build a "smart preloader" which knows when to reveal itself.
// Note 1: because the preloader stream will be ended, we need to create such stream anew
// each time user want to see next image. This is why, here we have a function.
// Note 2: this stream will have eather ("preloader.gif", <end>) values or just (<end>). In other words,
// img stream just ends reloader stream, but does not pollute it with a value.
var preloaderOrImage = () => Bacon.once("preloader.gif").delay(2000).takeUntil(img);
// map each call for the next image to smart preloader.
var cancelablePreloader = nextImage.flatMap(preloaderOrImage);
// finally, merge image and smart preloader. In other words, log a value that will come faster.
var result = img.merge(cancelablePreloader).log();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment