zooming icon indicating copy to clipboard operation
zooming copied to clipboard

Add a spinner while loading fullsize image

Open jimblue opened this issue 6 years ago • 8 comments

Hi there!

Actually when clicking on an image, Zooming doesn't provide any visual information to let the user know a better resolution image will show when loaded.

This can be a problem on devices with poor connection as users might close the Zoomed image before the full size image is displayed.

To let users know something better is coming, what do you think about adding a div with a css spinner while the full size image is loading.

Thanks for the good work on this awesome library btw 😄 !!

Cheers

jimblue avatar Jun 04 '18 19:06 jimblue

Yeah this is a good idea. However, I want to be careful about making it an opt-in feature because some people might not needed it. Maybe we can introduce two new event hooks onImageLoading and onImageLoaded, then user can add/remove loading indicator with their own styling. I'll experiment with it and see how it goes :)

  • https://stephanwagner.me/only-css-loading-spinner

kingdido999 avatar Jun 04 '18 23:06 kingdido999

Adding new event hooks also make sens for customisation, everyone will be able to add their own spinner design. That sounds great!

jimblue avatar Jun 05 '18 00:06 jimblue

The above two event hooks have been added to the latest release 2.1.0:

But I haven't figured out the most appropriate way to indicate the loading status yet. One thing I'm sure about is that we need to set a certain time threshold for the indicator to only show up in slow internet connection or the first fetch, otherwise it blinks which is a bit annoying.

kingdido999 avatar Jun 12 '18 04:06 kingdido999

One thing I'm sure about is that we need to set a certain time threshold for the indicator to only show up in slow internet connection or the first fetch, otherwise it blinks which is a bit annoying.

Turbolinks does this with a 500ms delay before showing the progress bar. I doubt this is based on any UX study, but I quite like the value.

migueldemoura avatar Jun 12 '18 12:06 migueldemoura

Hey @kingdido999,

Thanks for the new release! I've wrote a promise function to check image load properly. I use it to lazyload image everyday, it's pretty solid! You can probably improve the new event onImageLoaded with it.

/**
 * Method to fetch image from source
 *
 * @param {URL} imgSource
 * @returns {Promise}
 */
const fetchImage = imgSource => {
  // Return a promise to fetch the image
  return new Promise((resolve, reject) => {
    // Create a new image
    const imgElement = new Image()

    // Define events callbacks
    const loadCallback = () => {
      // Remove events listener
      imgElement.removeEventListener('load', loadCallback)
      imgElement.removeEventListener('error', errorCallback)

      // Resolve Promise
      resolve()
    }

    const errorCallback = () => {
      // Remove events listener
      imgElement.removeEventListener('load', loadCallback)
      imgElement.removeEventListener('error', errorCallback)

      // Reject Promise
      reject(Error(`Error while loading image at ${imgSource}`))
    }

    // Listen to load and error events on image
    imgElement.addEventListener('load', loadCallback)
    imgElement.addEventListener('error', errorCallback)

    // Set image source
    imgElement.src = imgSource
  })
}

You can use it like so:

fetchImage(imgSource).then(() => { console.log('image loaded') })

jimblue avatar Jun 12 '18 23:06 jimblue

About the time threshold, as usage will probably be different for each case, I suggest you to simply add an exemple into the doc.

In the end it's simple as adding a timeout to onImageLoaded callback... nope?

jimblue avatar Jun 13 '18 05:06 jimblue

Lastly to prevent the problem of the first fetch you could create an empty loaded array that will be filled as data-original source are loaded:

let loaded = []

if (loaded[imgIndex] === true) {
    onImageLoaded()
} else {
     fetchImage(imgSource).then(() => {
        onImageLoaded()
        loaded[imgIndex] = true
    })
}

This will help not impact performances.

jimblue avatar Jun 13 '18 06:06 jimblue

Hi @kingdido999!

Can we have your input on this please?

Tks

jimblue avatar Nov 18 '18 13:11 jimblue