# 结构式画板 · 使用与部署说明

> **在线地址**：<http://114.55.131.51/structure/>  
> **站点入口**：WordPress「站点导航」→「结构式画板」  
> **版本**：v1.1 · 2026-10-18  
> **源文件**：`structure/index.html` + `style.css` + `app.js` + `elements.js`（多文件静态页）  
> **文档在线版**：<http://114.55.131.51/structure/structure-sketch-guide.md>

---

## 1. 概述

结构式画板是一个可以直接在浏览器里画有机结构式的轻量工具：

- 纯 HTML + CSS + Canvas 2D，多文件静态页，无外部 JS/CSS/字体依赖
- 元素数据放在 `elements.js`，离线打开 `structure/index.html` 也能用
- 支持原子、单/双/三键、环、芳环模板、隐式氢、相对分子质量
- 导出带分子式和相对分子质量的 PNG
- 导出前做价键与连通性检查，明显不合理的结构（例如 CH₈）会被拒绝

线上页面是独立静态页，不套 WordPress 主题头尾；从站点菜单点击后进入，浏览器返回键返回站点。

![线上结构式画板](structure-live-preview.png)

---

## 2. 功能一览

| 功能 | 说明 |
| --- | --- |
| 元素 | 10 个快捷元素：C、H、O、N、S、P、F、Cl、Br、I |
| 周期表 | 90 个天然/常见元素，点击选择；含 28 个灰色未收录占位 |
| 键级 | 单键、双键、三键 |
| 画布 | 单击放原子、拖拽成键、单击原子换元素、右键删原子 |
| 撤销 | 支持 `Ctrl/Cmd + Z`，最多保留 60 步 |
| 框选删除 | 拖出矩形，删除框内原子及相连键；`Esc` 取消 |
| 整理结构 | 弹簧布局统一键长、张开键角、避免重叠，可撤销 |
| 芳环模板 | 苯、甲苯、萘、吡啶、吡咯、呋喃，一键插入 |
| 分子量 | 自动补隐式氢，计算分子式与相对分子质量 |
| 导出 PNG | 白底、3× 缩放、左下角分子式、右下角相对分子质量 |
| 结构校验 | 过价、多个互不相连片段会被拒绝导出 |

---

## 3. 基本操作

### 3.1 放置原子

- 在空白处**单击**：放置当前元素原子
- 单击位置附近 110px 内有原子时，会按 **46px 键长 + 15° 角度**吸附，避免键长忽长忽短
- 吸附只改变位置，不会自动连键

### 3.2 画键

- 从一个原子**拖到空白处**：在 46px 处生成新原子并连键
- 从一个原子**拖到另一个原子**：在两原子之间连键
- 拖拽时按当前键级生成单/双/三键
- 从原子直接拖出是获得规整键长最稳妥的方式

### 3.3 修改

- **单击原子**：把该原子换成当前选中的元素
- **右键原子**：删除该原子及相连键
- **框选删除**：点「框选删除」后拖矩形，框内原子和相连键一起删除；`Esc` 退出
- **撤销**：按钮或 `Ctrl/Cmd + Z`

### 3.4 手机端

- 单指点击/拖动，交互与桌面一致
- 工具栏会自动换行
- 周期表弹窗可左右滑动查看
- 导出 PNG 走浏览器下载

---

## 4. 元素与周期表

![元素周期表](structure-preview.png)

- 快捷元素区末尾的「周期表」按钮打开完整周期表
- 桌面显示「周期表」文字；手机显示网格图标
- 选中非常用元素后，按钮会显示该元素符号（如 `Fe`）
- 周期表按类别配色：非金属、卤素、准金属、金属、稀有气体
- 点击元素即选用；当前元素有绿色描边
- 底部显示：中文名、元素符号、相对原子质量、最多键数、价电子排布
- 灰色格子是未收录的人造/超重元素，只用于保持周期表形状，不可选

### 收录范围

共 **90 个元素**：

- 1–92 号，排除 43 号锝（Tc）和 61 号钷（Pm）
- 93–118 号超重元素不收录
- 周期表中对应位置显示为灰色占位

---

## 5. 芳环模板

工具栏「芳环」组提供 6 个常用模板，点击后自动找空位插入，不会压到已有结构；插入可撤销。

![芳环模板与苯环](structure-aromatic-preview.png)

| 按钮 | 结构 | 分子式 | 相对分子质量 |
| --- | --- | --- | --- |
| 苯 | 六元芳环 | C₆H₆ | 78.11 |
| 甲苯 | 苯环 + 甲基 | C₇H₈ | 92.14 |
| 萘 | 两个稠合苯环 | C₁₀H₈ | 128.17 |
| 吡啶 | 含一个 N 的六元芳环 | C₅H₅N | 79.10 |
| 吡咯 | 含 NH 的五元芳环 | C₄H₅N | 67.09 |
| 呋喃 | 含 O 的五元芳环 | C₄H₄O | 68.07 |

说明：

- 芳环采用 **Kekulé 交替双键**表示，不画苯环中间的圆圈
- 吡啶的 N 显示为 `N`，吡咯显示为 `NH`，呋喃显示为 `O`
- 插入后可以继续拖出取代基、单击改元素、右键删原子
- 模板本身可以通过导出前的价键校验

---

## 6. 整理结构

点「整理结构」会把当前结构重新排布：

- 弹簧力把所有键长拉向 **46px**
- 1–3 弹簧把键角张开，避免整理后变成一条直线
- 原子间斥力避免重叠
- 整理后整体中心基本不变
- 整理前会写入历史，可撤销
- 没有原子时按钮自动禁用
- 炔烃、累积双键等本来就是直线的中心会跳过键角张开

适合修复“手点出来键长不一致”的旧结构。新画的结构建议直接用拖拽生成，键长天然一致。

---

## 7. 环内双键/三键画法

环上的多重键采用“外边完整、内侧短线”的画法：

- 双键：一条完整的环边 + 一条画在环内侧的短线
- 三键：一条完整的环边 + 两条环内侧短线
- 内侧线两端各缩短一段，不顶到顶点
- 非环双键/三键（C=O、链状 C=C、C≡C）保持原来的对称平行线画法

当前参数：

| 参数 | 值 |
| --- | --- |
| 内侧偏移 | 4.2px |
| 两端内缩 | 18%，最多 9px |
| 三键内侧线 | 4.2px / 7.8px |

环的判定基于图结构：去掉当前键后两端仍连通，即认为在环上；对稠环、杂芳环、手画环都适用。

---

## 8. 分子式、相对分子质量与 PNG 导出

### 8.1 隐式氢规则

导出时会自动补氢：

- 只对**已成键**的非氢原子补隐式氢
- 使用元素数据里的 `hydrogenValence` 作为常见价数
- 补氢数 = `max(0, hydrogenValence − 键级总和)`
- 金属、稀有气体不自动补氢，孤立原子也不补
- 碳上的氢按骨架式惯例不显示，但在分子式里计入
- 杂原子上的氢会显示：`OH`、`NH₂`、`NH`、`SH` 等

### 8.2 分子式

- 按 Hill 顺序排列：有 C 时先 C、再 H，其余按字母序；没有 C 时全部按字母序
- 数字使用真正的下标：`C₂H₆O`
- 单原子时右下角写「相对原子质量」，其余写「相对分子质量」

### 8.3 PNG 版式

- 白底
- 结构居中
- 3× 缩放（长边不超过 4096）
- **左下角**：分子式（下标）
- **右下角**：`相对分子质量 M = xx.xx`

![苯环导出](structure-mass-preview.png)

已验证示例：

| 结构 | 分子式 | 相对分子质量 |
| --- | --- | --- |
| 苯 | C₆H₆ | 78.11 |
| 乙醇 C–C–OH | C₂H₆O | 46.07 |
| 甲醛 C=O | CH₂O | 30.03 |
| 甲烷（单个 C） | CH₄ | 16.04 |
| 单个 C 原子 | C | 12.01（相对原子质量） |

导出成功时提示：`PNG 已导出 · M = 46.07`。

---

## 9. 导出前的结构校验

点「导出 PNG」之前会检查结构；不通过时**不生成图片**，并弹出红色错误提示。

### 9.1 检查项

| 检查 | 规则 |
| --- | --- |
| 过价 | 每个原子的成键总数不能超过上限 |
| 断开 | 除单原子外，所有原子必须连成一个分子 |

成键上限：

- C：4
- H：1
- N：4（容忍硝基、铵）
- O：3（容忍氧鎓）
- B：4（容忍硼酸根）
- 其他主族元素：按 JSON 的 `maxBonds`
- 过渡金属、镧系/锕系：配位数可变，不做硬性上限

### 9.2 示例

画一个碳连 8 个氢，导出会提示：

> 无法导出：碳（C）已成 8 键，超过上限 4 键。

画一个碳和一个氧但不相连，导出会提示：

> 无法导出：画面中有多个互不相连的片段，请先连接成一个分子。

### 9.3 边界

这不是“化学数据库查询”，只做价键和连通性检查。以下情况没有完整建模：

- 电荷、离子、两性离子
- 自由基、卡宾、激发态
- 芳香性、互变异构、共振式
- 配合物、金属有机物种
- 同位素、盐、混合物

---

## 10. 元素数据文件

`elements.json` 是独立数据文件，共 90 个元素；页面实际加载的是由它生成的 `elements.js`（`window.ELEMENTS_DATA = ...`）。字段如下：

| 字段 | 含义 |
| --- | --- |
| `number` | 原子序数 |
| `symbol` | 元素符号 |
| `name` | 中文名 |
| `mass` | 相对原子质量 |
| `maxBonds` | 常规最大成键数（金属取常见配位数） |
| `hydrogenValence` | 用于补隐式氢的常见价数 |
| `valence` | 价电子排布，如 `3d⁶4s²` |
| `period` / `group` | 周期 / 族 |
| `block` | s/p/d/f 区 |
| `category` | 非金属/卤素/准金属/金属/稀有气体 |
| `fRow` / `fIndex` | 镧系/锕系行与位置 |

注意：

- 页面通过 `elements.js` 里的 `window.ELEMENTS_DATA` 读取数据；`elements.json` 是源数据
- 修改 `elements.json` 后需要重新生成 `elements.js`，否则页面仍使用旧数据
- `maxBonds` 是常规上限，画图时不强制，但导出校验会用它检查明显过价
- `hydrogenValence` 只用于补氢和分子量，不等同于最大成键数

---

## 11. 部署说明

### 11.1 线上地址

- 结构式画板：<http://114.55.131.51/structure/>
- 页面标题：`结构式画板`
- 首页入口：WordPress「站点导航」菜单，工具栏和左侧栏各有一个「结构式画板」

![WordPress 菜单](wordpress-menu-preview.png)

### 11.2 服务器路径

| 项目 | 值 |
| --- | --- |
| WordPress 根目录 | `/www/wwwroot/114_55_131_51/` |
| 静态页目录 | `/www/wwwroot/114_55_131_51/structure/` |
| 入口页面 | `/www/wwwroot/114_55_131_51/structure/index.html` |
| 样式 | `/www/wwwroot/114_55_131_51/structure/style.css` |
| 脚本 | `/www/wwwroot/114_55_131_51/structure/app.js` |
| 元素数据 | `/www/wwwroot/114_55_131_51/structure/elements.js` |
| 目录权限 | `www:www`，`755` |
| 文件权限 | `www:www`，`644` |

这是纯静态页，nginx 直接返回，不经过 PHP，也不读写数据库。

### 11.3 菜单

- 菜单名称：`站点导航`
- 菜单 term_id：`3`
- 菜单位置：`toolbar_menu`、`leftbar_menu`
- 现有菜单项：
  1. 电子云实验室 → `/cloud/`
  2. 结构式画板 → `/structure/`（本次新增，item_id `22`）
- 菜单链接使用**相对路径** `/structure/`；以后绑定域名或启用 HTTPS 不需要改菜单

### 11.4 更新页面

1. 把新的多文件覆盖到：

   ```text
   /www/wwwroot/114_55_131_51/structure/index.html
   /www/wwwroot/114_55_131_51/structure/style.css
   /www/wwwroot/114_55_131_51/structure/app.js
   /www/wwwroot/114_55_131_51/structure/elements.js
   ```

2. 保持权限：

   ```bash
   chown www:www /www/wwwroot/114_55_131_51/structure/*
   chmod 644 /www/wwwroot/114_55_131_51/structure/*
   ```

3. 浏览器强刷（`Ctrl/Cmd + Shift + R`）即可；静态页没有 WordPress 缓存问题
4. 菜单不需要改动

如果改了 `elements.json`，需要重新生成 `elements.js`（内容是 `window.ELEMENTS_DATA = <JSON>;`）再上传；只改 JSON 不会影响页面。

### 11.5 域名说明

WordPress 里配置的站点地址是 `http://www.sakurafalling.fun`，但该域名目前没有解析成功。现在请直接用服务器 IP 访问：

- 站点：<http://114.55.131.51/>
- 画板：<http://114.55.131.51/structure/>

菜单用的是相对路径，域名恢复后入口不会失效。

---

## 12. 已知限制

- 不支持电荷、自由基、同位素、互变异构、共振式
- 芳环用 Kekulé 双键表示，没有“苯环中间画圆圈”的离域表示
- 过渡金属/镧系/锕系的过价检查被跳过，配合物不在适用范围内
- 不做保存/打开/云同步，刷新页面后画布内容会清空
- 没有重做（redo）、拖动移动原子、复制粘贴
- 含多个互不相连片段的画面不能导出为单一分子
- 线上是独立静态页，没有 WordPress 主题头尾；用浏览器返回键回站点
- `maxBonds` 中金属取常见配位数，不是严格化学上限

---

## 13. 文件清单

| 文件 | 用途 |
| --- | --- |
| `structure/index.html` | 页面骨架（约 112 行） |
| `structure/style.css` | 全部样式 |
| `structure/app.js` | 绘制、交互、整理、导出、校验 |
| `structure/elements.js` | 页面加载的元素数据 |
| `elements.json` | 90 个元素源数据 |
| `structure-sketch.html` | 旧单文件归档（离线备用） |
| `cloud/index.html` + `style.css` + `app.js` | 电子云项目多文件版 |
| `electron-cloud.html` | 电子云旧单文件归档 |
| `structure-preview.png` | 元素周期表截图 |
| `structure-aromatic-preview.png` | 芳环模板与苯环截图 |
| `structure-mass-preview.png` | 苯环导出 PNG 示例 |
| `structure-live-preview.png` | 线上页面截图 |
| `wordpress-menu-preview.png` | WordPress 菜单截图 |
| `structure-sketch-guide.md` | 本文档 |

---

## 14. 上线验证记录

- `http://114.55.131.51/structure/` 返回 **200**，`index.html` 4,659 字节
- `style.css` 11,624 字节、`app.js` 40,973 字节、`elements.js` 18,029 字节，均返回 200
- 页面标题：`结构式画板`
- 线上页面检测到：
  - 6 个芳环模板按钮
  - 10 个快捷元素按钮
  - `周期表`、`导出 PNG` 等按钮正常
  - 无浏览器控制台错误
- 首页「站点导航」检测到两处「结构式画板」，href 均为 `/structure/`；同时保留「电子云实验室」`/cloud/`
- 模板导出校验：
  - 苯 C₆H₆ / 78.11
  - 甲苯 C₇H₈ / 92.14
  - 萘 C₁₀H₈ / 128.17
  - 吡啶 C₅H₅N / 79.10
  - 吡咯 C₄H₅N / 67.09
  - 呋喃 C₄H₄O / 68.07
- CH₈：拒绝导出，提示“碳（C）已成 8 键，超过上限 4 键”
- 断开片段：拒绝导出，提示“画面中有多个互不相连的片段”
- 非环 C=O：仍为对称双线，CH₂O / 30.03

---

*文档版本 v1.1 · 2026-10-18*
