likes
comments
collection
share

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

作者站长头像
站长
· 阅读数 22

使用excalidraw搭建自己的中文手写画板

成品预览地址guizimo.github.io/excalidraw/

excalidraw提供了英文的手写体,但中文还是正正方方的,感觉不搭。希望中文也可以有那样一种手写风格。

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

本文使用的是excalidraw,它是一个十分优秀的开源项目,地址:github.com/excalidraw/…

1、创建项目

1.1、拉取代码

首先在excalidrawGithub主页Fork一份代码到自己的账户下

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

Fork之后,clone到本地

  git clone git@github.com:guizimo/excalidraw.git

然后在这里,签出一个新的分支:zh-dev,这个分支用来提交我们自定义的提交和变动,在后续如果excalidraw更新后,可以合并主干,得到最新的特性。

1.2、运行

尝试本地运行

 // 安装依赖
 yarn install
 // 运行
 yarn run start

在浏览器中打开http://localhost:3000/,发现已经可以正常运行了

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

2、下载中文字体

选择一款你看的舒服的中文手写字体,当然这里你喜欢其他的字体也可。需要注意的是字体的版权问题哈。笔者在选择中文字体的时候发现了一个网站:猫啃网,大家有空可以自己去了解哈。

我这边选择的是平方雨桐体,在这里感谢作者提供那么好的字体!

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

下载好中文字体包,并重命名为 Yutong.ttf

3、加入中文字体

到这一步了需要手动调整代码了,因为不同的版本,代码会有一些调整。目前的excalidraw使用了monorepo来管理项目了。

这里提供一种思路,观察其中的一个内置的字体,通过断点调试了解它的加载流程,按照它的思路,添加我们自定义的字体即可。

3.1、放置字体资源

将我们之前下载好的字体文件 Yutong.ttf放置到 packages/excalidraw/fonts/assetspublic目录下。

3.2、注册字体

编辑 packages/excalidraw/fonts/assets/fonts.css,添加中文手写体Yutong

 @font-face {
   font-family: "Yutong";
   src: url(./Yutong.ttf) format("truetype");
   style: normal;
   display: swap;
 }

编辑packages/excalidraw/index-node.ts添加registerFont

 registerFont("./public/Virgil.woff2", { family: "Virgil" });
 registerFont("./public/Yutong.ff2", { family: "Yutong" });
 registerFont("./public/Cascadia.woff2", { family: "Cascadia" });

3.3、预加载字体资源

编辑excalidraw-app/index.html,添加一个link

 <link
    rel="preload"
    href="../packages/excalidraw/fonts/assets/Yutong.ttf"
    as="font"
    type="font/ttf"
    crossorigin="anonymous"
 />

编辑scripts/woff2/woff2-vite-plugins.js,添加一个link

 <link
   rel="preload"
   href="/Yutong.ttf"
   as="font"
   type="font/ttf"
   crossorigin="anonymous"
 />

编辑 packages/excalidraw/constants.ts,在 FONT_FAMILY 常量中加入字体的枚举。

这里可以把枚举的数字设置大一点,防止后续更新新加了字体,导致冲突。

 export const FONT_FAMILY = {
   Virgil: 1,
   Helvetica: 2,
   Cascadia: 3,
   // leave 4 unused as it was historically used for Assistant (which we don't use anymore) or custom font (Obsidian)
   Excalifont: 5,
   Nunito: 6,
   "Lilita One": 7,
   "Comic Shanns": 8,
   "Liberation Sans": 9,
   Yutong: 999
 }

编辑packages/excalidraw/components/FontPicker/FontPicker.tsx,在列表中添加切换按钮。

这里懒得去添加图标和枚举了,我把Nunito的位置给占了哈,不像我这边懒的人可以去加上图标哈。

   {
     value: FONT_FAMILY.Yutong,
     icon: FontFamilyNormalIcon,
     text: t("labels.normal"),
     testId: "font-family-yutong",
   },
   // {
   //   value: FONT_FAMILY.Nunito,
   //   icon: FontFamilyNormalIcon,
   //   text: t("labels.normal"),
   //   testId: "font-family-normal",
   // },

编辑packages/excalidraw/fonts/index.ts添加_register

import Yutong from "./assets/Yutong.ttf";

......
_register("Yutong", FONT_METADATA[FONT_FAMILY.Excalifont], {
  uri: Yutong,
});

再次运行起来,那么在使用字体的第二项的时候,已经可以正常使用我们刚添加的中文手写字体了。

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

4、部署

在本地已经可以正常使用了,为了更加方便使用,这边直接选择使用Github Page部署。可以借助gh-pages来实现。

gh-pages的原理

就是创建一个gh-pages的分支,将选中的已经构建好的资源文件,放入该分支,然后推送到远程的Github仓库,Github识别到gh-pages的分支有更新,会生成一个deploy,通过该链接就可以正常访问了。

4.1、安装依赖

yarn add -D gh-pages

修改package.json文件,添加deploy脚本。

"scripts": {
  ......,
  "deploy": "gh-pages -d excalidraw-app/build"
}

4.2、调整配置

注意:目前笔者是使用二级部署的,即部署之后访问的链接形式是:https://xxx.com/xxx/excalidraw,需要调整打包之后的资源引用路径。

编辑excalidraw-app/vite.config.mts,使用相对路径base: './'

export default defineConfig({
  ......,
  base: './', // 使用相对路径
  ......,
})

4.3、构建部署

首先打包成为静态资源

yarn run build

部署

yarn run deploy

执行之后,在远程仓库中,会自动创建github-pages deployments

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

这里会给到一个链接:guizimo.github.io/excalidraw/

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

打开链接就可以看到成功部署的中文手写版excalidraw了。

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

编辑Github主页配置。

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

4.4、踩坑

部署成功之后,自己添加的字体无法正常显示。

报错信息

DOMException: The source provided ('url(https://guizimo.github.io/excalidraw/assets/Yutong-BrR4G41P.ttf) format('ttf')') could not be parsed as a value list.

发现format('ttf')并不是一个合法的格式。但是搜索整个代码,并未声明format('ttf')这样的一种格式。

通过断点调试找到了在packages/excalidraw/fonts/ExcalidrawFont.tsgetFormat方法中,会将字体文件的后缀名作为format,导致浏览器加载不上我们添加的ttf格式字体。

改造getFormat

ttf对应的格式为:truetype

private static getFormat(url: URL) {
  try {
    const pathname = new URL(url).pathname;
    const parts = pathname.split(".");

    if (parts.length === 1) {
      return "";
    }
    // ttf is not a valid format, so we are converting it to truetype
    let type = parts.pop()
    if (type === 'ttf') {
      type = 'truetype'
    }
    return `format('${type}')`;
  } catch (error) {
    return "";
  }
}

各种字体对应的格式

  • format('truetype') :用于指定 TrueType 字体(.ttf 文件)的格式。
  • format('woff') :用于指定 Web Open Font Format 字体(.woff 文件)的格式。
  • format('woff2') :用于指定 Web Open Font Format 2 字体(.woff2 文件)的格式。
  • format('opentype') :用于指定 OpenType 字体(.otf 文件)的格式。

重新构建部署,自定义的字体已经生效!

使用excalidraw搭建自己的中文手写画板本文介绍了如何基于开源项目 Excalidraw 搭建一个支持中文手写字体

转载自:https://juejin.cn/post/7404780384539918388
评论
请登录