【踩坑日记 · 前端】为 Excalidraw 添加中文手写字体

news2025/7/28 3:13:49

前言

Excalidraw 是一款完全免费的手绘风格绘图在线应用,能快速画出漂亮的流程图、示意图和图表,地址: Excalidraw | Hand-drawn look & feel • Collaborative • Secure

在这里插入图片描述
请添加图片描述

但美中不足的是,Excalidraw 只支持英文手写字体,好在 Excalidraw 是开源软件,我们可以通过修改代码为其添加中文手写字体。

中文手写字体

在这里向大家推荐几款好看的中文手写字体,我个人比较喜欢 沐瑶软笔手写体,下面就以这款字体为例,演示如何为 Excalidraw 添加中文手写字体。

  • 字语青梅硬笔(商用需付费)

    • (
  • 沐瑶软笔手写体(免费商用)

    • 在这里插入图片描述
  • 沐瑶随心手写体(免费商用)

    • 在这里插入图片描述

步骤

1. 下载源代码和中文字体

下载 Excalidraw 源代码 到本地并解压,或者直接使用 Git 克隆项目:

git clone https://github.com/excalidraw/excalidraw

下载中文手写体,并将其复制到 public 目录下:

在这里插入图片描述

注意:字体名不能含有中文或其他特殊符号,建议将字体名重命名为纯英文。在这里我选择的字体是 沐瑶软笔手写体,并重命名为 Muyao.ttf后续代码中的字体名一定要保持一致。

2. 注册字体

编辑 public/font.css,添加文手写体:

@font-face {
  font-family: "Muyao";
  src: url("Muyao.ttf");
  font-display: swap;
}

添加完成后代码如下:

在这里插入图片描述

编辑 src/index-node.ts,添加下列代码注册中文手写字体:

registerFont("./public/Muyao.ttf", { family: "Muyao" });

添加完成后代码如下:

在这里插入图片描述

3. 预加载字体资源

编辑 public/index.html,在其中加入字体预加载代码,可以提高应用启动时的速度:

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

添加完成后代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TE4l615i-1668768518048)(_imgs/image-20221118182429809.png)]

4. 增加字体枚举

编辑 public/constant.ts,在 FONT_FAMILY 常量中加入字体的枚举:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44WjGvMC-1668768518049)(_imgs/image-20221118182649625.png)]

5. 添加字体切换按钮

最后,编辑 /src/actions/actionProperties.tsx,在 PanelComponent 的返回值数组中加入下列元素:

{
    value: FONT_FAMILY.Muyao,
    text: t("labels.handDrawn"),
    icon: FreedrawIcon,
}

添加完成后代码如下:

在这里插入图片描述

部署测试

进入 excalidraw 源代码目录,在终端中执行下列代码:

# 安装依赖包
yarn

# 启动应用
yarn start

在这里插入图片描述

出现上面的输出代表应用启动成功,用浏览器访问 http://localhost:3000

在这里插入图片描述

在左侧的面板中可以看到刚才添加的手写字体,选择即可切换。

参考资料

[1] Excalidraw - 免费的手绘风格白板应用 - 知乎

[2] 送给大家的免费字体:沐瑶软笔手写体_春颜秋色-站酷ZCOOL

[3] 送给大家的字体2:沐瑶随心手写体_春颜秋色-站酷ZCOOL

[4] 字语青梅硬笔字体免费下载和在线预览-字体天下

[5] GitHub - excalidraw/excalidraw: Virtual whiteboard for sketching hand-drawn like diagrams

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计爱行无忧旅游票务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

一文搞定,JMeter的三种参数化方式

1、Test Plan 中添加变量 可以在 Test Plan 中设置好添加变量&#xff0c;变量名可以在任意的位置使用&#xff0c;比如说在线程组中直接用${ 变量名 }方式引用&#xff0c;步骤如下&#xff1a; 1&#xff09;设置变量名和变量值 2&#xff09;添加线程组 3&#xff09;添…

记一场vue面试

Vue 修饰符有哪些 事件修饰符 .stop 阻止事件继续传播.prevent 阻止标签默认行为.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理&#xff0c;然后才交由内部元素进行处理.self 只当在 event.target 是当前元素自身时触发处理函数.once 事件将只会触发一次.pass…

AcWing 数据结构

单链表 邻接表用的多 存储树和图 new()速度慢 数组模拟 模板 -1代表头节点 const int N 1e6 5; // head存储链表头 //e[]存储节点的值 //ne[]存储节点的next指针 //idx表示当前用到了哪个节点 int head, e[N], ne[N], idx;// 初始化 void init() {head -1;idx 0; }// 将…

皕杰报表之控件元素

在皕杰报表中&#xff0c;填报操作时&#xff0c;控件类型分为无输入控件、文本框、文本域、下拉框、下拉树、单选框、复选框、日期、时间、日期时间、自定义控件类型。如图所示&#xff1a; 1 无输入控件 选中此控件的单元格在页面生成无任何变化&#xff1b; 2 文本框 选中…

加拿大海运专线怎么选?加拿大海运专线有哪些费用

由于全球经济的发展&#xff0c;近年来&#xff0c;越来越多的国内跨境电商卖家向加拿大和、墨西哥、欧洲、美国等出口货物&#xff0c;而海运的运输方式相对比较划算。那么加拿大海运专线怎么选?又有哪些费用呢?一、加拿大海运专线怎么选 加拿大海运专线运输方式有整柜运输和…

Linux-----网络套接字编程

文章目录铺垫一下概念知识基于UDP协议下的套接字编程基于TCP协议下的套接字编程铺垫一下概念知识 我们知道IP地址是用来标识主机唯一性的。 而源IP地址表示从哪个主机来&#xff0c; 目的IP地址表示去哪个主机。 端口号&#xff08;port&#xff09;&#xff1a; 1&#xff0…

C++之继承、派生

目录 1.继承的概念与定义 2.层次概念是计算机的重要概念: 3.私有的能被继承&#xff0c;不能被访问 4.继承的三步骤 1.继承语法 2.继承例子 5.有继承和组合的构造顺序---内存布局 6.继承之下的赋值运算符重载 1.基础知识 2.Person、Student例子 7.一个类被多个类继承 …

22.11.18打卡 [传智杯 #3 初赛] 部分题

森林图论懒得写, 等搞完dp之后再来复习图论, 还有一题数据有问题没写 [传智杯 #3 初赛] 课程报名 - 洛谷 哇真的签到, 第一眼还想着推公式呢, 看这数据范围直接暴力了 /* ⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿…

LiveGBS/LiveNVR组合实现GB35114平台端和GB35114设备端的GB35114的交互流程

概述&#xff1a; GB35114是在GB28181基础上扩展而来&#xff0c;增加了身份认证和数据加密。LiveNVR设备通过GB35114注册到LiveGBS时&#xff0c;LiveGBS平台端需要校验LiveNVR设备的身份&#xff0c;这是单向认证。同时可选LiveNVR也检验LiveGBS平台的身份&#xff0c;如果互…

[Howto] Pytorch Window GPU 环境配置

注&#xff1a; how to 系列只有基本的操作&#xff0c;不涉及原理&#xff0c;类似于操作手册。 Linux&#xff0c;MacOS和Window配置方法差不多&#xff0c;就是环境变量的修改方式不太一样&#xff0c;就不单独说明了。 1. 确定Pytorch版本 估计像我一样的初学者&#xf…

关于commonjs、AMD、UMD、ESM以及ts模块之间的使用差异

commonjs 特点&#xff1a;一个文件就是一个模块&#xff0c;拥有独立的作用域&#xff0c;适用于服务端不适合浏览器端。导出模块内部数据通过module.exports或exports对象默认导出&#xff1a; // true const a 1 const b 2 module.exports {a, b }或者 // true const …

【跨境电商卖家】Instagram营销初学者指南(二):方法与技巧

关键词&#xff1a;跨境电商卖家、instagram营销 1.为 Instagram营销设定目标 在你开始在 Instagram 上发帖之前&#xff0c;问问你自己&#xff08;或你的团队&#xff09;一件事&#xff1a;你为什么在 Instagram 上&#xff1f;尽管该平台很受欢迎&#xff0c;但您的回答不…

linux笔记(6):东山哪吒D1H显示HDMI测试-命令行调试

文章目录1.测试流程和结果2.测试过程详解2.1 挂载测试工具1.2 设置参数1.2.1设置name1.2.2选择命令1.2.3 设置命令参数1.3开启显示3.还没搞清楚怎么在应用中显示字符测试开发板的HDMI输出。 参考文档&#xff1a;全志官方文档。 1.测试流程和结果 测试结果&#xff1a; 2.测…

如何实现一键全选

利用复选框的激活、非激活实现一键全选功能 效果展示 前置准备 投票列表素材 具体步骤 添加素材 制作列表复选框 制作一件全选按钮 创建复选框相关行为触发器 制作一键全选触发器 步骤分解 添加素材 拖拽 图片组件 到 根容器 选中 图片组件 铺满父级容器 点击 检查面板 中的 …

一种新的群体智能优化算法:麻雀搜索算法(SSA)(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

C++中函数调用的整个过程内存堆栈分配详解

函数调用过程中&#xff1a;实参将值拷贝给函数的形参&#xff0c;而函数的形参相当于一个生存周期位于函数 内部的局部变量&#xff0c;函数内部的内存操作也只是将拷贝到形参的值进行操作&#xff0c;形参在函数结束 后会被栈自动回收释放(形参在栈中分配)&#xff0c;这就是…

Spring Security如何防止会话固定攻击

在春季安全课程的这篇文章中&#xff0c;我们将研究春季安全会话固定以及如何防止春季应用程序中的会话劫持。 春季安全会话固定 会话固定是一种非常常见且最常见的攻击类型&#xff0c;恶意攻击者可以通过访问站点来创建会话&#xff0c;然后诱使其他用户使用相同的会话登录…

副业是刚需?分享几个程序员接外包私活的网站

经常看到某某程序员接了个项目开发&#xff0c;工作之余轻轻松松赚了钱还顺带提升了技术&#xff1b;或者看到某大佬又发表了一篇程序员技术提升稿件&#xff0c;阅读点赞收藏三连发&#xff0c;这个月的零花钱又不愁了...但自己只是一名普普通通的程序员&#xff0c;能找到这样…

Golang入门笔记(10)—— 闭包 closure

先看一段代码&#xff0c;脱离代码讲闭包&#xff0c;太干了。 package mainimport "fmt"func main() {a : Adder()fmt.Println(a(1))fmt.Println(a(2))fmt.Println(a(3)) }func Adder() func(int) int { // 累加器&#xff1a;这里从10开始累加var sum int 10retu…