Travis

Travis

这里支持的小组件太少,写不下😂,欢迎查看我的个人 blog <blog.lxythan2lxy.cn>

nextjs に画像のぼかしプレースホルダーを追加する

本文永久リンク次の js で画像のぼかしプレースホルダーを追加する方法 | トラビスのブログ

本文の内容はHow to: Blurred images on load in Next.jsから取得しました。コードの変更は私のこのコミットで行われました。

紹介#

Next.js の Image コンポーネントは、blurDataURL パラメータをサポートしており、画像が完全に読み込まれる前にベース 64 の画像をプレースホルダーとして使用することができます。

画像の位置を Markdown 構文で制御し、画像のぼかし生成プロセスをサーバーのビルド時に行い、フロントエンドで画像を取得してから生成するのではなく、生成プロセスを画像コンポーネントに含めることはできません。そのため、mdx が tsx オブジェクトにレンダリングされる際に行う必要があります。このプロセスを制御するために、rehype プラグイン1を使用しました。

mdx ファイルは contentlayer によって管理され、まず remark を使用して mdx を html に変換し、その後 rehype を使用していくつかの後処理を行い、tsx に変換してレンダリングします。この一連のプロセスはnext buildの段階で完了し、要件を満たしています。

開始#

  1. 必要なパッケージをインストールします。plaiceholderは画像から対応するぼかしプレースホルダーを生成するパッケージで、直接ベース 64 形式で生成することができます。
pnpm i plaiceholder unist-util-visit
  1. 次に、対応する img タグを見つけ、対応する src ファイルを読み取り、plaiceholder を使用して対応するベース 64 文字列を生成し、img の blurDataURL 属性に配置し、その後、独自のコンポーネントでパラメータを処理します。
import { getPlaiceholder } from "plaiceholder";
import { visit } from "unist-util-visit";

// ノードが画像ノードであるかどうかを確認するだけの関数
function isImageNode(node) {
  const img = node;
  return (
    img.type === "element" &&
    img.tagName === "img" &&
    img.properties &&
    typeof img.properties.src === "string"
  );
}

// ぼかし画像に使用する指定された`src`のプロパティを返す
export async function returnProps(src) {
  const { base64: blurDataURL, img } = await getPlaiceholder(src);

  // 解像度の計算中にエラーが発生した場合はエラーをスローする
  if (!img) throw Error(`Invalid image with src "${src}"`);

  return {
    blurDataURL,
  };
}

async function addProps(node) {
  // 画像の新しいプロパティを返す
  const { blurDataURL } = await returnProps(node.properties.src);

  node.properties.blurDataURL = blurDataURL;
}

const imageMetadata = () => {
  return async function transformer(tree) {
    // マークダウンファイルからすべての画像を保持する配列を作成する
    const images = [];

    visit(tree, "element", (node) => {
      // ツリー内のすべてのノードを訪れ、画像であるかどうかをチェックし、画像をimages配列に追加する
      if (isImageNode(node)) {
        images.push(node);
      }
    });

    for (const image of images) {
      // すべての画像をループしてプロパティを追加する
      await addProps(image);
    }

    return tree;
  };
};

export default imageMetadata;
  1. img タグを処理し、img を Next.js のImageに変換します。
import Image from "next/image";

export default function MyImage({
  src,
  width,
  height,
  alt,
  blurDataURL,
}: any) {
  return (
    <div className="not-prose mx-2 mt-4 mb-0 break-inside-avoid-page">
      <div>
        <Image
          src={`${src}`}
          width={width}
          height={height}
          alt={alt}
          blurDataURL={blurDataURL}
          placeholder="blur"
        />
      </div>
    </div>
  );
}
  1. contentlayer の設定に作成した rehype プラグインを追加します。
import imageMetadata from "./lib/imageMetadata";

...

export default makeSource({
  contentDirPath: "data",
  documentTypes: [Blog, Movie, About, Idea],
  mdx: {
    rehypePlugins: [
      [rehypeImgSize, { dir: "public" }],
      rehypeCodeTitles,
      imageMetadata,
      [rehypePrism, { showLineNumbers: true }],
      rehypeKatex,
      rehypeSlug,
    ],
  },
});

以上です。

Footnotes#

  1. Github rehypejs/rehype

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。