[英]How can I add a fade-in animation for Nextjs/Image when it loads?
我正在使用next/image
,效果很好,除了实际加载的图像非常刺耳,并且没有 animation 或淡入。有没有办法做到这一点? 我已经尝试了很多东西,但它们都不起作用。
这是我的代码:
<Image
src={source}
alt=""
layout="responsive"
width={750}
height={height}
className="bg-gray-400"
loading="eager"
/>
根据文档,我可以使用className
道具,但是这些道具会立即加载,并且在加载 class 后,我想不出任何方法来应用它。
我也试过onLoad
,根据这张票,它不受支持: https://github.com/vercel/next.js/issues/20368
您可以尝试使用下一个占位符来实现这种效果
因此,我想实现相同的目标并尝试使用 onLoad 事件。 nextJs 的 Image 组件接受这个作为道具,所以这是我的结果:
const animationVariants = {
visible: { opacity: 1 },
hidden: { opacity: 0 },
}
const FadeInImage = props => {
const [loaded, setLoaded] = useState(false);
const animationControls = useAnimation();
useEffect(
() => {
if(loaded){
animationControls.start("visible");
}
},
[loaded]
);
return(
<motion.div
initial={"hidden"}
animate={animationControls}
variants={animationVariants}
transition={{ ease: "easeOut", duration: 1 }}
>
<Image
{...p}
onLoad={() => setLoaded(true)}
/>
</motion.div>
);
}
但是,图像并不总是淡入,如果图像尚未缓存,onLoad 事件似乎被触发得太早了。 我怀疑这是一个将在未来的 nextJS 版本中修复的错误。 如果其他人找到解决方案,请让我更新!
然而,上面的解决方案经常工作,并且由于每次都会触发 onLoad,它不会破坏任何东西。
编辑:此解决方案对 animation 使用成帧器运动。 这也可以被任何其他 animation 库或本机 CSS 转换替换
NextJS 现在支持占位符。 您可以使用图像的 base64 字符串填充 blurDataURL 属性,您可以使用 getServerSideProps 或 getStaticProps 上的 lib plaiceholder轻松获取该字符串。 然后为了使过渡平滑,您可以添加transition: 0.3s;
快速示例:
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,
},
},
};
}
索引.css
img {
transition: 0.3s;
}
是的,它可以捕获实际图像加载的事件。 我在 Reddit 上找到了对此的答案,并想将其转发给像我这样正在寻找答案的人。
“要让 onLoad 在 NextJS 图像组件中工作,您需要确保目标不是他们用作占位符的 1x1 像素。
const [imageIsLoaded, setImageIsLoaded] = useState(false) <Image width={100} height={100} src={'some/src.jpg'} onLoad={event => { const target = event.target; // next/image use an 1x1 px git as placeholder. We only want the onLoad event on the actual image if (target.src.indexOf('data:image/gif;base64') < 0) { setImageIsLoaded(true) } }} />
从那里你可以使用 imageIsLoaded boolean 来做一些像 Framer Motion 库这样的淡入淡出。
来源: https://www.reddit.com/r/nextjs/comments/lwx0j0/fade_in_when_loading_nextimage/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.