定位
pf-editor 是图模工坊的设计端入口——管理员/设计师在浏览器里拖出版面、定义可编辑区域、保存为模板。它不是 PS 的替代品,而是面向”批量交付”的模板生产工具。
- 框架:Quasar 2.16 + Vue 3.5 + TypeScript 5.9
- 渲染引擎:Leafer 2.x(开源高性能矢量渲染引擎)
- 构建:Vite 7(quasar-cli-vite)
- 端口:开发环境
9000 - 鉴权:JWT(与 pf-manage 共用账号体系,走
pf-service鉴权路由)
它和 PS / Figma 的区别
| 维度 | PS / Figma | pf-editor |
|---|---|---|
| 输出 | PSD / Fig 文件 | sceneJson,可被代码消费 |
| 可编辑区域 | 靠图层命名约定 | 节点上显式 editable: true |
| 字段化 | 用户在 PS 里改 | 用户在 H5 里填,编辑器侧只描述”哪里能改” |
| 批量 | 手工另存 N 张 | 一份模板 + N 份用户填值 → N 张成品 |
| 人脸避让 | 设计师手动放区域 | 节点声明 faceSafe: true,合成时自动避让 |
源码结构
1 | apps/pf-editor/src/ |
sceneJson 协议
整个编辑器围绕一份 JSON 工作。简化结构:
1 | { |
节点关键属性
| 属性 | 类型 | 作用 |
|---|---|---|
id |
string | 节点 id,用户提交时作为 userUploads / userTexts 的 elementKey |
tag |
string | Leafer 节点类型:Rect / Image / Text / Group / Path |
x / y / width / height |
number | 几何,单位与 templates.width/height 一致 |
editable |
boolean | 是否允许终端用户修改(图片/文字) |
locked |
boolean | 编辑器侧是否锁定(防误改) |
placeholder |
string | 用户端未填值时的占位 |
faceSafe |
boolean | 图片节点:合成时调用 face-service 做避脸裁剪 |
fit |
string | 图片填充:cover / contain / fill |
fontFamily / fontSize / fill / align |
mixed | 文字属性,可由用户覆写 |
编辑能力
- 基础节点:矩形、图片、文字、形状(Path)、组(Group)
- 图层管理:节点树、层级调整、显隐、锁定
- 画布操作:缩放(滚轮 / 触控板)、平移、对齐、吸附、网格
- 历史记录:Undo / Redo(基于 sceneJson diff,存 stores)
- 属性面板:右侧
PropertyEditor.vue按选中节点 tag 切换子组件 - 可编辑区标记:勾选
editable后画布上以高亮虚线提示 - 素材库联动:调用
pf-service的/shared/background-library、/shared/font-library拉取共享素材 - 测试合成:编辑过程中可调用一次”试合成”,验证最终效果(模板上线前的必跑校验)
与后端的交互
1 | pf-editor |
路由实现位于 apps/pf-service/src/routes/projects/pf-editor/,按职责拆分:
templateEditorRoutes.ts— 模板增删改查、版本控制templateSharedRoutes.ts— 与用户端、管理端共享的模板读接口
字体加载
编辑器和用户端共享 composables/fontPreload.ts——首次进入页面时按 font_variants 拉取并 FontFace.load() 注册到浏览器,确保画布渲染的文字与最终合成一致。
字体的”权威源”是 MinIO 中的 woff2 文件;Puppeteer 合成时通过相同 URL 注入,保证三端字形完全对齐。
协作约束
参见 apps/pf-app/dev.md 与项目根 AGENTS.md:
- Vue 文件 PascalCase,TS 文件 camelCase
<script setup lang="ts">强制- 组合式函数命名
useXxx,位于composables/ - 共享代码沉到
packages/*(如@sa/hooks、@sa/materials)
与 pf-app 的代码复用
两个 Quasar 应用结构对称、Boot 文件几乎一致——核心组件如 ImageCropper.vue、ImagePreview.vue 也会通过 packages/materials 抽取共享。编辑器多出来的是”出版” UI,用户端多出来的是”消费” UI,渲染引擎和 sceneJson 解析逻辑是共用的,这是一份模板能跨端用的根本。