跳到主要内容

灵感库

· 阅读需 3 分钟

画家的原始资本积累

我今天整理家里的书柜,扫出了12本速写本,原来我这几年画了这么多(扶额)。还有一个裁切a4纸上作画的碎片小纸盒。

这些都是小a5规格,八开往上的还有约莫五六本,我还没整理和翻动。
我粗略看了下,一本大概100页,12本,a5尺寸,双面2400面。大概有75平方,一个客厅的面积🤯。我原来还挺厉害的。

(还挺感慨的,扫描或者拍照就能在电脑加工使用了,有很多种变化玩法)

里面当然不都是好东西,但是那些烂的反而更喜欢。都是非常好的素材库,我称为发酵。也算是时间复利啦。

我现在要找灵感的时候就翻一番,在原素材上面直接改,或者拼贴,又是新的。关键是,不存在侵权!都是我的。
这是我随手选的几张,我才翻了三本,就拍了一百多张😂。

(能看出这是Bill Evans的某个封面的构图彩蛋吗?)

(偶尔能画出这种很酷的东西,不过并不经常。)

可不只有所谓好图哦,也有这种普通人觉得很怪,但是超好玩的风格的。

所以不要焦虑创作,别怀疑怀疑自己了。而且妥善保管自己的内容,别扔掉,特别是你当时以为的垃圾,不知道那天就会变成你极为宝贵的核心资产。1

我画插图的过程

我通常会先在a4纸或者速写本用0.7的签字笔画速写稿,如果不复杂的话,通常就是直接不打草稿一次成型了。 (不打草稿不是什么值得炫耀的事情,只是同类型东西画太多而已,事实上画新东西或者做前期设计是要画无数草稿的)

然后拍照(我暂时没有用扫描仪或打印机),转成提取黑白稿的时候,那些不闭合的线条会形成很有趣味的留白,美术黑话叫做“气口”。

主页看板娘陈谷累的新插图草稿,直接就是线稿了。)

但是进入PS或者Krita存在一个很烦人的问题。 线条不闭合,导致魔棒工具无法选区上色,增加了很多工作量。

不做二分,层次太多会稀释线条的表现力,而且简简单单画起来没负担。
简单分配一下色块,然后整体用上杂色滤镜就能模拟出纸张印刷一样的肌理感,通常会比web风格的插图更耐看。

缺点就是会让图变很大,原图png有16mb,压缩成了webp后是1mb,稍微变模糊没那么精神,不过能接受。
(最后完成是这样,我就喜欢简简单单的滴胶画填色。)


Footnotes

  1. 小小的Q&A😊
    可能你会说,骗人!你画得很好啦,不要扮猪吃老虎啦。
    其实并非如此,关键是在主观认知上,某个时期我觉得我的东西根本没法拿出去给人看,扔垃圾桶也无所谓。
    我的建议是别想这个问题,留着。现在看来,我画得很不错。

我的Krita初体验

· 阅读需 2 分钟

不是Krita的部分

我也开始尝试用Krita了,我之前是深度的PSProcreate用户,图片处理和排版还是需要用到PS,涉及高精度描线稿的情况Krita还是比不过ProcreateCSP

其他工具还会用 hp4,其实在浏览器就能用,笔刷也很好,不过不知道下载本地几次后,要登录才能下载。就再见了👋。

(HP4的web体验很好,而且它的笔刷用鼠标画起来很舒服,问题是它现在也大便化💩)

webchemy,目前还行,我用来罗夏图。风格实验什么的。

用Krita,扔掉盗版PS吧🤷‍♀️

Krita是个开源软件,而且各方面都不错,当然要鼎力推荐,不要抱着那个盗版PS了,我知道还是很多人用的。换Krita吧。

Krita的预设画笔🖌️其实体验下来都很不错,有我特别喜欢的洇墨签字笔。
干粉笔和油画笔其实也不错,不过油画笔的预设压感不太符合我手感,需要调整,中途手感上有不习惯,导致我下意识就拿起鼠标画,反而更顺手。
又来了🙄,用笔划玻璃是世界上最蠢的设计,什么时候能进化回纸张。

所以我也没打算画一些有造型的内容了,刷几下体验笔刷,然后圈一圈,命名为【火男】,也挺应景。

是不是很艺术?乱画的。

超廉价咖啡

· 阅读需 5 分钟

休息时间随机了一下同乐会的文章,看到neil的咖啡小知识,突然回想到,哦~我好想也挺爱喝咖啡的。毕竟我也算是开过咖啡店的人,虽然倒闭了。

原文珠玉在前,介绍了那些tds之类的很专业的参数。
我曾经也很沉迷啦,不过我现在通常是这样喝咖啡:

手冲咖啡的部分☕️

研磨

我已经不用咖啡磨豆机了(太贵了),而是直接用家用磨粉机只要30¥一台,还能兼顾其他香料磨粉。 串味?我试验过,串味有,但是很微弱,感觉对我影响不大,单独管理一个研磨的感情成本更高。现在不需要管理,无脑扔下去,很爽,关键是只需要30¥。
不均匀?我能接受。

(两勺刚好18克上下,正好是1:15一杯的分量)

超廉价冲煮

用一个v60滤杯(其实只要有个洞就行啦,v60还是有点智商税的)+滤纸。
水壶冲水(就是普通的热水壶,控温板普遍是默认90℃的),细嘴壶手感更好,但是我家的是没带加热的,所以也懒得用。

重点推荐的是装咖啡粉的码兜,304不锈钢,1.5¥一个,耐摔好清洗,刚好是一份。而且是经典厨房泛用组件。

粉水比

原则上推荐的是1:15,也就是20克粉:300克咖啡液体。我都是在1:12-1:18直接看心情👀
实际情况则是,刚好一杯。别管。
水温原则上推荐90℃,也别管。刚跳闸就倒水就行了。
萃取时间⌚️?不考虑。

这样一轮下来,你就得到了一杯毫无感情负担的好喝咖啡。
因为咖啡好喝不好喝,决定性因素其实是咖啡豆和水质(水质用矿泉水就行啦,我平常是不管的。)

更懒的方式(只适合浅烘焙咖啡豆)

把咖啡粉研磨后用冷泡法,泡12-24小时,也就是一晚上。过滤咖啡粉,或者懒的话就用嘴过滤。风味萃取更多更稳定,更好喝。但是会有更多咖啡因被溶解。

另外可以过滤后放冰箱冷冻二次发酵,或者改用冰滴法(闲人玩具,区别不大)。原则上3-5天,会变成有复杂发酵和酒香的咖啡。

⚠️不要存放超过一周,会拉肚子。

冲煮完的咖啡粉别扔掉

咖啡粉可以烘干,我是直接扔到平底锅上面热。烘干后的咖啡粉收集起来,可以作为厨房调料,为肉类增加复杂厚重的烘焙香气

废弃香料

或者制作香囊、干燥剂、泥土肥料。

关于咖啡豆

如果是几年前,我会告诉你要精品咖啡,严选产地,具体产区说一大堆。
不过现在呢,去找你们本地的烘焙商,让他们推荐,实惠就买,不好喝就换一家。产地,哪种豆让他们推荐,你只管享受。

不过大致也可以说说不同地方的风味偏好: 非洲- 代表是 埃塞俄比亚的耶加雪啡(原生种,经典的花香)、肯尼亚(非常酸,跟新鲜水果差不多)

亚洲- 云南、台湾、爪哇苏门答那,草药泥土和偏向茶叶的气味。java有非常奇特的小产区金java,不过另说。

拉丁美州-地方太多,代表是geisha瑰夏(有不那么贵的,其实还是很贵)。我推荐哥伦比亚-图利马Colombia-Tolima产区的瑰夏(是个火山🌋),相对不贵,质量不错(暂时的)。

ps:为什么没有欧洲和北美?那个地方不产咖啡!😂。


假装很高深其实并不高深的升华

说到底,就是别陷入消费主义里面了,咖啡只是一个饮品特色农产品,而且咖啡因并不健康。喝起来舒服,钱包不难受就好了。不要赋予太多文化符号,小资包装。

哦对了,如果居家?别买意式咖啡机,除非你爱玩成人玩具或者真的很爱喝卡布奇诺。


又追加-消费主义幽灵

如果你们还能找到,或者在本地可以试试这几个我很喜欢的品牌或单品

俄罗斯: 🫘 The Welder Catherine – Gold Java

墨尔本: ☕️ Wood and Co – Colombia Tolima

英国: hasbean现在改名叫Ozone Coffee了,不知道好不好喝。

广州: 太多太多了,分享不来。

以上好不好喝,稳定不稳定,我不知道,你们如果当地或者旅游顺路方便就去找找吧。但是别跨境,别费神,农产品生鲜食品,不值得。

怎么算是一个靠谱的人?

· 阅读需 2 分钟

ok,我知道大家一看到这个标题就要开始焦虑了,起码我是。 仿佛要被念咒施加挥之不去的传统道德和意识形态。
但我倒不是想落入那种站着说话不腰疼的成见与窠臼里面,起码本意不是。

(开始爹味起来了🥱)

所谓靠谱,我的定义

其实就很简单,有把握的事正常做,没把握的提前告知风险,但凡有一点风险都要告知,并且把责任厘清,是否执行或者对赌什么的。

虽然实话说,很多人其实是想把决策权外包,然后假装相信你能替他承担风险。这是不可能的。

为了避免陷入这种纠纷,我都会提前告知,不被捆绑决策权。 这会让一部分人觉得你没有担当,无法承担责任,或者说很冷漠。

但恰恰这才是最尊重他人的行为策略,因为这意味着相信每个人应该为自己负责。(抱歉,又爹味起来了🙉)

这不叫原子化

如果把这种思维顺势延伸,很容易就会被理解为各家自扫门前雪、只死道友不死贫道。

但当然没这么蠢。恰恰是每个人都认清楚责任与风险,才能更有效地理清个人无法面对的风险与议题,构建公共保障。
这明显是把所有人理想化成理性人了,现实往往很复杂,不然怎么会有这么多问题焦头烂额呢?

ai用得多爽?多费电?关我什么事?你们第三世界来承担代价就好啦🥱
新质生产力?劳务派遣,临时工?你们过劳死,跟我有什么关系。🔫
我说的

(就这样结束了?是的,因为我也没有答案,我也是粪海狂蛆。)

当然了,这个层面也只能尽人事听天命。
不要想太多,觉得这个太严肃就看点别的娱乐下吧。

美味非洲菜😋

· 阅读需 3 分钟

大家都说广州很多黑人,这是真的。不过我不打算参与那种无聊且小气的沙文主义、保守的种族主义叙事🥱。(我讨厌小肚鸡肠)

我要讲讲我吃过的两种非洲菜,西非和东非的,或许以后这个名录会增加。

芯翡州西非菜

我本来以为只有新和联胜新洋葱学术,居然还有新非洲(凭什么不呢?)1
说是西非菜,肉类都是油炸&烧烤🍖,吃起来充满野性。

肉类🍖

我们点的[拼盘A]里面有这些东西。

西非特色拼盘
├── 烤羊肉(或许是炸的)
│ // 充满野性,有羊膻味,但我很爱吃🥳
├── 炸罗非鱼
│ // 骨头都是脆的!爱吃炸鱼皮吗?你一定会喜欢的
├── 烤鸡腿
│ // 这个就比较普通了,肉质不错,但味道一般
└── 三种西非特色主食
│ ├── fufu(香蕉糯米团)
│ ├── gari(木薯团,带发酵酸味,绝大多数人吃不惯)
│ └── ugali(玉米面团,没什么味道,口感跟fufu一样偏软)
├── 羊肉汤
│ // 说是羊肉,其实基本上是羊肚。
├── 瓜子酱
│ // 黄色那碟就是。
├── 秋葵酱
│ // 最左边那碟。

羊肉汤light soup

说是羊肉,我看到基本上是羊肚。而且居然叫light soup💡,看起来红红的,油光粼粼,确实挺亮。
里面有打融的番茄🍅,味道很好喝,但是还是有一些羊杂脏器的味道,我要是吃一碗就不能吃别的了。估计很多人接受不了内脏的气味。

light soup

⚠️注意: 可能下了一些棕榈油,油含量不少,也或者是全部食物吃完比较油腻(吃的时候完全不觉得),我第二天去了很多次洗手间。

瓜子酱Egusi(大概是这个名字)

“Egusi”指的是几种西非和中非本土瓜类植物的种子。这些瓜的外形像西瓜,但果肉发苦,所以当地人不吃果肉,只取瓜子食用。⬅️ai说的

其实我一开始吃以为是鸡蛋🥚混合高汤做的,
后来觉得鸡蛋应该没有这种小点点呀,应该是鱼籽吧。
结果都不是,是瓜子,而且里面有一些类似昆布的条条,还有小鱼干,不知道是不是鳀鱼🐟️。

总体是很鲜美,很谷氨酸钠的。
egusi

秋葵酱

我不爱吃!像是鼻涕或者纳豆,会拉丝。味道也不好。烤秋葵其实很好吃,但是煮过做成酱,这种暗黄色就很糟糕。

(最左边那个,我懒得弄图片了)

油炸罗非鱼和香蕉🐟️

炸香蕉意外的好吃,咸甜混动。越吃越上瘾,而且不会油腻。 油炸罗非鱼

(待续)


Footnotes

  1. 我觉得取名[芯翡州]很大概率是工商局不允许用国家名[新非洲]。

是时候讲讲PogoShop的故事了

· 阅读需 6 分钟
這是我的「BlogBlog 同樂會 – 2026 年 8 月」的投稿文章。本月主題是「一期一會」,由 ikuka 主持。如果你有自己的部落格,歡迎一起來參加!

在2019年的时候我与[佩奇🐷]合伙开了一家小店,做咖啡馆☕️,慢慢想发展成空间和厂牌(你看,又是多么小资产阶级的幻想😜)。 小本经营,每人投了两万(我的钱是借的,真是蠢爆了),装修了一个月,开门营业,名字叫做POGOPogoShop

当然也有因为工商注册需要中文名而衍生的一些好笑的诨名,比如波哥娱乐,博歌棋牌。
(又俗又雅,不是真的,土到我都受不了😄)

🎰 波哥娱乐城,性感荷官在线发牌 🎰 波哥娱乐城,性感荷官在线发牌 🎰 波哥娱乐城,性感荷官在线发牌


还是看看我们正经的logo吧👀

logo

开店的故事

选址就在海珠区房产登记局的隔壁,挨着藤木琴行(现在两个店都是遗址了😄),早上开店,晚上收摊去琴行合奏乐队🪗,我们吉他手也租住在pogo的二楼,方便得不可思议。

地图

装修

在我们接手之前,是很旧的房子,佩奇妈妈楼上装修,顺便施工队一起做了,所以收得相对便宜,40平方,好像一共花了两万。

设计是好兄弟yelor做的,没收我一分钱,设计规划、图纸、建模,全包了。哪怕后来的软装,宣传都有参与,给指导。虽然店后来倒闭了,不过我是非常感激的😇。

(我们可是一起熬夜改方案,煮过面的交情,你试过两个男人熬夜一起吃方便面吗😵?)

最后装修完就是这个样子,老实说比我现在住的家漂亮多了(这钱如果不开店就是拿来装修的不过拿来试错,买了个教训经验也不是不行👋)。

(我暂时没找到白天的外墙照片,只能用夜晚狐朋狗友的一面了)

外面的部分

里面的部分

正式营业!

开始的三个月

第一个月收入还不错哦,平帐了,甚至还赚了50¥。不过有一些是亲戚朋友捧场,算下来其实不理想。 所以收入曲线就是这么一个形状 第一个月峰值,然后下降(我看看能不能找到统计图,补充:没找到)

圣诞颂歌🎄

一个圣诞节我们还录制R&B风格的即兴圣诞歌。
完整的视频被我误删了,或许yelor那里还有备份,总之我得找找,现在只找到当时的预告片。
已经找到了,这是当时的视频。

yelor帮忙拍摄和录制,[阿周chow(堆填区乐队的吉他手)]帮忙混音和演奏吉他部分🎸,所以一路下来真的得到很多人的帮助🙏。

那时候我还挺胖的,疫情过后有一段抑郁时期更胖,不过现在又没那么胖了。

疫情来了😷

新冠covid来的时候,一开始大家其实没当回事。对于经历过2003年萨斯疫情的人反而很谨慎,我们这些小孩其实并无感。

游戏时光🎮

大概开店后的第四个月,全世界都渐渐水深火热的时候,我们无所事事地在店里打游戏,ps4和switch。 黑暗之魂3、塞尔达-荒野之息(野炊)、大乱斗,还有其他。

反正没法工作,全面停摆,不如放心娱乐。
现在回想起来,其实很是逍遥的,全世界都允许你暂停,没有人用绩效主义push你,当然也不会自我push。

朋友们

在开店的过程也认识了很多的客人、朋友、合作伙伴。

客人

虽说是客人,但是也一起疯一起玩,联系很深。 比如小白、阿星、peper、拖地、赵医师,其他的我记不起名字了。 (他们的故事我或许以后会写,截止现在没什么力气写,暂作罢✍️)

维乐家welove

王sir,496,维乐家创始人。 我的亦师亦友的好朋友,给我供货,教我音乐,开我眼界。一次次地想帮我推广,奈何我当时缺乏跟人协作的经验与教养,没有接收到。

伟仔,现在好像转行做焊武帝(电工视频up主,不知道有没有youtube)了,主要的供货与协调都是他帮忙跟进执行,真的感激谢谢。

面包房

阿牛🐮、阿政、陈大哥,三人拍档在我们店后面工业园租了一个面包工作室🥖,专门烘焙超好吃的欧包,因为离我们店只有300米,所有面包一出炉马上送样品给我试吃一起品尝,这是我这辈子吃过最好吃的面包。毕竟面包好吃的第一要义,越新鲜越好吃。 面包 我记得疫情前还组织过一次品尝会,腐乳牛肉披萨🍕,终身难忘。(是的,能做好面包就能做好披萨,毕竟是面团发酵大师)

奶茶店(暂不写)


或许这能牵强附会地说算是「一期一會」,也可以很假学术的称为个人史写作✏️,太多东西可以写了,写到脱力。暂止于此。

小恐龙艺廊包🐔

· 阅读需 2 分钟

我把我现在的 Docusaurus 项目,简化成了一个画廊模板包,叫 小恐龙艺廊包

小恐龙艺廊包!你的docusaurus宝宝辅食😊!

你应该有一个自己的数字根据地,快行动起来吧!

其实就是给视觉艺术家们用的一个小工具。里面有画廊页面、字体切换,Mermaid 图表也提前开好了——当然,当然MDX 还能插音乐,不过不是这次的重点。

不过考虑到宝宝向用户,我只保留了画廊页面,其他功能没动。用熟了喜欢了,你大可以自己改。现在有 AI 帮忙,改前端真的超级方便,别怕。

快行动起来吧。😄


功能

  • 🖼️ 画廊页面(我做的!)/sketch 路径下自动展示分类图片
  • 🔤 字体切换(这个也是我做的!):右上角一键切换系统 / 像素字体
  • 📊 Mermaid 图表:已预置,支持流程图、时序图等
  • 🎵 MDX 支持(本来就支持啦!):可插音乐、视频、互动组件

(项目包内附详细使用说明,安装完node.js后,点击项目包的本地渲染.bat全在里面👀。)

使用方式

  1. 解压项目包
  2. 安装 Node.js(我把安装包都准备好了!就在项目根目录里,双击安装就行,一路“下一步”)
  3. 运行依赖安装.bat,linux/mac用户在终端运行npm install
  4. 把图片放进 static/sketch/你的分类名/
  5. 双击 图片抓取.bat 生成索引
  6. 双击 本地渲染.bat 运行项目

下载

📦 下载小恐龙艺廊包

EX.

©️版权- Docusaurus 采用的是 MIT 许可证,随便用啦。

我的增加部分(如配置、样式、脚本及文档)则是随便用,不用问我。
当然,如果你觉得有用,愿意提一下「小恐龙艺廊包 · 顾游Gize_Ku」就更好了,我会很感激的。😊


有问题可以联系我 📮 gizeku@outlook.com
也欢迎常来 小花园🌻 看看。

追加新功能字体切换②

· 阅读需 7 分钟

复盘一下技术路径,方便自己以后查看,也方便大家在其他静态站生成器里面重写,如果是docusaurus则可以照搬。

设计的思路图在最下面,放前面一大块,我自己看得不爽👀。1

说是要兼容两个设备,好像很烦。其实在docusaurus里面挺好实现的,
涉及修改的文件路径目录

项目根目录/
├── src/
│ ├── css/
│ │ └── custom.css ← 修改:定义 @font-face、:root 变量、[data-theme-font] 规则
│ └── theme/
│ └── Root.js ← 新增/修改:注入导航栏按钮,处理所有交互逻辑
├── static/
│ └── fonts/ ← 放你自己需要的字体就行👍
│ ├── ZLabsPixel_12px_M_CN.ttf.woff2 ← 新增:像素字体文件
│ └── SmileySans-Oblique.otf.woff2 ← 新增:得意黑字体文件
└── docusaurus.config.js ← 无需修改(保持原样)
`custom.css`需要追加的内容
/* ============================================================
🎯 字体切换功能 · 可配置模板
============================================================ */

/* ---------- 1. 定义你的字体 ---------- */
/* 将你的字体文件放在 static/fonts/ 目录下,然后替换下方的名称和路径 */

@font-face {
font-family: '你的字体A名称'; /* ← 改这里 */
src: url('/fonts/你的字体A文件名.woff2') format('woff2'); /* ← 改这里 */
font-weight: normal;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: '你的字体B名称'; /* ← 改这里 */
src: url('/fonts/你的字体B文件名.woff2') format('woff2'); /* ← 改这里 */
font-weight: 400;
font-style: normal;
font-display: swap;
}

/* ---------- 2. 基础变量(默认系统字体) ---------- */
:root {
--ifm-font-family-base: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

/* ---------- 3. 切换方案(与 data-theme-font 配合) ---------- */
[data-theme-font='字体A-key'] { /* ← key 可自定义,与 JS 中对应 */
--ifm-font-family-base: '你的字体A名称', system-ui, sans-serif;
}

[data-theme-font='字体B-key'] { /* ← key 可自定义,与 JS 中对应 */
--ifm-font-family-base: '你的字体B名称', system-ui, sans-serif;
}

📄 字体切换 — Root.js
import React, { useEffect } from 'react';

function FontSwitcherButton() {
useEffect(() => {
// 等待导航栏渲染完成后,插入按钮
const insertButton = () => {
const navbar = document.querySelector('.navbar__items--right');
if (navbar && !document.querySelector('.font-switcher-btn')) {
// 读取当前字体偏好
const saved = localStorage.getItem('font-preference') || 'system';
const isCustom = saved !== 'system';

const btn = document.createElement('button');
btn.className = 'font-switcher-btn';
btn.style.cssText = `
background: none;
border: none;
cursor: pointer;
padding: 4px 6px;
display: inline-flex;
align-items: center;
justify-content: center;
opacity: 0.7;
transition: opacity 0.2s;
border-radius: 4px;
color: var(--ifm-navbar-link-color);
`;
btn.onmouseenter = () => btn.style.opacity = '1';
btn.onmouseleave = () => btn.style.opacity = '0.7';

// 渲染 SVG 滑块(isCustom: true=绿色右侧,false=灰色左侧)
const renderSVG = (custom) => {
return `
<svg width="34" height="20" viewBox="0 0 34 20" style="display:block;">
<rect
x="0" y="0" width="34" height="20" rx="10"
fill="${custom ? '#4CAF50' : '#ccc'}"
style="transition: fill 0.25s ease;"
/>
<circle
cx="${custom ? '25' : '9'}"
cy="10"
r="7"
fill="white"
style="transition: cx 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 1px 4px rgba(0,0,0,0.15);"
/>
</svg>
`;
};

btn.innerHTML = renderSVG(isCustom);
btn.title = isCustom ? '切换到系统字体' : '切换到自定义字体';

// 交互逻辑:左键切换 + 右键/长按/双击弹出菜单
let pressTimer = null;
let clickTimer = null;

// 动态获取字体列表
const getFontList = () => {
const fonts = [];
const seenKeys = new Set();
fonts.push({ key: 'system', label: '系统字体' });
seenKeys.add('system');

for (const sheet of document.styleSheets) {
try {
const rules = sheet.cssRules || sheet.rules;
if (!rules) continue;
for (const rule of rules) {
if (rule.selectorText && rule.selectorText.includes('[data-theme-font=')) {
const match = rule.selectorText.match(/\[data-theme-font="([^"]+)"\]/);
if (match && match[1]) {
const key = match[1];
if (seenKeys.has(key)) continue;
seenKeys.add(key);
const fontFamily = rule.style.getPropertyValue('--ifm-font-family-base');
let label = key;
if (fontFamily) {
const names = fontFamily.split(',').map(s => s.replace(/['"]/g, '').trim());
label = names[0] || key;
}
fonts.push({ key, label });
}
}
}
} catch (e) {
continue;
}
}
return fonts;
};

// 菜单功能
const showFontMenu = (x, y) => {
const existingMenu = document.querySelector('.font-switcher-menu');
if (existingMenu) existingMenu.remove();

const fonts = getFontList();
if (fonts.length === 0) {
fonts.push(
{ key: 'system', label: '系统字体' },
{ key: 'pixel', label: '像素字体' }
);
}

const menu = document.createElement('div');
menu.className = 'font-switcher-menu';
menu.style.cssText = `
position: fixed;
top: ${Math.min(y, window.innerHeight - 120)}px;
left: ${Math.min(x, window.innerWidth - 140)}px;
background: var(--ifm-background-surface-color, #fff);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
padding: 6px 0;
z-index: 9999;
min-width: 120px;
border: 1px solid var(--ifm-color-emphasis-200, #e0e0e0);
font-size: 0.9rem;
`;

const current = document.documentElement.getAttribute('data-theme-font') || 'system';

fonts.forEach((font) => {
const item = document.createElement('div');
item.textContent = font.label;
const isActive = font.key === current;
item.style.cssText = `
padding: 6px 16px;
cursor: pointer;
transition: background 0.15s;
color: var(--ifm-font-color-base, #333);
${isActive ? 'font-weight: bold; background: var(--ifm-color-emphasis-100, #f0f0f0);' : ''}
`;
item.onmouseenter = () => item.style.background = 'var(--ifm-color-emphasis-100, #f0f0f0)';
item.onmouseleave = () => {
if (!isActive) item.style.background = 'transparent';
else item.style.background = 'var(--ifm-color-emphasis-100, #f0f0f0)';
};
item.onclick = () => {
document.documentElement.setAttribute('data-theme-font', font.key);
localStorage.setItem('font-preference', font.key);
if (font.key !== 'system') {
localStorage.setItem('last-custom-font', font.key);
}
updateSliderUI(font.key !== 'system');
menu.remove();
};
menu.appendChild(item);
});

const closeMenu = (e) => {
if (!menu.contains(e.target)) {
menu.remove();
document.removeEventListener('click', closeMenu);
}
};
setTimeout(() => document.addEventListener('click', closeMenu), 10);

document.body.appendChild(menu);
};

// 更新滑块 UI
const updateSliderUI = (isCustom) => {
const svg = btn.querySelector('svg');
if (svg) {
const rect = svg.querySelector('rect');
const circle = svg.querySelector('circle');
if (rect) rect.setAttribute('fill', isCustom ? '#4CAF50' : '#ccc');
if (circle) circle.setAttribute('cx', isCustom ? '25' : '9');
}
btn.title = isCustom ? '切换到系统字体' : '切换到自定义字体';
};

// 1. 左键点击:快速切换
btn.onclick = (e) => {
if (clickTimer) {
clearTimeout(clickTimer);
clickTimer = null;
return;
}

const current = document.documentElement.getAttribute('data-theme-font') || 'system';
const lastCustom = localStorage.getItem('last-custom-font') || 'pixel';
const next = current === 'system' ? lastCustom : 'system';
const nextIsCustom = next !== 'system';

document.documentElement.setAttribute('data-theme-font', next);
localStorage.setItem('font-preference', next);
updateSliderUI(nextIsCustom);
};

// 2. 右键点击:弹出菜单
btn.oncontextmenu = (e) => {
e.preventDefault();
showFontMenu(e.clientX, e.clientY);
};

// 3. 长按(≥500ms):弹出菜单
btn.onmousedown = (e) => {
if (e.button !== 0) return;
pressTimer = setTimeout(() => {
showFontMenu(e.clientX, e.clientY);
pressTimer = null;
}, 500);
};
btn.onmouseup = () => {
if (pressTimer) {
clearTimeout(pressTimer);
pressTimer = null;
}
};
btn.onmouseleave = () => {
if (pressTimer) {
clearTimeout(pressTimer);
pressTimer = null;
}
};

// 4. 双击:弹出菜单
btn.ondblclick = (e) => {
e.preventDefault();
if (clickTimer) {
clearTimeout(clickTimer);
clickTimer = null;
}
showFontMenu(e.clientX, e.clientY);
};

// 防双击的单击处理
btn.addEventListener('click', (e) => {
if (clickTimer) {
clearTimeout(clickTimer);
clickTimer = null;
return;
}
clickTimer = setTimeout(() => {
clickTimer = null;
}, 300);
});

// 初始化 UI 状态
const savedState = localStorage.getItem('font-preference') || 'system';
updateSliderUI(savedState !== 'system');

// 插入到深色模式按钮之前
navbar.insertBefore(btn, navbar.lastElementChild);
}
};

// 初次插入
insertButton();

// 监听路由变化,重新插入(Docusaurus 是 SPA)
const observer = new MutationObserver(() => insertButton());
observer.observe(document.body, { childList: true, subtree: true });

return () => observer.disconnect();
}, []);

return null;
}

export default function Root({ children }) {
return (
<>
<FontSwitcherButton />
{children}
</>
);
}

Footnotes

  1. 没那么复杂啦

追加新功能字体切换

· 阅读需 1 分钟

这个功能在最右上角!快去点它!😊(这个贴文发布的时候)

我今天看了資工小廢物 - JN的部落格,左下角那个像素字体切换功能太赞了。
所以我决定ctrl+c复刻一个,他原版是只切换像素字体,我升级成右键可以调出列表选择自己想要的字体了,目前有Z工坊像素黑体 12px得意黑

现在没有文字注释,像个彩蛋,要自己发现。(其实也有,鼠标放上去就会显示了)

想换什么字体就在 custom.css 里加,超级好玩!!!👍

大开眼界👀

· 阅读需 1 分钟

今天逛网站挖到宝啦 , 在Neocities搜到了越南裔艺术家espy的个人网站。 纯html+python手搓,没有前端框架,还能pc和移动端差异化适配交互。

风格还超级独特,而且有blog、漫画、建模、动画、开源工具、成就墙,超颠的👀,而且每一种交互都有设计调试。 完美阐述什么叫数字花园🌼。

非常厉害和有启发性,不过我现在大脑还晕乎乎的🧠。

我现在就开始复制他的功能(看我的学习进度),看到优秀的创作,自身也干劲满满😊。