# React-Konva 画区块链上链凭证:为什么我放弃 HTML,改用 Canvas 做证书系统

4 阅读6分钟

我用 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
Hashx=130 y=360
红章x=850 y=1320
二维码x=920 y=1480

这些元素:

不应该被网页布局影响。


真正专业的证书系统怎么做

后来我去研究:

  • 易签宝
  • 法大大
  • Canva
  • 创客贴

发现它们本质上都不是普通网页。

而是:

「画布系统」

也就是:

Canvas
SVG
Skia

这一类:

坐标渲染系统。

因为:

证书真正需要的是:

背景图 + 固定坐标元素

而不是:

HTML 自动排版

为什么我最终选择 React-Konva

React-Konva 本质上是:

Konva 的 React 封装

官网:

konvajs.org/

安装:

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

非常关键。

否则:

导出的证书会糊。

我后来甚至直接拿它生成:

  • PDF
  • 存证凭证
  • 合同快照
  • 区块链证明

效果都非常好。


React-Konva 最适合哪些场景

后来我发现:

它特别适合:

场景推荐
区块链凭证
NFT 卡片
电子合同
海报系统
名片生成
模板编辑器
可视化拖拽系统

尤其是:

「固定布局 + 动态内容」

这一类系统。


后面还能继续升级什么

后来我又继续扩展了:

1. 证书模板系统

用户可以:

  • 上传背景
  • 拖字段
  • 保存模板
  • 自动生成证书

已经有点像:

Canva

了。


2. 区块链验真

证书生成后:

PDF → SHA256 → 上链

然后:

TxHash + 二维码

直接生成上链凭证。


3. PDF 导出

后面配合:

jspdf

直接导出:

电子合同
区块链凭证
资产存证书

非常适合做:

  • SaaS
  • 电子签
  • 存证平台

最后的感受

以前我一直以为:

证书只是一个页面

后来才发现:

真正的证书系统:

本质上是“渲染引擎”。

React-Konva 最大的价值:

不是“能画 Canvas”。

而是:

它终于让证书变成了“固定画布”。

这也是为什么后来:

  • 电子签
  • 海报平台
  • 模板系统
  • NFT 平台

越来越偏向:

Canvas/SVG 渲染

而不是:

HTML absolute 布局

如果你也正在做:

  • 区块链上链凭证
  • NFT 卡片
  • 存证系统
  • PDF 模板
  • 电子合同

那么:

React-Konva 真的值得试一次。