LoginSignup
7
2

【Next.js】Imageコンポーネントのplaceholder="blur"ではブラーのアニメーションできない!どうする?

Posted at

こんにちは!最近Next.jsとReactをいそいそ勉強しています、加能です。

この記事の背景

📕作って学ぶ Next.js/React Webサイト構築(2022年7月発売)を実践している時のこと。

このような、画像ロード後にふんわり画像が表示するアニメーションさせるには、

Next.jsの <Image>placeholder="blur"を使って、下記CSSを当てよう とありました。

span > img {
    transition: 0.2s;
}

しかし現在の最新バージョンのNext.jsでは、<Image>spanタグは入らなくなり、
この方法ではアニメーションさせることができなくなりました。

となると、

「今<Image>を使って、画像ロード後にふんわり表示するにはどうしたらいいの?」
と疑問に思ったので、調査結果をまとめました。

前提

環境 Next.js ルーティング React(一応)
書籍 v12.2.0 Pages Router v18.2.0
v14.2.3 App Router v18.3.1

結論 :pen_ballpoint:

  • <Image>placeholder="blur"を使ってブラーのアニメーションさせることはできない
  • 代わりに placeholder=blurを使わず、ブラーをCSSでやる と良い

なぜplaceholder="blur"ではできないのか :thinking:

<Image>placeholder="blur"を使用すると、
ローカル画像ではblurDataUrlというブラー画像が生成されます。

ちなみに外部から持ってくる画像はblurDataUrlを別途指定する必要があります。

画像ローディング中はそれを使って
background-image: url({blurDataUrl})がstyleとしてimgタグに付与されます。

なので、このように読み込み中はブラーになります。

image.gif

background-imageは徐々に変更させられない

ですが、このCSSのbackground-imageはCSSアニメーションで徐々に変更することはができません。

background-imageのMDNでは、background-imageの公式定義では「アニメーションの種類:離散値」となっています。

アニメーションの種類の「離散」は、下記を見るとわかります。

離散
プロパティの値は加算されず、補間は 50% で開始値から終了値に入れ替わります。

つまり、50%のタイミングでぱつっと切り替わるため、徐々に変わるようなアニメーションはできません。

じゃあ<Image>を使ってブラーのアニメーションさせるには? :point_up:

<Image>を使ってふんわりブラーのアニメーションをさせるには、
そもそも placeholder="blur"を使わずにブラーの段階からCSSでやるとうまくいきます。

この方のやり方のように、
useStateを使い、画像ロード完了時にClassNameを切り替えることで実現可能です。
(参考にさせていただきました :pray:

// component

import { useState } from 'react';
import Image from 'next/image';
import styles from './ImageComponent.module.css';

export const ImageComponent = () => {
  const [isImageLoaded, setIsImageLoaded] = useState(false);

  return (
    <>
      <Image
        src="/path/to/image.jpg"
        alt="image alt"
        width={400}
        height={400}
        className={`${isImageLoaded ? styles.removeBlur : styles.blur}`}
        onLoad={() => setIsImageLoaded(true)}
      />
    </>
  );
};
/* css */

.blur {
  filter: blur(8px);
  transition: filter 0.5s ease-in;
}

.removeBlur {
  filter: blur(0);
  transition: filter 0.5s ease-in;
}

まとめ

Next.jsの<Image>でふんわりブラーのアニメーションをさせるには、
画像をブラーさせるところから、CSSを使うと良いです。

ちなみに古いバージョンの場合、
span > imgのCSSでいけるのかはまだ試せてないので、そのうち試してみます。

📕作って学ぶ Next.js/React Webサイト構築はとてもわかりやすくて楽しいです😀

もし間違いがあればコメントでご指摘ください。
お読みいただきありがとうございました。

参考にしたページ

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2