feat: 骨架——Vite + Vue3 + Fabric v7,左工作区右侧栏

共享外壳与类型契约,四条并行开发线在此之上各自填空:
- types.ts 是唯一的跨线接口,并行期间冻结
- editor/ 画布单例、选中态、尺寸预设与比例锁
- Sidebar 按选中对象切换面板,五个面板位已接好
- fonts/ filters/ sources/ io/ 留桩,各线只改自己目录

导出定 WebP:实测 540x287 PNG 134KB vs 1200x630 WebP 23KB。
字体接口挂在 Vite 中间件上,工具只在 dev 下完整可用。
This commit is contained in:
Jz0ojiang
2026-09-04 15:42:27 +08:00
commit 95eeb69ff8
26 changed files with 1390 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
import { ref } from "vue";
import type { FontEntry } from "@/types";
/**
* 【T2 待实现 — 字体子系统】
*
* 前端这一半:向 `/__fonts` 取列表,选中某款时向 `/__fonts/:id` 取文件,
* 用 `FontFace` API 动态挂载到 `document.fonts`,之后 Fabric 的 Textbox 就能用
* `fontFamily: entry.family` 渲染。
*
* 注意 Fabric 在字体真正 ready 之前渲染会退到 fallback 字形,
* 挂载后要 `await document.fonts.load(...)` 再 `canvas.requestRenderAll()`。
*/
export const fonts = ref<FontEntry[]>([]);
export const loadingFonts = ref(false);
export async function listFonts(): Promise<FontEntry[]> {
throw new Error("T2 未实现:listFonts");
}
export async function ensureFontLoaded(_entry: FontEntry): Promise<void> {
throw new Error("T2 未实现:ensureFontLoaded");
}
+28
View File
@@ -0,0 +1,28 @@
import type { Plugin } from "vite";
/**
* 【T2 待实现 — 字体子系统】
*
* Vite 开发服务器中间件,给前端提供本机安装的字体。两个接口:
*
* GET /__fonts -> FontListResponse(见 src/types.ts)
* GET /__fonts/:id -> 字体文件二进制,Content-Type 按 ext 给
*
* 枚举来源是 Windows 注册表的两个键(本机实测共 651 条):
* HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts 系统字体,值是文件名,目录 C:\Windows\Fonts
* HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts 用户字体,值多为绝对路径
*
* 注意 `.ttc` 是合集包(如 msyh.ttc 里有微软雅黑的多个 face),浏览器不能直接当 webfont 用,
* 需要抽出单个 face 再返回;`FontEntry.needsExtraction` 标记这种情况。
*
* 只在 `apply: "serve"` 下生效,构建产物里不存在这两个接口。
*/
export function fontsPlugin(): Plugin {
return {
name: "cover-studio:fonts",
apply: "serve",
configureServer() {
// T2 在这里挂 server.middlewares.use(...)
},
};
}