# 向村行 · 电容印章 H5 实验室

日期：2026-11-07，完整盖章流程版。用途：录入实体触点与电子章图案，在手机下半屏正方形区域识别，显示章面并收入本机集章册。尚未使用实际电容章验证。

## 快速开始

1. 用手机 Safari 或 Chrome 打开部署后的 HTTPS 地址。先用这些浏览器排查，再测试微信内置浏览器。
2. 点击「录入新章」，填写名称，选择山野/茶叶/溪桥内置章面或上传 PNG/JPG，再选择实物触点数（3、4 或 5）和颜色。上传图片限 5 MB，页面压缩为不超过 320px 的 PNG，透明背景保留。
3. 裸手握住样章导电部位，在下方正方形区域轻按约半秒，然后全部抬起。重复三次，第二、三次换位置或转动方向。
4. 三次采样一致后点击「保存模板与电子章」。页面拒绝点数不符、近共线、不一致或与已有模板太相似的录入。
5. 保存后自动回到「识别盖章」。重新按压，完全抬起后，方形区域显示绑定的印章图案和盖章动画，同时点亮集章册。重复识别仍显示图案，不增加收藏数量。「继续盖章」或下一次触摸清除旧章面；失败不显示上一次成功图案。
6. 进入「我的集章册」，用「导出模板」保存包含图案的 JSON，发送到另一台手机，在同一个站点「导入模板」。其他设备不会自动取得本机模板。
7. 异常时进入「工具与说明」，展开「触点数据与诊断记录」，查看当前/最多触点数并导出诊断记录。诊断包含最近 100 次采样、浏览器信息、视口及像素比例，不包含登录信息。

可以用手指验证多点触摸通路，但人手无法稳定重复同一几何布局，不能用此结果证明电容印章可靠。鼠标不支持实物多点测试。本页显示的设备最大触点数是浏览器报告值，不是本页实测能力。

## 上传 Cloudflare Pages

这是静态站点：没有 Java 服务、数据库、外部字体、CDN 脚本或账户密码。无需填写服务器地址，不需要端口转发。

交付文件：`output/stamp-h5/cloudflare-pages.zip`。ZIP 根目录就是 `index.html` 和其依赖。也可以上传 `stamp-h5/dist/` 文件夹。

1. 登录 Cloudflare，进入 **Workers & Pages**，创建 **Pages** 项目，选择 **Direct Upload / Upload assets**（直接上传静态资源，具体按钮名称以控制台为准）。
2. 上传 ZIP 或整个 `dist` 文件夹，填写项目名称并部署。不要把整个 Java/小程序项目上传，也不要选需要 Worker 入口代码的模板。
3. 打开 Cloudflare 返回的 `https://项目名.pages.dev` 地址，用手机浏览器测试。是否能顺利访问取决于所在地网络；先确认页面可达，再排查硬件。
4. 后续更新仍上传新 ZIP，尽量使用同一生产域名。预览域名、自定义域名、不同浏览器的本地存储互相独立。

官方文档：https://developers.cloudflare.com/pages/get-started/direct-upload/ 。2026-11-07 核对：控制台拖放支持 ZIP/文件夹；Wrangler 只接受文件夹。选择 Direct Upload 的项目不能直接切成 Git integration，需要另建项目。

若使用 Git integration：项目根目录设为 `travel-village-main/stamp-h5`（若仓库根就是 travel-village-main，则填 `stamp-h5`），构建命令 `npm run build`，输出目录 `dist`，无需安装此站点的生产依赖。

本项目的 Cloudflare Pages 生产地址为 https://travel-village-stamps.pages.dev/ ，项目名 `travel-village-stamps`，生产分支 `main`。更新时在已授权账号下运行 `npx wrangler pages deploy dist --project-name travel-village-stamps --branch main`。本机 localhost、预览地址与生产域名的存储互相独立；已有模板请先从原地址导出，再在生产地址导入。

## 本地运行与打包

在 Node.js 22 或更高版本运行：

```powershell
cd D:\bcb\travel-village\travel-village-main\stamp-h5
npm test
npm start
```

启动器打印本机预览地址，按 Ctrl+C 停止。此预览绑定 127.0.0.1；手机使用 Cloudflare HTTPS 地址。不要直接双击 HTML 用 file:// 打开，ES modules 需要 HTTP(S)。

```powershell
npm run build
```

构建只复制明确列出的静态资源到 `dist/`。不包含源码测试、node_modules、现有后台账号、其他项目数据库等。

浏览器测试需要父项目已有的 Playwright 和 Chrome：`npm run test:browser`。该测试用浏览器合成多点事件，不能证明实体印章或 iPhone Safari 兼容。

## 相对点位与三角基准的区别

你的想法属于「基准点 + 编码点」设计：用三个不共线、可区分的基准点建立局部坐标系，再判断其他点处于什么位置。但这不是电容章统一行业协议；必须约定基准点、如何从所有点中找出基准点、可选编码位置和误差范围。不能只说“有一个三角形”就自动确定每个点的身份。

- 一点只能确定位置，不能确定方向和尺度。
- 两个已知且能区分身份的点，可确定平面相似变换的位置、方向和尺度。三个不共线的点可以增加校验、确定朝向，并在约定中表示二维坐标基准。
- 对称三角形的顶点难区分，三个基准点应具有足够不对称的几何特征，并确保不会和编码点组成另一个近似基准三角形。
- 三个固定基准点若没有其他点，所有印章的几何形状一样，无法表示不同章。通常至少需要第四个点作编码；点越多，漏点和系统手势风险也越高。
- 手机提供的是屏幕平面触点，无法可靠恢复倾斜的章面或补出未接触的点。不能把“确定一个面”理解为有三点就可任意斜压。

此 H5 使用另一种更直接的方式：**整组点匹配**。3～5 点时枚举点的对应关系，去掉中心位置、归一化尺度、求最合适旋转，比较归一化残差。无需指定三点为锚点，也不依赖浏览器 touches 的数组顺序。

参数是原型起点，不是已标定的硬件指标：

| 项目 | 实现 |
|---|---|
| 点数 | 3～5，严格要求匹配模板点数，不做缺点补全 |
| 平移/旋转 | 允许任意平移和 0～360° 平面旋转，所有点仍须落在触摸区 |
| 尺度 | 中心均方半径比例约 0.55～1.8；用于不同 CSS 像素尺度，不使用 DPR 直接换算毫米 |
| 形状误差 | 归一化 RMS 残差 ≤ 0.065；显示为几何误差百分比，不是成功概率 |
| 唯一性 | 第一、第二候选误差差距不足 0.035 则拒绝 |
| 录入 | 独立按压三次，任意两次需一致，近似重复模板拒绝 |
| 采集 | 稳定约 220ms，等全部抬起才提交；按压中出现的最大点数为准，剥离时的子集不会另盖一枚 |
| 镜像 | 不主动允许反射匹配；若布局本身对称，镜像可能与某个旋转等价，因此仍需避免对称码型 |

不能通过整体旋转、平移或等比例缩放同一布局制作“不同编码”。不做任意仿射变形拟合：任意两个非共线三角形都能通过仿射变换互相映射，放开这个自由度会丢失三点章的区分能力。

本页会在录入和导入时拒绝跨点数的子集冲突，识别时如果像某款已知多点章的不完整接触也会拒绝。仍不能由坐标推断未知章未被检测到的第四点，也不能识别所有触点合并、漂移等硬件异常。建议首批统一触点数，并以真实手机的漏点与串认数据继续调整码本。附图的三点版正好是四点版的子集，因此两者用于分阶段结构试验，不能作为两款模板同时录入。

## 自制样章：购买什么

| 材料 | 首次准备 | 规格/用途 |
|---|---:|---|
| 手机无源电容笔软触头 | 6～10 个 | 明确是电容屏用导电硅胶/橡胶触头，软、圆润、可更换；首轮可试约 6～9mm 接触直径 |
| 导电握柄/金属握环 | 1～3 套 | 裸手自然接触，表面不能完全被绝缘涂层覆盖 |
| 细铜线或铜箔、压接片 | 一批 | 在内部把触头与握持部位可靠连接，不在屏幕侧形成裸露大面积导体 |
| 绝缘底板和外壳 | 1～3 套 | PLA/PETG 等 3D 打印；也可用加工的绝缘板；可换底板更适合调位置 |
| 弹性支撑与紧固件 | 一批 | 让触点处于同一接触平面，允许轻微压缩，硬件不会触屏 |

搜索：`无源电容笔替换头`、`导电硅胶触屏头`、`3D 打印定制外壳`。普通防静电海绵、普通橡胶不保证合用。不要购买 TTP223 传感模块、NFC 标签或蓝牙模块来代替触头。

工作原理是人体通过握柄和导体参与电容耦合，不是收集或释放人体静电。无需摩擦“充电”、赤脚、接电源或地线。普通手套可能削弱耦合；首次先裸手测试。无需电池并不等于随便几块导电胶就能工作，接触面积、材料、握持结构和屏幕固件都会影响结果。

## 如何定制点位：给加工方毫米坐标

建议先固定接触材料，测出触头安装柄/卡扣尺寸，再画底板。不要拿屏幕上的像素坐标直接当毫米下单。

本包附 `layout-3point.svg`、`layout-4point.svg` 和 `layout-points.csv`：仅用于首轮结构试验，不是已经验证的商用编码。图纸以**直接看向接触屏幕的底面**为准，左上角为原点，X 向右、Y 向下，单位毫米。

下载：[三点样章图](./layout-3point.svg) · [四点样章图](./layout-4point.svg) · [毫米坐标表](./layout-points.csv)。SVG 设定了毫米尺寸，打印时选择 100% 并用尺核对图中 20mm 校验线，不能使用“适合纸张”自动缩放。

| 点 | X / mm | Y / mm | 用途 |
|---|---:|---:|---|
| A | 8 | 8 | 三点版保留 |
| B | 34 | 8 | 三点版保留 |
| C | 13 | 32 | 三点版保留 |
| D | 22 | 18 | 四点版增加，先验证四点稳定性 |

底板示意 42×42mm，圆圈示意接触头直径 7mm，**圆圈不是安装孔径**。安装孔径必须按实购触头的柄/卡扣实测确定；打印误差和配合公差由加工方试配。上表四点版的最小中心距离约 15.6mm；数值只是加工起点，不代表所有屏幕都能分开这几个点。

加工要求可直接发给商家：

> 请按附图制作绝缘可换底板，点位使用毫米坐标。图为触屏底面视图，不要无意镜像。安装孔依我提供的触头实测柄径与卡扣结构确定，不按 7mm 接触圆直接钻孔。触头需可更换、等高、轻压时全部接触；触头压缩到限位时，硬质底板、螺丝与内部金属仍不能接触屏幕。内部预留导线槽和与金属握柄的连接位置，外侧导电握持区裸手可触及。先打一件样，不开量产模具。

如果采用软连接，先验证轻压下触点不会横向漂移。不要把整片导电胶铺满底面再画几个圆：屏幕可能只识别成大块掌触。硬铜箔、针、螺丝不能作为接触手机玻璃的触头。

建议顺序：单触头手机可感知 → 三点同时被上报 → 三次录入及旋转识别 → 多手机/膜/手套试验 → 再改为四点编码和扩展码本。已有章的接触点布局变了，就删除旧模板并重新录入；只改电子章名称无需改变实物。

## 数据与正式系统边界

- 当前 H5 是独立体验工具，含识别盖章、录入新章、我的集章册、工具与说明四个入口。电子章支持三款内置图案及 PNG/JPG 上传，不包含账号体系、云端模板同步或礼品兑换。旧版无图案模板默认使用山野章面。新的收藏记录保存获得时的图案与名称快照。
- 模板和测试记录用 localStorage 保存；清理网站数据会丢失，隐私模式可能不能持久保存。导出模板应作为备份。存储失败会明确提示，不会把未保存当成功。
- 导入文件最多 2 MB、50 款模板，每款严格三次采样，每次 3～5 点；图案必须为内置设计或受限 PNG；导入时额外验证图片能否解码，校验通过后再整体写入。模板与本机记录合计限 2 MB，避免图案过大；不执行导入内容。
- 本机记录也是客户端可修改的数据。浏览器触摸坐标不能证明某个实体章身份，亦不能证明人在景点现场。
- 现有 Java Demo 的“识别编码 → 电子章”仍保留。将来接入时，把此处模板 ID 对应到后台 patternCode，再接正式服务端业务校验；目前此 H5 不调用其接口。
- 当前触摸算法基于标准 Touch Events，微信内浏览器、iOS 多指编辑手势、Android 三指截屏、屏幕掌触抑制等需真机验证，网页不能绕过操作系统限制。

## 源码与验证

- `core.mjs`：几何校验、排列对应、旋转匹配、录入/导入验证、完整按压采集。
- `app.mjs`：Touch Events、录入/识别及章面显示、本地存储、导入导出。
- `artwork.mjs`：内置章面、图片压缩与验证、章面渲染。
- `tests/core.test.mjs`：相对布局、噪声、镜像、缺/多点、模糊匹配、数据校验、抬起/取消等边界。
- `tests/browser.cjs`：Chrome 合成多点录入、保存刷新、旋转识别、重复记录、模板跨上下文导入、非法导入与相似模板拒绝、移动布局。
- `output/playwright/stamp-h5/`：截图与浏览器测试结果，属于浏览器模拟输入，不是真机实物报告。

本次完整流程验证：16 项算法/图案/采集测试通过；Chrome 合成多点验证内置及上传章面录入、旋转识别显图、重复识别、失败清理、跨浏览器上下文导入后识别、存储失败与 320/375/390/430px 移动布局。此为软件和浏览器模拟输入证据，不是实物兼容性证明。
