next/imageでのFade-inアニメーション

imatomix
2021年11月1日 0:51

概要

面倒なことをやってくれる next/image は便利ですが、読み込み完了次第、画像がパッと表示されるため、少し不格好です。せめてフェードインさせましょう。

完成形

next/image の処理が終わったら、スタイルを切り替えるだけ。

<iframe src="https://codesandbox.io/embed/next-image-fade-in-swzr9?fontsize=14&hidenavigation=1&theme=dark" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="next/image fade-in" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>

スクリプト

Image.tsx
import Image, { ImageProps } from 'next/image' import styles from './Image.module.scss' export const NextImage: React.FC<ImageProps> = (props: ImageProps) => { const onLoad = (e) => { if (e.target.srcset) { e.target.dataset.load = 'done' } } return ( <Image className={styles.image} onLoad={onLoad} {...props} /> ) } export default NextImage

image.module.scss
.image { opacity: 0; transition: opacity 0.5s ease; &[data-load='done'] { opacity: 1; } }

要点

  • onLoadでスタイル変えれば行けると思ったらそうでもなかった。
  • 遷移時はうまくいくが、リロードなどの初回表示時にはうまくいかなかった。
  • 初回時はonLoadが2回実行されてた。この時は1回目でdatasetを追加するのは速すぎるらしい。
  • srcsetの存在確認してdatasetを追加したらうまくいった。
  • 1回目のonLoadを回避できた。