我用 React-Konva 重构了整个证书系统:从 HTML 崩布局到真正的“固定画布”方案
做区块链上链凭证、电子签、NFT 卡片时,我用 HTML + absolute 定位。
直到有一天,一个“资产地址”字段把整张证书撑炸了。
前言
最近在做一个:
- 区块链上链凭证
- 电子签证书
- 资产存证页面
- PDF 导出系统
最开始我的实现方案非常传统:
<div class="certificate">
<img src="/bg.png" />
<div class="title">区块链上链凭证</div>
<div class="hash">0x123456...</div>
</div>
然后:
position: absolute;
疯狂定位。
一开始感觉还挺合理。
但随着动态数据越来越多,问题开始疯狂出现:
- 长文本撑坏布局
- 手机端比例错乱
- 背景和内容不协调
- 导出 PDF 模糊
- 字体位置总是偏
- 缩放以后布局直接炸掉
尤其是这种字段:
杨柳国际新城火炬广场01单元4层0402号
直接把整张证书顶变形。
后来我意识到:
我做的根本不是“网页”
而是:
「一个证书渲染系统」
于是我把整个方案彻底换成了:
React + React-Konva
结果:
整个世界都清净了。
为什么 HTML 不适合做证书
很多人做证书时,下意识会认为:
证书 = 一张背景图 + 一堆 div
但实际上:
HTML 的本质是:
「流式布局」
也就是说:
- 内容会自动换行
- 高度会自动撑开
- flex 会重新计算
- 响应式会重新排列
它更适合:
- 官网
- 后台
- CMS
- 表单系统
而不是:
- 证书
- 海报
- 电子合同
- NFT 卡片
- 上链凭证
因为这些东西本质上:
都是“固定画布”
什么意思?
例如一张证书:
| 元素 | 坐标 |
|---|---|
| 标题 | x=300 y=120 |
| Hash | x=130 y=360 |
| 红章 | x=850 y=1320 |
| 二维码 | x=920 y=1480 |
这些元素:
不应该被网页布局影响。
真正专业的证书系统怎么做
后来我去研究:
- 易签宝
- 法大大
- Canva
- 创客贴
发现它们本质上都不是普通网页。
而是:
「画布系统」
也就是:
Canvas
SVG
Skia
这一类:
坐标渲染系统。
因为:
证书真正需要的是:
背景图 + 固定坐标元素
而不是:
HTML 自动排版
为什么我最终选择 React-Konva
React-Konva 本质上是:
Konva 的 React 封装
官网:
安装:
npm i react-konva konva
我选择它最核心的原因只有一句话:
它是真正的“固定画布”方案。
例如:
<Text
x={120}
y={360}
text="区块链哈希"
/>
这段代码意味着:
这个元素永远在这个位置
不会:
- 被 flex 影响
- 被换行影响
- 被响应式影响
- 被高度撑开影响
这才是证书真正需要的东西。
React-Konva 为什么特别适合证书系统
当时我把整个系统迁移完以后,最大的感受就是:
“终于像在做证书了,而不是在做网页。”
因为它天然支持:
| 功能 | React-Konva |
|---|---|
| 固定画布 | ✅ |
| 坐标定位 | ✅ |
| 整体缩放 | ✅ |
| 高清导出 | ✅ |
| 二维码 | ✅ |
| 红章 | ✅ |
| 动态数据 | ✅ |
| PDF 导出 | ✅ |
尤其是:
「整体缩放」
这是 HTML 最难处理的东西。
我最终的证书结构
我后来把整个证书拆成:
Stage
└── Layer
├── 背景图
├── 标题
├── 上链信息
├── 商品信息
├── 用户信息
├── 红章
└── 二维码
这时候整个证书:
已经变成了一个真正的“渲染树”
而不是:
一堆乱飞的 absolute div
开始实现一个区块链上链凭证
一、创建固定画布
首先定义证书尺寸:
const CERT_WIDTH = 1200;
const CERT_HEIGHT = 1700;
这里我使用的是:
A4 比例
然后创建 Stage:
<Stage
width={CERT_WIDTH}
height={CERT_HEIGHT}
>
这里的 Stage:
你可以理解成:
整张证书的“世界坐标系”
二、加载背景图
很多人会继续用:
background-image
但实际上:
Canvas 正确做法是:
<KonvaImage
image={image}
width={CERT_WIDTH}
height={CERT_HEIGHT}
/>
这样背景会真正进入 Canvas。
后面导出 PNG/PDF 时:
背景也会一起导出。
三、使用坐标定位内容
这是整个系统最核心的一步。
例如:
<Text
x={130}
y={340}
text="上链交易哈希"
/>
这时候:
元素的位置已经完全固定
不会再受到:
- 浏览器布局
- flex
- 响应式
- 换行
影响。
这也是为什么:
Canvas 天生适合做证书。
四、实现动态数据
我最终的数据结构:
const data = {
txHash: '0x123456',
userName: '李先生',
amount: '100000000'
}
然后:
<Text text={data.txHash} />
即可。
这里最大的好处是:
数据和布局完全解耦。
后面:
- 接后端
- 接区块链
- 接存证接口
都会非常舒服。
五、React-Konva 最强的能力:整体缩放
这是我真正被惊艳到的地方。
以前 HTML 做证书时:
transform: scale()
会出现:
- 坐标错乱
- 清晰度下降
- 鼠标位置偏移
- 导出异常
但 Konva:
只需要:
<Stage
scaleX={scale}
scaleY={scale}
>
整个证书:
- 背景
- 文字
- 红章
- 二维码
- 边框
会:
一起等比例缩放。
而且:
布局完全不变。
这才是真正的:
证书系统
六、实现自适应
我的实现方式:
const newScale = Math.min(
containerWidth / CERT_WIDTH,
1
)
这样:
- PC 正常显示
- 手机自动缩小
- 永远不会超出屏幕
最关键的是:
所有内容都会跟着一起缩放。
这和 HTML 完全不是一个体验。
七、导出高清 PNG
Konva 原生支持:
stageRef.current?.toDataURL({
pixelRatio: 3
})
这里:
pixelRatio: 3
非常关键。
否则:
导出的证书会糊。
我后来甚至直接拿它生成:
- 存证凭证
- 合同快照
- 区块链证明
效果都非常好。
React-Konva 最适合哪些场景
后来我发现:
它特别适合:
| 场景 | 推荐 |
|---|---|
| 区块链凭证 | ✅ |
| NFT 卡片 | ✅ |
| 电子合同 | ✅ |
| 海报系统 | ✅ |
| 名片生成 | ✅ |
| 模板编辑器 | ✅ |
| 可视化拖拽系统 | ✅ |
尤其是:
「固定布局 + 动态内容」
这一类系统。
后面还能继续升级什么
后来我又继续扩展了:
1. 证书模板系统
用户可以:
- 上传背景
- 拖字段
- 保存模板
- 自动生成证书
已经有点像:
Canva
了。
2. 区块链验真
证书生成后:
PDF → SHA256 → 上链
然后:
TxHash + 二维码
直接生成上链凭证。
3. PDF 导出
后面配合:
jspdf
直接导出:
电子合同
区块链凭证
资产存证书
非常适合做:
- SaaS
- 电子签
- 存证平台
最后的感受
以前我一直以为:
证书只是一个页面
后来才发现:
真正的证书系统:
本质上是“渲染引擎”。
React-Konva 最大的价值:
不是“能画 Canvas”。
而是:
它终于让证书变成了“固定画布”。
这也是为什么后来:
- 电子签
- 海报平台
- 模板系统
- NFT 平台
越来越偏向:
Canvas/SVG 渲染
而不是:
HTML absolute 布局
如果你也正在做:
- 区块链上链凭证
- NFT 卡片
- 存证系统
- PDF 模板
- 电子合同
那么: