Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a fade-in animation for Nextjs/Image when it loads?

I'm using next/image, which works great, except the actual image loading in is super jarring and there's no animation or fade in. Is there a way to accomplish this? I've tried a ton of things and none of them work.

Here's my code:

<Image
  src={source}
  alt=""
  layout="responsive"
  width={750}
  height={height}
  className="bg-gray-400"
  loading="eager"
/>

According to the docs I can use the className prop, but those are loaded immediately and I can't figure out any way to apply a class after it's loaded.

I also tried onLoad, and according to this ticket, it isn't supported: https://github.com/vercel/next.js/issues/20368

like image 986
Citizen Avatar asked Jan 03 '21 03:01

Citizen


Video Answer


2 Answers

NextJS now supports placeholder. You can fill the blurDataURL property with the base64 string of the image which you can easily get using the lib plaiceholder on getServerSideProps or getStaticProps. Then to make the transition smoothly you can add transition: 0.3s;

Quick sample:

export const UserInfo: React.FC<TUserInfo> = ({ profile }) => {
  return (
    <div className="w-24 h-24 rounded-full overflow-hidden">
      <Image
        src={profile.image}
        placeholder="blur"
        blurDataURL={profile.blurDataURL}
        width="100%"
        height="100%"
      />
    </div>
  );
};

export async function getServerSideProps(props: any) {
  const { username } = props.query;

  const userProfileByName = `${BASE_URL}/account/user_profile_by_user_name?user_name=${username}`;
  const profileResponse = await (await fetch(userProfileByName)).json();
  const profile = profileResponse?.result?.data[0];

  const { base64 } = await getPlaiceholder(profile.profile_image);

  return {
    props: {
      profile: {
        ...profile,
        blurDataURL: base64,
      },
    },
  };
}

index.css

img {
  transition: 0.3s;
}
like image 120
Gabriel Linassi Avatar answered Sep 18 '22 14:09

Gabriel Linassi


You could try use next-placeholder to achieve this sort of effect

like image 34
oldo.nicho Avatar answered Sep 19 '22 14:09

oldo.nicho