文章導出插件:從一張圖到一套產品
前些天為「島上隨筆」開發了 export_article 文章導出插件——在每篇文章下方加一個「📤 導出」按鈕,一鍵把文章變成精美的豎版海報圖片或 Word 文檔。開發過程中反覆打磨,從最樸素的「能導出」到現在的面板化、可配置、四種二維碼模式,這裡把完整的產品設計、設計決策與技術細節記錄下來。
一、產品說明書
1.1 它是什麼
export_article 是一個 emlog 插件,作用是在文章詳情頁注入導出工具:把當前文章渲染成一張手機海報長圖(PNG)或 Word 文檔(.doc),附帶實時預覽——所見即所得。
1.2 核心功能
| 功能 | 說明 |
|---|---|
| 導出圖片 | 手機豎版(720px 寬)或 PC 閱讀樣式(1000px 寬),2 倍清晰度 PNG |
| 導出 Word | 兼容 Word 的 HTML 打包成 .doc,含字體/背景/簽名樣式 |
| 實時預覽 | 左側預覽框即時同步所有設置,手機 9:16 或 A4 豎版兩種比例框 |
| 四種二維碼 | 原文鏈接 / 自定義鏈接 / 文件提取(解碼重生成)/ 圖片粘貼(截圖) |
| 中心文字 | 二維碼中心疊加品牌文字(可自定義,默認「島上隨筆」) |
1.3 設置項總覽(右側面板)
排版
- 樣式切換:📱 手機(默認)/ 🖥 PC
- 字號四檔:小 20 / 中 26(默認) / 大 32 / 特大 38——手機默認 26px,切 PC 自動 20px
- 字體六種:仿宋 / 宋體 / 黑體 / 楷體 / 雅黑 / 襯線
- 行距三檔:緊湊 1.6 / 標準 1.9 / 寬鬆 2.2
- 背景六色:純白 / 米黃 / 薄荷綠 / 霧藍 / 淡粉 / 深墨
- 文字顏色八色:深灰 / 純黑 / 墨藍 / 墨綠 / 棕 / 酒紅 / 黛紫 / 淺白
- 首行縮進開關
內容開關(分組)
- 封面頭:總開關 + 品牌 / 副標題 / 標題 三個單項
- 封面腳:總開關 + 來源 / 二維碼 / 時間 / 當前時間 四個單項
- 簽名(自定義,空則不顯示)
二維碼
- 四種模式 + 中心文字輸入框 + 自定義鏈接輸入 + 生成按鈕
1.4 二維碼四模式詳解
- 原文鏈接:直接生成當前文章 URL 的二維碼(默認)
- 自定義鏈接:填任意網址 → 點「生成二維碼」→ 預覽即時更新
- 文件提取:上傳二維碼圖片 → jsQR 解碼出鏈接 → 用該鏈接重新生成新碼(附註:微信官方升級後的新碼無法識別,僅支持舊碼/其他來源)
- 圖片粘貼:上傳帶二維碼的圖片 → 自動框選二維碼區域(jsQR 角點定位)→ 確認後截圖放入
二、設計說明書
2.1 視覺設計:參考真實案例
手機樣式參考了一張公眾號封面海報的佈局:上部 85% 深紫藍漸變(#140629 → #40226e)的星空頭,下部 15% 白色二維碼區。由此定下手機版三段式:
┌──────────────────────┐
│ 深紫藍漸變星空頭 │ ← 品牌 + 副標題 + 標題(白字)
│ ✦ 星點裝飾 │
├──────────────────────┤
│ 正文(白底,深色字) │ ← 閱讀區
├──────────────────────┤
│ 白底底部:來源+時間 │ ← 左文字右二維碼
└──────────────────────┘
PC 樣式則保留經典的「品牌頭 + 獨立標題 + 正文 + 來源條」閱讀佈局。
2.2 字號體系:基準倍率
以正文為基準,所有元素按倍率等比縮放,保證任何字號下比例協調:
| 元素 | 倍率 | 26px 時 |
|---|---|---|
| 正文 | ×1.0 | 26px |
| 頭部主標題 | ×1.5 | 39px |
| 文章標題 | ×1.3 | 34px |
| 頭部副標題 | ×0.7 | 18px |
| 底部來源 | ×0.7 | 18px |
2.3 交互設計
- 面板默認收起:點「📤 導出」才展開,不干擾閱讀
- 左右分欄:左預覽(58%)右設置(42%),窄屏自動改上下
- 預覽框滿屏:高度 62vh(一屏),寬度按 9:16 或 A4 比例自動推導,內容超一屏才出現內部滾動條
- 防抖刷新:下拉/複選在 change 後 400ms 刷新,輸入框實時刷新,避免預覽閃爍
- 字號聯動:切手機/PC 自動帶對應默認字號,手動改過則不覆蓋
2.4 二維碼中心文字
最初想用站點 favicon 圖片做中心 logo,但 SVG 跨域繪製到 canvas 失敗(生成空白),改為用戶可輸入的文字方案:白底襯底 → 深灰文字 + 3px 對比色描邊(深字白邊/淺字深邊),與碼點清晰分離,任何背景下可讀。文字顏色跟隨用戶選的文字色。
三、代碼修改情況
3.1 技術棧
| 庫 | 用途 | 說明 |
|---|---|---|
| html2canvas 1.4.1 | 頁面截圖 | 本地託管,離線可用 |
| qrcode.min.js | 生成二維碼 | 支持 canvas 輸出 |
| jsQR 1.4.0 | 解碼二維碼 | 文件提取模式用,256KB |
3.2 踩過的坑(重要教訓)
- html2canvas CSS 解析崩潰:字體棧含中文字體名(宋體/楷體)或帶空格字體名(Kaiti SC)會報
Error parsing CSS component value, unexpected EOF。修復:全部改用純 ASCII 無空格字體棧(SimSun,STSong,serif 等),並加 normalizeFont 過濾器兜底。 - 行距不生效:主題全局
p { line-height: 2 }覆蓋了導出容器設置。修復:給 p/li 顯式加line-height:inherit。 - JS 閉合錯亂:多次插入功能後 loadJs 嵌套鏈(html2canvas→qrcode→jsQR)括號失衡,node --check 反覆報錯,最終用深度追蹤逐層修復。
- SVG 中心 logo 空白:
ctx.drawImage(SVG)異步加載跨域失敗,改文字方案。 - 微信新碼無法識別:微信官方升級二維碼算法,jsQR 解不出,界面明確提示並改為「文件提取」模式。
- 框選偏移:裁剪換算用容器尺寸而圖片未佔滿容器,導致截圖偏上;統一改用圖片自身 getBoundingClientRect 坐標系 + 偏移校正。
3.3 版本演進
| 階段 | 內容 |
|---|---|
| v1.0 | 基礎導出圖片 + Word,模板 5 套,字體/字號/背景/行距/縮進/簽名 |
| 模板差異化 | 每模板獨立強調色 + 頭部漸變;後因維護複雜移除模板,改自由組合 |
| 開關體系 | 封面頭/封面腳分組總開關 + 單項開關,全部可隱藏 |
| 時間體系 | 默認文章發佈時間,可切當前時間 |
| 二維碼升級 | 原文/自定義/文件提取/圖片粘貼四模式 + 中心文字 |
| 預覽優化 | 手機 9:16 / A4 比例框,滿屏一屏超屏滾動 |
3.4 文件結構
export_article/
├── export_article.php # 主文件(按鈕注入 + 全部 JS/CSS)
├── export_article_callback.php # 插件生命周期回調
└── js/
├── html2canvas.min.js # 截圖庫(本地)
├── qrcode.min.js # 二維碼生成
└── jsQR.js # 二維碼解碼
四、後續計劃
- 把插件打包發布(v1.2)到主站下載區
- 模板預設功能考慮以「預設組」形式回歸(不影響自由組合)
- 微信新碼識別待跟進官方方案
「一島之道,始於一張導出圖。」
文章导出
生成预览中...