cyrilwanner / react-optimized-image

Easy to use React components for optimized-images-loader / next-optimized-images.
MIT License
62 stars 8 forks source link

lqip support #5

Open tilman opened 4 years ago

tilman commented 4 years ago

In https://github.com/cyrilwanner/next-optimized-images/issues/120 you mentioned that this Img Component should also support an lqip placeholder. Is there any progress on this? Would love to try it out! :)

cyrilwanner commented 4 years ago

It is one of the features I'll be working on over the next weeks, but it isn't in canary yet. I'll notify you once it can get tested.

allan2 commented 4 years ago

Are there any plans for trace too?

I think an <ImgLoader> component for the placeholders would be cool. I could see that getting a lot of use.

Like this, but with same props as v3 <Img> like webp and resize.

/** Placeholder component for next-optimized-images v2 using image-trace-loader
    Credit given to https://github.com/EmilTholin/image-trace-loader **/

const ImgLoader = ({ traceObject, alt }: Props) => {
  const [imageLoaded, setImageLoaded] = useState(false);

  return (
    <div css={animation}>
      <img
        css={[animation, { position: 'absolute', opacity: imageLoaded ? 1 : 0 }]}
        src={traceObject.src}
        alt={alt}
        loading="lazy"
        onLoad={() => setImageLoaded(true)}
      />

      <img css={{ opacity: imageLoaded ? 0 : 1 }} src={traceObject.trace} alt={alt} />
    </div>
  );
};

WebP + resize + your choice of placeholder is a potent combo indeed!

cyrilwanner commented 4 years ago

Are there any plans for trace too?

Yes, I plan to provide a component for all lazy loading techniques, like <BlurUp>, <Trace>, etc. The API will probably be like this so you can use all normal properties of the <Img> tag and use resizing or webp conversion as you like:

<BlurUp>
    <Img src={image} webp sizes={[500, 1000]} />
</BlurUp>
tilman commented 4 years ago

I already created a Placeholder component on my own in the meantime. Feel free to reuse anything you want from this component for this project: https://github.com/tilman/react-intersection-placeholder Also if you need help I'm glad to help :)

It uses an Intersection Observer to only display the child if it is near the viewport.

import Img from 'react-optimized-image';
import TestImg from 'test.png';
import TestImgLqip from 'test.png?lqip';
...
<IntersectionPlaceholder
    src={TestImg} // original image needed for having the right dimensions
    lqip={TestImgLqip} // pass your placeholder image here
    observerOptions={{ threshold: 0.5 }} // you can also pass options for the intersection observer. Use the same config object as you would use to init the intersection observer.
>
    <Img src={TestImg} />
</IntersectionPlaceholder>