Gatsby上のMDX記事で画像のスライドショーを表示するための手順メモです。 gatsby-plugin-image と react-responsive-carousel を使って実現してます。
昨日の記事で紹介した手順で作成した資産 に対して追加設定を行います。
1.ゴール
以下のような MDX ファイルでスライドショー表示ができるようにします。
---
slug: "test2"
title: "テスト"
images:
- ./image-01.jpg
- ./image-02.jpg
- ./image-03.jpg
---
テストだよ
import SlideShow from '../../components/SlideShow'
<SlideShow images={props.frontmatter.images} interval={1000} autoPlay={true} infiniteLoop={false} />
- frontmatter (MDXファイルの
---
より上の部分) の images でスライドショー表示する画像を指定できる - SlideShow コンポーネントでスライドショー表示ができる
- SlideShow コンポーネントは以下の属性を指定可能にする
- images: スライドショー表示する画像ファイル
- interval: スライドを送るタイミング
- autoPlay: 自動的にスライドを送るかどうか
- infiniteLoop: 無限ループするかどうか
2.プラグインの組み込み
gatsby-plugin-image とその必須コンポーネントおよび react-responsive-carousel をインストールします。
npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp react-responsive-carousel
gatsby-config.js に gatsby-plugin-image, gatsby-plugin-sharp, gatsby-transformer-sharp のプラグイン設定を行います。
module.exports = {
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
(その他のプラグイン設定)
],
}
3.gatsby-node.js の修正
MDXファイルの frontmatter に記述した images
のファイル情報を受け取れるように gatsby-node.js を設定します。
(省略)
const result = await graphql(`
{
allMdx {
edges {
node {
frontmatter {
title
slug
images {
childImageSharp {
gatsbyImageData
}
}
}
}
}
}
}
`)
(省略)
4.src/templates/blog-post.jsの修正
src/templates/blog-post.js
のクエリ―でも images
のファイル情報を受け取れるように修正します。
(省略)
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
mdx(frontmatter: { slug: { eq: $slug } }) {
body
frontmatter {
title
slug
images {
childImageSharp {
gatsbyImageData(
width: 300
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
)
}
}
}
}
}
`
- ここでは gatsbyImageDataのパラメタとして以下を指定しています。
- width: 指定された幅の画像に変換する。ここでは300pxを指定。
- placeholder: 実際の画像が読み込まれる前に表示される画像。ここではぼかし画像を指定。
- formats: 生成する画像のタイプ。ここでは元画像のフォーマット(jpg / png), WebP, AVIF を指定。
- gatsbyImageDataのその他のパラメタに関しては、gatsby-plugin-imageのリファレンス を参照。
- gatsby-plugin-image を使うと gatsbyImageData で指定したパラメタに従って画像生成が行われ、以下のような picture タグを用いたHTMLに変換されます。このおかげで、より効率的な (サイズの小さい) 画像が自動的に選択されるようになります。
<picture> <source type="image/avif" srcset="/static/.../abc.avif 75w, ..."> <source type="image/webp" srcset="/static/.../abc.webp 75w, ..."> <img src="/static/.../abc.jpg" srcset="/static/.../abc.jpg 75w"> </picture>
5.SlideShowコンポーネントの作成
src/components/SlideShow.js
ファイルを作成します。
import React from 'react'
import { GatsbyImage, getImage } from 'gatsby-plugin-image'
import 'react-responsive-carousel/lib/styles/carousel.min.css'
import { Carousel } from 'react-responsive-carousel'
const SlideShow = ({images, interval, autoPlay, infiniteLoop}) => {
return (
<div style={{width:'300px'}}>
<Carousel showThumbs={false} infiniteLoop={infiniteLoop} autoPlay={autoPlay} interval={interval}>
{images.map(i => ( <div><GatsbyImage image={getImage(i)} /></div>))}
</Carousel>
</div>
);
}
export default SlideShow
- 「react-responsive-carousel の Carousel コンポーネントの中に gatsby-plugin-image の GatsbyImage コンポーネントを並べる」というイメージの構成です。
- GatsbyImage コンポーネントは、gatsby-plugin-image の説明においてはDynamic imagesとされているものに該当します。
- Carouselの属性指定については react-responsive-carouselの説明 を参照ください。
6.SlideShowを利用する記事と画像を配置する
src/posts フォルダの下に一つフォルダを作ってその下に index.mdx
という名前でファイルを作ります。
(例: src/posts/2021-04-18-test2/index.mdx
)
---
slug: "test2"
title: "テスト"
images:
- ./image-01.jpg
- ./image-02.jpg
- ./image-03.jpg
---
テストだよ
import SlideShow from '../../components/SlideShow'
<SlideShow images={props.frontmatter.images} interval={1000} autoPlay={true} infiniteLoop={false} />
さらに、index.mdx と同じフォルダに images で指定した画像(この例では image-01.jpg, image-02.jpg, image-03.jpg)を格納します。
※画像ファイルがないと gatsby develop
や gatsby build
を実行した際にエラーになるため、必ず事前に画像を格納しておく必要があります。
動作確認
gatsby develop
で動作確認できます。
実際の動作イメージはこちらの記事でも確認できます。
コードこちら: