マンガでわかる!画像データでページを切り替えるマンガビューアを試してみる ― 横向き4ページ版とスマホ縦読み版

プログラミング・Web開発

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。papanda925 Character Sheet v1 をキャラクターの正本として統一した4枚のマンガ画像を使い、JSONから1ページずつ切り替える「横向きページ切り替え版」と、同じ画像を上から順に並べる「スマホ縦読み版」を Daily-Code-Samples に実装して、表示方式の違いを比べています。

検証ステータス:🧪 GitHub実装済み・JavaScript/JSON/公開安全性チェック成功・GitHub Pages build完了・スマホ実機表示は未確認

マンガをWebで見せるなら、1枚の長い画像をそのまま縦に置くのが一番簡単です。

でも今回は、あえてもう一歩だけ進めます。

「前へ」「次へ」で1ページずつ切り替える横向きビューアと、スマホでそのまま下へスクロールして読む縦読みビューアを、同じ4枚の画像データから作ってみました。

専用のマンガライブラリは使いません。

必要なのは、HTML、CSS、JavaScript、JSON、そしてマンガ画像だけです。

まず試してみる

今回のサンプルは GitHub Pages で公開しています。

横向き版では「次のページ」を押すと、1 / 42 / 43 / 44 / 4 と表示が切り替わります。

画像だけではありません。タイトル、説明、タグも、そのページのデータとして一緒に切り替わります。

縦読み版では同じ4枚を上から順に並べます。「次へ」ボタンは使わず、スマホではそのまま下へスクロールして読みます。

今回使っている4枚のマンガ画像

現在は papanda925 Character Sheet v1 を基準にしたPapanda へ統一しています。

1 / 4 — ブラウザでページを切り替える

1ページ目:ブラウザでページを切り替えるマンガビューア

2 / 4 — 画像と付帯データを分けて持つ

2ページ目:画像と付帯データを分けて持つ

3 / 4 — 前へ・次へでページを切り替える

3ページ目:前へ次へでページを切り替える

4 / 4 — GitHub Pagesで公開する

4ページ目:GitHub Pagesで公開してブラウザで見る

スマホ縦読み版の説明用画像も用意しました。

スマホで縦に読むPapanda Manga Viewer

Papandaの正本は Character Sheet v1

今回から、Papandaの見た目を記事ごとにその場で決めるのではなく、Character Sheet v1 を正本として扱うことにしました。

基準にしているのは、たとえば次のような特徴です。

  • 顔は真円ではなく、少し横長でやわらかい輪郭

  • 顔とおなかはクリーム寄りの白

  • 耳・目の周り・手足は真っ黒ではなく濃いブラウン

  • 大きめでツヤのある目

  • 薄いピンクのほっぺ

  • 小さな口

  • 2〜3頭身程度の、かわいらしいアニメ・ちびキャラ調

  • 「考える」「驚く」「説明する・うれしい」を基本表情にする

この基準を文章でも再利用できるよう、GitHubに CHARACTER_SOURCE.md を置きました。

今後マンガ画像を増やすときも、ここを参照元にすることで、記事ごとに別のパンダのようになるブレを減らせます。

全体像

今回のポイントは、マンガ画像そのものと、どう見せるかを分けたことです。

flowchart TD
    A[4枚のSVG画像] --> B[manga.json / manga-vertical.json]
    B --> C{表示方法}
    C --> D[横向き版]
    C --> E[スマホ縦読み版]
    D --> F[currentIndexで1枚を選ぶ]
    F --> G[前へ / 次へで差し替える]
    E --> H[全ページを順番にDOMへ追加]
    H --> I[下へスクロールして読む]

同じ画像を使っていても、JavaScript側の表示方法を変えれば読み方を変えられます。

これが今回の実験で一番面白かったところです。

横向き版のファイル構成

docs/demos/papanda-manga-viewer/
├── index.html
├── style.css
├── app.js
├── manga.json
└── pages/
    ├── page-01.svg
    ├── page-02.svg
    ├── page-03.svg
    └── page-04.svg

HTMLを4ページ分作っているわけではありません。HTMLは1画面だけです。

その中にある <img> の参照先を JavaScript で差し替えています。

画像と付帯データはJSONで持つ

manga.json では、画像パスだけでなく、そのページに付随する情報も一緒に持たせています。

{
  "image": "./pages/page-02.svg",
  "alt": "2ページ目。Papandaが画像と付帯データを分けて管理する考え方を紹介するイラスト",
  "title": "2ページ目:画像と付帯データを分けて持つ",
  "caption": "画像パスだけでなく、タイトル・説明・タグもJSONから取得します。",
  "tags": ["JSON", "メタデータ", "付帯データ"]
}

ページ切り替えだけなら、JavaScriptへ画像名を4つ直接書いても動きます。

それでもJSONを分けたのは、画像と表示用の情報を1ページ分のデータとして扱いたかったからです。

JSONを fetch() で読む

ページ情報は fetch() で読み込みます。

fetch('./manga.json')
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    return response.json();
  })
  .then((data) => {
    if (!Array.isArray(data.pages) || data.pages.length === 0) {
      throw new Error('pages が空、または配列ではありません');
    }

    pages = data.pages;
    renderPage();
  })
  .catch((error) => {
    status.textContent =
      `マンガデータを読み込めませんでした: ${error.message}`;
  });

response.ok を確認し、さらに pages が配列として存在するかもチェックしています。

currentIndex で「今のページ」を持つ

横向き版の中心はこれです。

let pages = [];
let currentIndex = 0;

配列は0から始まるため、4ページならこう対応します。

currentIndex = 0 → 1ページ目
currentIndex = 1 → 2ページ目
currentIndex = 2 → 3ページ目
currentIndex = 3 → 4ページ目

画面では、

`${currentIndex + 1} / ${pages.length}`

として、人間が読みやすい 1 / 4 に変えています。

renderPage() で画像と付帯データをまとめて変える

function renderPage() {
  const page = pages[currentIndex];
  if (!page) return;

  image.src = page.image;
  image.alt = page.alt ?? '';
  counter.textContent = `${currentIndex + 1} / ${pages.length}`;
  title.textContent = page.title ?? '';
  caption.textContent = page.caption ?? '';
}

中心になるのは次の1行です。

image.src = page.image;

同じ <img> 要素の src を変えるだけで、別のマンガ画像へ切り替えられます。

「前へ」「次へ」は同じ関数を使う

function movePage(step) {
  const nextIndex = currentIndex + step;

  if (nextIndex < 0 || nextIndex >= pages.length) {
    return;
  }

  currentIndex = nextIndex;
  renderPage();
}

次へなら movePage(1)、前へなら movePage(-1) です。

画面の端では、範囲外へ進まないようボタンも無効にします。

prevButton.disabled = currentIndex === 0;
nextButton.disabled = currentIndex === pages.length - 1;

PCでは左右キーでも読める

document.addEventListener('keydown', (event) => {
  if (event.key === 'ArrowLeft') movePage(-1);
  if (event.key === 'ArrowRight') movePage(1);
});

ボタン用とは別の移動処理を作らず、同じ movePage() を再利用しています。

スマホ縦読み版は何が違う?

縦読み版でもマンガ画像は同じです。

違うのは、JavaScript側で1枚だけ選ばず、全部を順番に画面へ追加することです。

docs/demos/papanda-manga-viewer-vertical/
├── index.html
├── style.css
├── app.js
├── manga-vertical.json
└── vertical-sample.svg

実際の4ページ画像は複製せず、横向き版の pages/ を参照しています。

同じ4枚のSVG
     ├─ 横向き版 → 1枚ずつ切り替える
     └─ 縦読み版 → 4枚を上から順に並べる

縦読み版は forEach() で全ページを作る

const fragment = document.createDocumentFragment();

data.pages.forEach((page, index) => {
  fragment.append(
    createPage(page, index, data.pages.length)
  );
});

root.replaceChildren(fragment);

横向き版は currentIndex で今の1ページだけを表示し、縦読み版は forEach() ですべてのページを順番に表示します。

同じページデータでも、表示ロジックを変えるだけで別の読み方になることが分かります。

縦読みでは遅延読み込みも使う

image.loading = index === 0 ? 'eager' : 'lazy';
image.decoding = 'async';

1ページ目はすぐ読み込み、2ページ目以降はブラウザの遅延読み込みを使います。

今回の4ページ程度では差は小さいですが、ページ数を増やしたときに効いてくる考え方です。

横向き版と縦読み版を比べる

項目横向きページ切り替え版スマホ縦読み版
読み方前へ / 次へ下へスクロール
中心ロジックcurrentIndexforEach()
同時表示原則1ページ全ページ
PC見やすい閲覧可能
スマホ閲覧可能特に読みやすい
画像データ4枚を参照同じ4枚を再利用
付帯データJSONJSON

コンテンツと表示方法を分けておけば、同じマンガ画像から別のUIを作れます。

GitHubでコードと画像を全部見る

READMEからライブデモだけでなく、実装ファイルとサンプル画像へ直接たどれるようにしています。

横向き版

スマホ縦読み版

GitHub Pagesで公開する

今回のビューアは、HTML、CSS、JavaScript、JSON、SVGだけで構成されています。PHPやPythonなどのサーバー側プログラムは不要です。

Daily-Code-Samples は main ブランチの /docs を公開元にしています。今回の更新後、GitHub Pages側の状態が built になっていることを確認しました。

ただし、ここで確認しているのはGitHub Pagesのビルド状態です。スマートフォン実機でのレイアウト・操作感は、この記事の公開時点ではまだ追加確認対象としています。

今回あえて入れなかった機能

今回は「画像をどう見せ分けるか」に集中するため、スワイプ操作、ページめくりアニメーション、URLへの現在ページ保存、拡大表示、全画面表示、吹き出し位置の外部データ化、AIによるマンガ自動生成パイプライン、WordPress専用埋め込みなどはまだ入れていません。

まずは、

画像 + JSON
     ↓
横なら1枚ずつ切り替える
縦なら全部並べる

という最小構成を動かすところまでにしました。

まとめ

Papanda Manga Viewer v0.1 では、専用のマンガライブラリを使っていません。

横向き版の中心は currentIndeximage.src = page.image;。縦読み版では同じ4枚を forEach() で上から順に追加しています。

さらに、画像だけでなくタイトル・説明・タグをJSONへ分けておくことで、同じコンテンツを別のUIから再利用できるようになります。

そして今回から、Papanda自体も Character Sheet v1 を正本にしました。

同じキャラクター、同じ画像データ、違う表示方法。

マンガを題材にすると、JSON、配列、DOM操作、レスポンシブ表示といったWebの基本が、かなり目で見て分かりやすくなります。

参考リンク


最終更新: 2026年9月10日

文書情報

記事タイトル
マンガでわかる!画像データでページを切り替えるマンガビューアを試してみる ― 横向き4ページ版とスマホ縦読み版
作成日
更新日
Source URL
https://papanda925.com/?p=15418

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました