mlisook / plastic-image

A Polymer 3.0 element which adds extra plasticity to <iron-image> with support for srcset and lazy loading
MIT License
30 stars 6 forks source link

Ability to show a placeholder while source has not been fully loaded? #36

Closed BorntraegerMarc closed 6 years ago

BorntraegerMarc commented 6 years ago

Is there a way to show a default image ("loading" image for example) while the src has not been fully fetched?

mlisook commented 6 years ago

Yes. You can put any url in the placeholder attribute. I normally use a tiny downscaled base64 image of the same image I'm loading, but any image url will work.

<plastic-image id="i50" use-element-dim lazy-load preload fade 
        placeholder="images/loading.gif"
        sizing="contain" srcset="images/IMG_20170425_111558-150x150.jpg 150w, images/IMG_20170425_111558-300x225.jpg 300w, images/IMG_20170425_111558-768x576.jpg 768w"
        style="height: 300px; width: 80%;">
</plastic-image>

Another technique I've used is to encode an animated SVG spinner image:

static get properties() {
        return {
          _svgSpinner: {
            type: String,
            value: () => {
              return 'data:image/svg+xml;charset=utf-8,' +
        encodeURIComponent(
`<svg width="135" height="135" viewBox="0 0 135 135" xmlns="http://www.w3.org/2000/svg" fill="#28a096">
    <path d="M67.447 58c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10zm9.448 9.447c0 5.523 4.477 10 10 10 5.522 0 10-4.477 10-10s-4.478-10-10-10c-5.523 0-10 4.477-10 10zm-9.448 9.448c-5.523 0-10 4.477-10 10 0 5.522 4.477 10 10 10s10-4.478 10-10c0-5.523-4.477-10-10-10zM58 67.447c0-5.523-4.477-10-10-10s-10 4.477-10 10 4.477 10 10 10 10-4.477 10-10z">
        <animateTransform
            attributeName="transform"
            type="rotate"
            from="0 67 67"
            to="-360 67 67"
            dur="2.5s"
            repeatCount="indefinite"/>
    </path>
    <path d="M28.19 40.31c6.627 0 12-5.374 12-12 0-6.628-5.373-12-12-12-6.628 0-12 5.372-12 12 0 6.626 5.372 12 12 12zm30.72-19.825c4.686 4.687 12.284 4.687 16.97 0 4.686-4.686 4.686-12.284 0-16.97-4.686-4.687-12.284-4.687-16.97 0-4.687 4.686-4.687 12.284 0 16.97zm35.74 7.705c0 6.627 5.37 12 12 12 6.626 0 12-5.373 12-12 0-6.628-5.374-12-12-12-6.63 0-12 5.372-12 12zm19.822 30.72c-4.686 4.686-4.686 12.284 0 16.97 4.687 4.686 12.285 4.686 16.97 0 4.687-4.686 4.687-12.284 0-16.97-4.685-4.687-12.283-4.687-16.97 0zm-7.704 35.74c-6.627 0-12 5.37-12 12 0 6.626 5.373 12 12 12s12-5.374 12-12c0-6.63-5.373-12-12-12zm-30.72 19.822c-4.686-4.686-12.284-4.686-16.97 0-4.686 4.687-4.686 12.285 0 16.97 4.686 4.687 12.284 4.687 16.97 0 4.687-4.685 4.687-12.283 0-16.97zm-35.74-7.704c0-6.627-5.372-12-12-12-6.626 0-12 5.373-12 12s5.374 12 12 12c6.628 0 12-5.373 12-12zm-19.823-30.72c4.687-4.686 4.687-12.284 0-16.97-4.686-4.686-12.284-4.686-16.97 0-4.687 4.686-4.687 12.284 0 16.97 4.686 4.687 12.284 4.687 16.97 0z">
        <animateTransform
            attributeName="transform"
            type="rotate"
            from="0 67 67"
            to="360 67 67"
            dur="8s"
            repeatCount="indefinite"/>
    </path>
</svg>`);
            }
          }
        };
      }
<plastic-image id="i50" use-element-dim lazy-load preload fade 
        placeholder="[[_svgSpinner]]"
        sizing="contain" srcset="images/IMG_20170425_111558-150x150.jpg 150w, images/IMG_20170425_111558-300x225.jpg 300w, images/IMG_20170425_111558-768x576.jpg 768w"
        style="height: 300px; width: 400px;">
</plastic-image>

This provides a nice animated set of spinning circles while loading. The SVG used above is from Sam Herbert SVG Loaders.

BorntraegerMarc commented 6 years ago

Worked like a charm. Thanks!

BorntraegerMarc commented 6 years ago

@mlisook I just noticed that on safari the placeholder is never replaced with the actual image. Are you awar eof the bug?

BorntraegerMarc commented 6 years ago

@mlisook sorry false alarm. forgot to include the polyfills in our prod build :) but I did noticed something weird when using the polyfills: If the image is for 1 milisecond in the viewport & then the browser scrolls away -> the image is never loaded

Happens only on page re-load

have you come across this issue?

mlisook commented 6 years ago

@BorntraegerMarc thanks for the reports about these.

Regarding the first, Safari, I started investigating as soon as I got the notification from Github. I actually am seeing a problem with IOS Safari (but not MacOS Safari) when used in conjunction with something else that handles scroll events also. For example iron-scroll-threshold or iron-scroll-target-behavior seems to cause the intersection observer to not get some or even most scroll events. It doesn't happen on the Mac Safari. This is pretty concerning since Polymer Starter Kit and anything using the app-layout would have iron-scroll-target-behavior. I need some more testing, but I have a simple fix for this in mind. Safari is the only browser that needs the polyfill now.

Regarding the second one, I have not seen that or tried to duplicate it yet (if you have a minimal example that would be appreciated). Do you suspect that is platform specific?

BorntraegerMarc commented 6 years ago

@mlisook I'm confused now. I only reported one bug 😄

I'm experiencing the exact same bug with IE 11 (but not edge). So it's not only safari

mlisook commented 6 years ago

Edge has native support for IntersectionObserver, but you are right, IE does not.

So "same bug" ... is that the first, second or both?

BorntraegerMarc commented 6 years ago

I mean this bug:

but I did noticed something weird when using the polyfills: If the image is for 1 milisecond in the viewport & then the browser scrolls away -> the image is never loaded

mlisook commented 6 years ago

Please try new release 1.0.13

If this does not resolve your issue would it be possible for you to either:

In the meantime, I will continue to try to duplicate this myself, but so far I have not gotten this result.

BorntraegerMarc commented 6 years ago

@mlisook the new version fixed the issue. Thanks a lot!