用漫画轻松懂!尝试制作基于图像数据的漫画切换查看器 —— 横屏4页版与手机竖屏阅读版

编程・Web开发

关于本文
本文采用利用生成式 AI 的自动化生成流程制作。papanda925 Character Sheet v1 在 Daily-Code-Samples 中实现了以统一的角色标准为基础的4张漫画图片,通过 JSON 实现逐页切换的“横屏页面切换版”,以及将相同图片从上到下依次排列的“手机竖屏阅读版”,以此比较不同显示方式的区别。

验证状态:🧪 GitHub 已实现・JavaScript/JSON/公开安全性检查成功・GitHub Pages 构建完成・手机实机显示未确认

如果要在网页上展示漫画,最简单的方法是将一张长图直接纵向放置。

但这一次,我们决定再向前迈出一步。

通过“上一页”和“下一页”逐页切换的横屏查看器,以及在手机上直接向下滚动阅读的竖屏查看器,我们使用相同的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 头身左右,可爱的小头Q版动画风格

  • 基本表情设定为“思考”、“惊讶”、“说明・高兴”

为了能够在文章中重复利用这些标准,我们在 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

并不是为4页分别制作了4个 HTML 文件。HTML 只有一个界面

通过 JavaScript 动态替换其中 <img> 的引用目标。

使用 JSON 保存图片与附加数据

manga.json 在 中,不仅保存了图片路径,还一同保存了该页面附带的相关信息。

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

如果只是切换页面,直接在 JavaScript 中写死4个图片名称也能运行。

即便如此,我们还是将 JSON 独立出来,因为我们希望将图片和显示用的信息作为一个单页的数据来处理

通过 fetch() 读取 JSON

页面信息通过 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 ?? '';
}

核心是下面这一行代码。

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';

第一页会立即加载,而第二页及之后的页面则使用浏览器的延迟加载功能。

虽然对于本次大约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页版与手机竖屏阅读版
?布日期
更新日期
来源
https://papanda925.com/?p=15421&lang=zh

?可: ?于本站?有相??利的正文及原??表,除非?有?明,可依据 CC BY 4.0 使用。本文可能包含使用生成式AI?建或??的内容。若代??有?可声明,或?接的GitHub???定了?可,?代?以??可?准。引用内容、第三方?料、?片及商?不在本?可范?内。 使用政策

标题和URL已复制