始める
レスポンシブデザイン
Reactでレスポンシブ画像ギャラリーを構築する方法

Reactでレスポンシブ画像ギャラリーを構築する方法

フロントエンド開発者であれば、画像ギャラリーが必要なアプリやウェブサイトに取り組むことが多いでしょう。写真共有アプリケーションからメッセンジャーやメモアプリ、検索エンジンまで、画像ギャラリーは複数の画像のプレビューをウェブページに表示し、ユーザーがそれらの画像と対話できるようにする最適な方法です。

シンプルな画像ギャラリーを構築するのは簡単かもしれませんが、デスクトップからスマートフォンまでのすべての画面サイズに合わせて画像をリサイズするのは簡単ではありません。画像帯域幅を最適化し、ページの読み込み時間を短縮する必要がある場合、タスクはさらに困難になります。すべての制約を満たしながら、何百枚または何千枚もの画像を含むギャラリーをスケーリングするのはさらに挑戦的です。

この記事で使用する画像ギャラリーの例

すべての画面サイズに合わせて複数の画像を作成する必要がない方法で、迅速にレスポンシブ画像ギャラリーを構築する方法があればどうでしょうか?

それがimgixを構築する際に念頭に置いていたユースケースの一つです。imgixサービスがエンドユーザーと画像が保存されている場所(例:S3バケット)との間に位置することで、オリジナル画像を動的に処理し、リサイズ、フィルタリング、フォーマットの変更、最終的に結果をキャッシュすることができます。imgixとの統合をさらに便利にするために、多くのクライアントライブラリとCMSプラグインを提供しています。

この記事では、特にReact開発者に役立つreact-imgix (opens in a new tab)ライブラリに焦点を当てます。なぜでしょうか?それは、HTML画像のsrcset属性を利用して、ブラウザが現在のウィンドウサイズに最適な画像を選択する柔軟性を提供するからです。react-imgixは自動的に強力なsrcsetを構築するため、レスポンシブ画像の作成に頭を悩ませる時間を節約できます。

imgixは画像を異なるサイズでオンザフライで提供できるため、srcsetと非常に相性が良いです。ブラウザによって選択された画像の派生版は、imgixサービスによって要求され、取得され、キャッシュされます。これにより、各画像の異なるバージョンを手動でリサイズ/保存する必要がなくなります。さらに、react-imgixが価値を提供する理由の一つは、srcsetが画像サイズ/品質を最大化しながら帯域幅コストを最小化するように構築されていることです。

imgixの実際の動作

プラットフォームについてのコンテキストが得られたところで、React画像ギャラリーを構築するための具体的な手順に進みましょう。プロジェクトのコードをフォローできるように、CodeSandbox (opens in a new tab)のコードを用意しました。このセクションでは、以下の手順をカバーします:

  • すべての依存関係を含むpackage.json構成ファイルの作成
  • シンプルなHTMLおよびCSSファイルの実装
  • Reactロジックとimgixの魔法を含むいくつかのJavaScriptファイルのセットアップ

package.jsonファイルの作成

一般的なセットアップはReactに慣れていれば非常に簡単です。このJavaScriptプロジェクトには、package.jsonが必要です。ボイラープレートコードには、以下の依存関係が含まれています:

"dependencies": {
  "@types/node": "^12.7.8",
  "prop-types": ">=15.5.6",
  "react": "^16.12.0",
  "react-dom": "^16.12.0",
  "react-imgix": "^9.0.1",
  "typescript": "^3.6.3"
}

もちろん、通常のReactライブラリが必要ですが、react-imgixライブラリも含まれていることに気付くでしょう。react-imgixは、imgixを使用してシンプルなフォトギャラリーを作成するためのツールを提供しているため、これを必ずインストールしてください。

HTMLおよびCSSファイル

このシンプルなimgixデモの目的のために、これらのファイルのボイラープレートは非常にシンプルです。HTMLファイルには、ルートJavaScriptファイルへの接続として機能するidを持つdivがあります:

<div id="root"></div>

それだけです!

CSSファイルにはもう少し内容がありますが、主にReactコンポーネントで使用するクラスのスタイリングが含まれていますが、コードは依然としてシンプルなままです。たとえば、ギャラリーコンポーネントで使用されるギャラリークラスのCSSは次のようになります:

.gallery {
  display: grid;
  overflow: hidden;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}

ギャラリーがグリッド要素として表示されるようにしたいので、display: gridプロパティがこれを実現するのに役立ちます。グリッドレイアウトでは、画像がギャラリー内のタイルよりも大きなサイズを持つ場合があり、画像が互いに重ならないようにするためにoverflow: hiddenプロパティを追加します。

最後の2つのプロパティは各ギャラリー項目のサイズを指定します。repeat(auto-fill…)部分は、グリッド内のすべての列が同じサイズで、最小20em単位、最大はグリッドの列のサイズになることを示しています。これらのCSSオプションが内部でどのように機能するかについて興味がある場合は、このCSSグリッドにおける自動サイズ調整列 (opens in a new tab)の記事で詳しく学ぶことができます。

JavaScriptロジック

いよいよプロジェクトの核心部分に入ります!index.jsファイルでは、子コンポーネントをインポートし(他のインポートも含む)、Appコンポーネントを作成します。

class App extends Component {
  constructor() {
    super()
    this.state = {
      name: "React",
    }
  }
 
  render() {
    return (
      <div>
        <HeroImage />
        <Gallery />
      </div>
    )
  }
}

Appコンポーネントは、2つの子コンポーネントを順番にレンダリングします。このメインコンポーネントをファイルの最後の行でレンダリングし、HTMLファイルに接続します:

render(<App />, document.getElementById("root"))

このindex.jsではimgixを使用していないことに気付くでしょう。それは、両方の子コンポーネントで使用するためです。まず、ギャラリーコンポーネントを見てみましょう。ライブラリをインポートした後、すべての画像のファイル名を含む文字列の配列を作成します:

const images = [
  "forest1",
  "forest2",
  "forest3",
  "mountain1",
  "mountain2",
  "mountain3",
  "river1",
  "river2",
  "river3",
]
 
const buildURL = (imagePath) =>
  `https://assets.imgix.net/tutorials/${imagePath}.webp`

これらが設定されたので、ギャラリーを構築します:

export const Gallery = () => (
  <div className="gallery">
    {images.map((image) => (
      <Imgix
        sizes="(min-width: 960px) 33vw, (min-width: 640px) 50vw, 100vw"
        src={buildURL(image)}
        imgixParams={{
          fit: "crop",
          fm: "jpg",
        }}
        width={600}
        height={600}
      />
    ))}
  </div>
)

このコードは、定義済みの配列内の各画像をreact-imgixライブラリの<Imgix/>要素にマップするGalleryコンポーネントを作成しています。この要素はsrcsetsizesを使用しており、ユーザーが指定した寸法を使用してブラウザが適切に画像をレンダリングできるようにします。

ギャラリーは多くの柔軟性を提供しており、他の要素(<img><picture>など)を活用し、クリエイティブな方向性を広げることができます。

次に、2番目の子コンポーネントを見てみましょう。HeroImage.jsでは、背景に画像をレンダリングするコンポーネントがあります:

export const HeroImage = () => (
  <Background
    src="https://assets.imgix.net/tutorials/forest4.webp"
    className="hero-image"
  >
    <h2>imgix demo</h2>
  </Background>
)

このコンポーネントは他にシンプルで、スタイルとヘッダーが含まれているだけなので、背景モードについて少し説明します。コンポーネントはDOM内のコンテナの自然サイズを測定し、その寸法に最適な画像をレンダリングします。

コンポーネントの再レンダリングを避けるために、幅と高さを手動で設定し、プロップとして渡すことで一度のパスで背景画像をレンダリングできます。

これですべてです!これらの2つの子コンポーネントは、imgixのさまざまな側面を使用し、imgixのサービスの簡単さと柔軟性を示しています。

結果

完成したプロジェクトがどのように見えるか見てみましょう。CodeSandboxでプロジェクトのライブ例を見る (opens in a new tab)ことができ、編集用のサンドボックスを作成できます。

また、CodeSandboxでファイル→ZIPにエクスポートをクリックして、プロジェクトファイルのコピーをダウンロードすることもできます。ファイルをダウンロードしたら、プロジェクトディレクトリでyarnを実行してすべての依存関係をインストールします。次に、yarn run startコマンドを使用して開発サーバーを起動し、プロジェクトをブラウザで開きます。

プロジェクトが読み込まれると、レスポンシブヒーロー画像とレスポンシブ画像ギャラリーが表示されます。

ヒーロー画像は、ブラウザウィンドウのサイズに応じてその寸法を変更します。ウィンドウサイズを変更して、ヒーロー画像がどのように適応するかを確認してください:

ウィンドウサイズの変更に応じてヒーロー画像が変化します。それぞれのサイズでimgixは背景画像を適切な寸法でロードします。

画像ギャラリーもブラウザウィンドウのサイズに応じて外観が変わります。ギャラリーセクションまでスクロールし、異なるウィンドウサイズで実験してみてください:

imgixのレスポンシブ画像ギャラリーは、画面サイズに応じて1行に1〜4枚の画像を含みます。

まとめ

imgixを使用して画像ギャラリーを作成することはシンプルで信頼性があり、動的です。多くの画像を扱い、それらの画像がすべてのデバイスとブラウザに適したフォーマットとサイズで提供されることを望む人にとって、理想的なソリューションです。

その他のリソース