From a72014e419356deb6c235a75ce52b2edf64e98a8 Mon Sep 17 00:00:00 2001 From: Jz0ojiang Date: Sat, 5 Sep 2026 18:19:32 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=8A=AC=E9=AB=98=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E4=B8=8A=E9=99=90=EF=BC=8C=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E6=94=BE=E5=A4=A7=E6=97=B6=E6=96=87=E5=AD=97=E5=92=8C=E5=BD=A2?= =?UTF-8?q?=E7=8A=B6=E9=94=90=E5=88=A9=E5=88=B0=E7=BA=A6=206=20=E5=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fabric 给每个对象缓存一张离屏画布,面积超过 perfLimitSizeTotal 时不是裁剪而是 降采样,再放大贴屏,于是边缘发虚。默认 2 Mpx 下一个 960x75 的文本框在 12 倍 缩放时 zoomX 从 12 掉到 3.5。 面积和边长是两道独立的闸:只把面积抬到 8 Mpx,zoomX 只从 3.5 涨到 3.9,紧接着 撞上 maxCacheSideLimit 的 4096。两道一起抬(边长 6144 / 面积 8 Mpx)之后实测 4 倍锐利、6 倍以上封顶在 5.92,覆盖了实际会用到的缩放区间。 只影响预览。导出按画板逻辑尺寸重新渲染,与视口缩放无关。 --- src/editor/useEditor.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/editor/useEditor.ts b/src/editor/useEditor.ts index 919a378..13d685b 100644 --- a/src/editor/useEditor.ts +++ b/src/editor/useEditor.ts @@ -10,6 +10,7 @@ import { Textbox, type TPointerEvent, } from "fabric"; +import { config } from "fabric"; import { ref, shallowRef } from "vue"; import type { CanvasSize, LayerKind, SelectionKind, ShapeKind, ToolId } from "@/types"; import { DEFAULT_SIZE } from "./canvasSize"; @@ -24,6 +25,32 @@ import { capImageSize } from "./imageLimits"; * 各条开发线通过 `getCanvas()` 拿到 Fabric 画布实例。**不要另外 new 一个 Canvas。** */ +/** + * 预览放大后文字和形状要保持清晰。 + * + * fabric 给每个对象缓存一张离屏画布,尺寸随对象在屏幕上的大小走;一旦面积超过 + * `config.perfLimitSizeTotal`(默认 2 097 152 px²),它不是裁剪而是**降采样**—— + * 按缩小后的比例画进缓存,再放大贴到屏幕上,于是边缘发虚。 + * + * 实测(2026-09-05,一个约 960×75 的文本框):默认值下 4 倍缩放仍然锐利, + * 12 倍时缓存被压到 3647×574、zoomX 从 12 掉到 3.5,肉眼可见的锯齿和发虚。 + * + * **面积和边长是两道独立的闸**,只抬面积没用:把 perfLimitSizeTotal 抬到 8 Mpx + * 之后 zoomX 只从 3.5 涨到 3.9,因为紧接着撞上了 maxCacheSideLimit 的 4096。 + * 两道一起抬才有效果。 + * + * 取值:边长 6144、面积 8 Mpx。对上面那个文本框大约能锐利到 6 倍,覆盖了实际 + * 会用到的缩放区间(1200×630 的封面很少工作在 400% 以上)。代价是**单个**被压的 + * 对象缓存最大 8 Mpx × 4 B = 32 MB,封面上对象个位数,这个代价可以接受。 + * 再往上抬性价比很低:12 倍锐利需要 40 MB 以上的单对象缓存,而位图图层受自身 + * 分辨率限制,抬多少都不会更清楚。 + * + * 注意这只影响**预览**。导出走的是另一条路(按画板逻辑尺寸重新渲染), + * 和视口缩放无关,io 那边的自验已经断言过 0.25×–3× 导出恒为 1200×630。 + */ +config.perfLimitSizeTotal = 8 * 1024 * 1024; +config.maxCacheSideLimit = 6144; + /** 自定义属性要登记在这里,`canvas.toJSON()` 才会带上(fabric v7 的 customProperties 机制)。 */ FabricObject.customProperties = ["layerId", "layerName", "layerLocked", "isBackground", "shapeKind"];