如何在下载时在 NextJS 中呈现图像的模糊版本?

How to present a blurred version of an image in NextJS as it's being downloaded?

我正在寻找与下面这个类似的效果:

我已经用 Gatsby 做了类似的事情,但我想知道这是否可以用 NextJS 来做?

您应该使用 React 渐进式图像加载。

安装:

npm install react-progressive-image-loading --save

进口:

import ProgressiveImage from "react-progressive-image-loading";

使用:

<ProgressiveImage
    preview="/images/prevImage.png"
    src="/images/image.png"
    render={(src, style) => <img src={src} style={style} />}
/>

你也应该使用 background-image 和 div。

<ProgressiveImage
    preview="/images/prevImage.png"
    src="/images/iamge.png"
    render={(src, style) => <div style={Object.assign(style, { backgroundImage: `url(${src})` })} />}
/>

您应该自定义过渡时间。

<ProgressiveImage
    preview="/images/tiny-preview.png"
    src="/images/preview.png"
    transitionTime={500}
    transitionFunction="ease"
    render={(src, style) => <img src={src} style={style} />}
/>

不用外部库,代码不多也能做到。

https://codepen.io/darajava/pen/GRZzpbB?editors=0110

我在加载时也在其中添加了动画。图像将适合其父容器的宽度。用法很简单:

<LoadImage largeImageSrc={url} smallImageSrc={url} />

对于 10.2 以上的版本,Nextjs 在图像组件中提供了内置的模糊图像。 花了几个小时后,我发现了这个 article

首先您需要将您的nextJs应用更新到10.2.4或以上版本。

yarn add next@10.2.4

然后使用两个附加属性 blurDataURLplaceholder 实现您的 nextJs Image 组件。检查下面的代码示例。

<Image
   className="image-container"
   src="/images/high-quality-image.jpg"
   width={250}
   height={240}
   quality={75}
   blurDataURL="/images/path-to-blur-image.jpg"
   placeholder="blur"
/>

对于 Next.js v11,这是内部支持的:

import Image from 'next/image';
import someImg from 'path/to/some/image.png';

// ...

<Image src={someImg} placeholder="blur" />

参考文献:

此外,this issue 讨论了很多备选方案,如果您使用较低版本或尝试将其用于非静态图像,这些备选方案可能会有所帮助。


官方演示:https://image-component.nextjs.gallery/placeholder

The example can be animated if you want: ()

import Image from 'next/image';
import { useState } from 'react';

import ViewSource from '../components/view-source';
import mountains from '../public/mountains.jpg';

const PlaceholderBlur = () => {
  const [loaded, setLoaded] = useState(false);

  return (
    <>
      <ViewSource pathname="pages/placeholder.js" />
      <h1>Image Component With Placeholder Blur</h1>
      <Image
        alt="Mountains"
        src={mountains}
        placeholder="blur"
        width={700}
        height={475}
        className={loaded ? 'unblur' : ''}
        onLoadingComplete={() => setLoaded(true)}
      />
      <style jsx global>{`
        .unblur {
          animation: unblur 1s linear;
        }

        @keyframes unblur {
          from {
            filter: blur(20px);
          }
          to {
            filter: blur(0);
          }
        }
      `}</style>
    </>
  );
};

export default PlaceholderBlur;

结果:


这与其他选项相比如何?

  • 您可以继续使用很棒的 next/image 而不是未优化的 img 标签或未优化的第三方实现。

  • 无需添加额外的依赖项,即包大小不会受到太大影响。

  • 无需手动生成小图像以显示为预览。 Next.js 自动为您生成一个非常小的 (<10px) 图片。

import Image from 'next/image';
import imageUrlBuilder from '@sanity/image-url';

import sanity from '../../utils/sanity';

export function urlFor(source) {
  return imageUrlBuilder(sanity).image(source);
}

const SanityImage = ({ src, width, height, alt, ...props }) => (
  <Image
    src={urlFor(src).width(width).height(height).url()}
    width={width}
    height={height}
    layout="responsive"
    placeholder="blur"
    alt={alt || 'kickoff'}
    blurDataURL="/images/coverImage.png"
    {...props}
  />
);

export default SanityImage;