page-mascot

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mascot

吉祥物

Turns "put a fox on my page" or "draw me a chibi otter" into a working
<Mascot />
.
Each character is two 3×3 sprite sheets: nine head directions, and nine expressions. The component swaps between them by moving
background-position
, so there is no per-frame JavaScript and no animation library. A character is its two files -- there is no registry and nothing has to know its name.
将“在我的页面上放一只狐狸”或“给我画一只 Q 版水獭”变成一个可正常工作的
<Mascot />
。
每个角色由两张 3×3 sprite sheet 组成:九种头部朝向和九种表情。组件通过移动
background-position
在二者之间切换,因此不需要逐帧 JavaScript,也不需要动画库。一个角色就是它的两个文件——没有 registry,也不需要任何代码知道它的名称。

Which route

选择路线

  • The user names a character, or would take one that exists -- Use one that is drawn. No Python, no API key, works in any React project. This is the common case.
  • The user wants something new, or their own likeness -- Draw a new one, then finish with Put it on the page.
Both routes end in Put it on the page. Do not stop at files and a snippet.
  • 用户指定了某个角色,或可以接受现有角色——使用已绘制的角色。无需 Python,无需 API key,可在任何 React 项目中使用。这是常见情况。
  • 用户想要新角色,或希望使用自己的形象——绘制新角色,然后完成放到页面上。
两条路线最终都要完成放到页面上。不要止步于文件和代码片段。

Use one that is drawn

使用已绘制的角色

  1. Pick.
    reference/characters.md
    lists the fifty-two. If the user did not name one, pick the one that fits the site, and say which you picked and why.
  2. Fetch the two sheets into wherever this project serves static files --
    public/
    for Next, Vite, CRA and Astro,
    static/
    for SvelteKit -- or next to the component to import them:
    bash
    mkdir -p public/mascots
    curl -fsSL -o public/mascots/fox-directions.webp https://koboyo.com/page-mascot/mascots/fox-directions.webp
    curl -fsSL -o public/mascots/fox-reactions.webp  https://koboyo.com/page-mascot/mascots/fox-reactions.webp
  3. Put it on the page (below).
  1. 选择。
    reference/characters.md
    列出了全部 52 个角色。如果用户没有指定角色,就选择一个适合该网站的角色,并说明选了哪个以及原因。
  2. 获取两张 sprite sheet,放入项目提供静态文件的位置——Next、Vite、CRA 和 Astro 使用
    public/
    ,SvelteKit 使用
    static/
    ——或放在组件旁边以便导入:
    bash
    mkdir -p public/mascots
    curl -fsSL -o public/mascots/fox-directions.webp https://koboyo.com/page-mascot/mascots/fox-directions.webp
    curl -fsSL -o public/mascots/fox-reactions.webp  https://koboyo.com/page-mascot/mascots/fox-reactions.webp
  3. 放到页面上(见下文)。

Put it on the page

放到页面上

Install the component. Use whichever package manager the lockfile points at:
npm i page-mascot
,
pnpm add page-mascot
,
yarn add page-mascot
, or
bun add page-mascot
. If this is not a package-managed React project, copy
mascot.tsx
from beside this SKILL.md into the project instead -- it is one file, needs only React, and uses inline styles.
Render it:
tsx
import { Mascot } from 'page-mascot'

<Mascot
  directions="/mascots/fox-directions.webp"
  reactions="/mascots/fox-reactions.webp"
/>
directions
and
reactions
are the served paths of the two sheets, or imported images. Both required. The other props are
size
(default 140),
label
(what a screen reader calls it) and
className
.
Put it where the user asked. If they did not say, the top of the page -- the header or hero, above or beside the title, which is where a head that watches the cursor reads best. Edit the actual component; then tell the user what you changed and where.
安装组件。 根据 lockfile 指向的包管理器使用:
npm i page-mascot
、
pnpm add page-mascot
、
yarn add page-mascot
或
bun add page-mascot
。如果这不是由包管理器管理的 React 项目,则改为把 SKILL.md 旁边的
mascot.tsx
复制到项目中——它只有一个文件,仅依赖 React,并使用内联样式。
渲染:
tsx
import { Mascot } from 'page-mascot'

<Mascot
  directions="/mascots/fox-directions.webp"
  reactions="/mascots/fox-reactions.webp"
/>
directions
和
reactions
是两张 sprite sheet 的提供路径,也可以是导入的图像。两者均为必填。其他 props 包括
size
(默认值为 140)、
label
(screen reader 对它的称呼)和
className
。
放到用户要求的位置。 如果用户没有指定,就放在页面顶部——header 或 hero 中,标题的上方或旁边,因为这种会注视光标的头部角色放在那里效果最好。编辑实际组件;然后告诉用户改了什么以及改在哪里。

Draw a new one

绘制新角色

First, work out how you will draw

首先,确定如何绘制

Two sheets have to be drawn per character, and agents differ in whether they can do that themselves. Check in this order:
  1. You have a built-in image generation tool (Codex does). Use it directly -- follow Drawing it yourself below. Find out first whether it can return a transparent background, because that decides which prompt you send: with the option, ask for transparency and set it; without one, draw on a solid key colour and remove it afterwards. Both are written out under Transparency.
  2. OPENAI_API_KEY
    is set.
    Use the API path, which needs no image tool at all -- follow Drawing through the API. This is the route for Claude Code, which has no image tool.
    generate.py
    asks for transparency through the API's
    background
    parameter and falls back to the key route on its own if no alpha comes back.
  3. Neither. Say plainly that drawing needs either an agent that can generate images or an
    OPENAI_API_KEY
    , and offer two alternatives: one of the fifty-two drawn characters (Use one that is drawn), or the manual route in
    reference/prompts.md
    , where the user pastes the prompts into a chat UI themselves. Do not try to drive a web UI in a browser to work around it: it depends on the page's markup, needs a logged-in session, and gets rate-limited part way through a set.
Either way, the build needs Python 3:
bash
python3 -c "import PIL, numpy, scipy" 2>&1
If that fails:
pip install -r <skill-dir>/scripts/requirements.txt
. Stop and say so rather than working around it.
<skill-dir>
everywhere below is the folder holding this SKILL.md -- the skill is usually installed outside the project, so use its full path. Run every command from the project root: the scripts read source sheets from
characters/<name>/
and write the built atlases to
public/mascots/
under the current directory. Pass
--dest static/mascots
(or wherever this project serves static files) when
public/
is not it.
每个角色都必须绘制两张 sprite sheet,而不同 Agent 能否自行完成这项工作并不相同。按以下顺序检查:
  1. 你有内置图像生成工具(Codex 有)。直接使用它——遵循下方自行绘制。先确认它能否返回透明背景,因为这决定了你应发送哪种 prompt:如果支持该选项,就请求透明背景并启用它;如果不支持,则在纯色 key 背景上绘制,之后再移除该背景。两种写法都列在透明背景部分。
  2. 已设置
    OPENAI_API_KEY
    。
    使用 API 路径,该路径完全不需要图像工具——遵循通过 API 绘制。这是 Claude Code 适用的路线,因为 Claude Code 没有图像工具。
    generate.py
    会通过 API 的
    background
    参数请求透明背景;如果没有返回 alpha 通道,则会自动回退到 key 色方案。
  3. 两者都没有。 明确说明,绘制需要能够生成图像的 Agent 或
    OPENAI_API_KEY
    ,并提供两个替代方案:从 52 个已绘制角色中选择一个(使用已绘制的角色),或采用
    reference/prompts.md
    中的手动路线,由用户自行将 prompt 粘贴到聊天界面中。不要尝试通过浏览器操控网页 UI 来绕过限制:该方式依赖页面 markup,需要已登录的会话,并且在一组操作进行到一半时会被限流。
无论采用哪条路线,构建都需要 Python 3:
bash
python3 -c "import PIL, numpy, scipy" 2>&1
如果失败:执行
pip install -r <skill-dir>/scripts/requirements.txt
。停止操作并如实说明情况,不要尝试绕过它。
下文的
<skill-dir>
均指存放此 SKILL.md 的文件夹——skill 通常安装在项目之外,因此要使用其完整路径。所有命令都从项目根目录运行:脚本从
characters/<name>/
读取源 sprite sheet,并将构建后的 atlas 写入当前目录下的
public/mascots/
。当
public/
不是静态文件目录时,传入
--dest static/mascots
(或项目实际使用的目录)。

Drawing through the API

通过 API 绘制

One command generates, screens, builds, verifies and retries:
bash
python3 <skill-dir>/scripts/mascot.py fox --describe "a chibi fox with warm orange fur, a cream muzzle and dark ear tips"
Add
--style riso
for a different look, or
--reference ~/photo.jpg
to redraw someone.
--only reactions
redraws just the expressions sheet and keeps the directions sheet. If the model returns no alpha channel, it redraws that sheet on a solid key colour and removes it, which costs one extra image;
--key green
forces that route from the start. It needs
pip install openai
alongside the packages above. The image model is pinned in
generate.py
; set
MASCOT_IMAGE_MODEL
to use a different one.
一条命令即可完成生成、筛查、构建、验证和重试:
bash
python3 <skill-dir>/scripts/mascot.py fox --describe "a chibi fox with warm orange fur, a cream muzzle and dark ear tips"
添加
--style riso
可使用不同外观,或添加
--reference ~/photo.jpg
可重新绘制某个人的形象。
--only reactions
只重新绘制表情 sheet,并保留朝向 sheet。如果模型没有返回 alpha 通道,它会在纯色 key 背景上重新绘制该 sheet,然后移除背景,这会额外消耗一次图像生成;
--key green
会从一开始就强制使用该路线。除上述依赖外,还需要
pip install openai
。图像模型在
generate.py
中固定;可设置
MASCOT_IMAGE_MODEL
改用其他模型。

Drawing it yourself

自行绘制

1. Draw the directions sheet. Use your image generation tool with the DIRECTIONS prompt from
reference/prompts.md
, substituting the character description. If your tool cannot return a transparent background, send the key variant of that prompt instead and turn the option off -- see Transparency below, and send the same variant for both sheets. Save it to
characters/<name>/directions.png
.
2. Draw the expressions sheet. Use the EXPRESSIONS prompt, and pass the directions sheet you just made as a reference image. Save it to
characters/<name>/reactions.png
.
3. Build and verify.
bash
python3 <skill-dir>/scripts/mascot.py <name> --skip-generate
4. Act on what it says. It either finishes and tells you the character is ready, or it names which of the two sheets is at fault. Redraw that one sheet and run step 3 again. Give up after two attempts and change the description instead -- past that the art is the problem, not the build.
Run the commands yourself. Do not print them for the user to copy.
1. 绘制朝向 sprite sheet。 使用图像生成工具,并采用
reference/prompts.md
中的 DIRECTIONS prompt,替换角色描述。如果工具无法返回透明背景,请改用该 prompt 的 key 变体并关闭相应选项——参见下方透明背景,且两张 sprite sheet 都使用同一变体。保存到
characters/<name>/directions.png
。
2. 绘制表情 sheet。 使用 EXPRESSIONS prompt,并将刚完成的朝向 sheet 作为参考图像传入。保存到
characters/<name>/reactions.png
。
3. 构建并验证。
bash
python3 <skill-dir>/scripts/mascot.py <name> --skip-generate
4. 根据结果处理。 它要么成功完成并告诉你角色已就绪,要么指出两张 sheet 中哪一张有问题。重新绘制有问题的 sheet,然后再次执行步骤 3。两次尝试后仍失败就放弃并修改描述——超过这个次数,问题出在美术效果上,而不是构建流程。
请自行运行命令。不要把它们打印出来让用户复制。

Check the head turns point the right way

检查头部朝向是否正确

The scripts measure everything except which direction the character is actually looking. Before you hand a character over, crop the
left
cell (middle row, first column) and the
right
cell (middle row, third column) of the directions sheet and look at them: the left one must face the viewer's left.
A sheet occasionally comes back mirrored, and it scores perfectly on every check while looking away from the cursor on the page. Do not regenerate it -- the art is right and only the cell order is wrong.
reference/design-rules.md
has the three-line column swap that fixes it.
脚本会测量除角色实际注视方向以外的所有内容。交付角色前,裁出朝向 sheet 的
left
单元格(中间行、第一列)和
right
单元格(中间行、第三列)并查看:left 必须朝向观看者的左侧。
偶尔 sheet 会以镜像形式返回,它会在每项检查中取得满分,但在页面上却背离光标。不要重新生成——美术内容是对的,只是单元格顺序错了。
reference/design-rules.md
提供了只需三行的列交换修复方法。

Transparency is the thing that most often goes wrong

透明背景是最容易出错的部分

The sheets must end up as PNGs with a real alpha channel, and the prompt cannot get you one. Transparency is a setting on the image call --
background: "transparent"
on the OpenAI API, the equivalent option on a built-in tool -- not something a model does because it was asked in words. Measured over fifteen sheets on
gpt-image-2.5
: with the option set, every sheet came back with real alpha whether or not the prompt mentioned transparency at all; without it, every sheet came back opaque with a painted grey-and-white checkerboard behind the character. That includes a prompt demanding "PNG WITH A REAL ALPHA CHANNEL... not white" in capitals. Unable to emit alpha, the model draws the pattern that stands for it.
So there are two prompts, and which one you send depends on the tool, not on the character:
  • The tool can return a transparent background. Set that option, and use the prompts in
    reference/prompts.md
    as they are.
  • It cannot. Then asking for transparency is the one thing you must not do, because that is what summons the checkerboard -- and a checkerboard is unrecoverable, its squares run under the character's edges. Send the key variant of the prompt instead (
    reference/prompts.md
    , Drawing without transparency): it asks for a flat pure green background and mentions transparency nowhere. Then remove that green:
    bash
    python3 <skill-dir>/scripts/key.py characters/<name>/directions.png --in-place
    mascot.py
    does this for you when it finds a sheet on a solid key colour, so normally you can just run the build and let it happen.
Hedging does not work. A prompt that asks for transparency and adds "use green if you cannot" gets the checkerboard, same as before. The two prompts are alternatives, never combined.
screen.py
names which case you are in:
what it printswhat happenedwhat to do
alpha: ok
real alpha channelnothing
alpha: MISSING (solid #02F902 background -- key.py can remove it)
drawn on the key colourkey it out, or let
mascot.py
do it
alpha: MISSING (painted checkerboard, 32px squares -- redraw)
asked for transparency a tool could not giveredraw with the right prompt for your tool
alpha: MISSING (opaque background)
flattened onto white or a sceneredraw; nothing can be keyed out of this
The last two cannot be repaired. A white background cannot be keyed because the character's own cream and white areas would go with it, which is also why the key colour is a saturated green and never white, grey or black.
这些 sheet 必须最终保存为带真正 alpha 通道的 PNG,而prompt 无法为你获得 alpha 通道。透明背景是图像调用时的一项设置——在 OpenAI API 中是
background: "transparent"
,在内置工具中则是对应选项——并不是模型仅凭文字要求就会执行的行为。对
gpt-image-2.5
生成的 15 张 sheet 进行测量后,结果如下:启用该选项时,无论 prompt 是否提到透明背景,每张 sheet 都会返回真正的 alpha;未启用时,每张 sheet 都会返回不透明背景,角色后面带有绘制出来的灰白棋盘格。其中就包括一条用全大写要求“PNG WITH A REAL ALPHA CHANNEL... not white”的 prompt。模型无法输出 alpha 时,就会画出代表透明背景的图案。
因此有两种 prompt,应发送哪一种取决于工具,而不是角色:
  • 工具可以返回透明背景。 设置该选项,直接使用
    reference/prompts.md
    中的 prompt。
  • 工具无法返回透明背景。 此时绝不能在 prompt 中要求透明背景,因为这会招来棋盘格,而且棋盘格无法修复,方块会延伸到角色边缘下方。改用 key 变体(
    reference/prompts.md
    中的不使用透明背景绘制):该变体要求使用纯绿色平面背景,完全不提及透明背景。然后移除绿色:
    bash
    python3 <skill-dir>/scripts/key.py characters/<name>/directions.png --in-place
    mascot.py
    会在发现 sprite sheet 使用纯色 key 背景时替你完成这一步,因此通常直接运行构建流程即可。
折中处理行不通。如果 prompt 既要求透明背景,又补充“无法做到时请使用绿色”,仍会得到棋盘格,与之前一样。这两种 prompt 是互斥方案,绝不能组合使用。
screen.py
会指出属于哪种情况:
输出内容发生的情况处理方式
alpha: ok
存在真正的 alpha 通道无需处理
alpha: MISSING (solid #02F902 background -- key.py can remove it)
在 key 色背景上绘制抠除 key 色,或让
mascot.py
处理
alpha: MISSING (painted checkerboard, 32px squares -- redraw)
要求了工具无法提供的透明背景使用适合该工具的 prompt 重新绘制
alpha: MISSING (opaque background)
已合成到白色或场景背景上重新绘制;无法通过抠图修复
后两种情况无法修复。白色背景无法抠除 key 色,因为角色自身的奶油色和白色区域也会被一起移除;这也是 key 色使用饱和绿色,而绝不使用白色、灰色或黑色的原因。

Writing the description

编写描述

This decides whether the result is good, so spend a sentence on it rather than passing the user's word through raw. "fox" gives a worse fox than "a cute chibi fox with warm orange fur, a cream muzzle and dark ear tips". Name the colours and two or three distinguishing features, in one sentence.
Avoid, because each breaks the alignment the effect depends on:
  • Long loose hair over the shoulders. Tie it back or put it under a hat. It gets drawn differently in each sheet and the mascot lurches when clicked. Most common failure by far.
  • Anything wider than the head -- big wings, wide headdresses. They get clipped at the cell edges.
  • Held props. Staffs, mugs, instruments. The framing is head and shoulders only.
Good:
a chibi robot with a mint-green boxy head and a single wide visor screen
,
a chibi grandmother with silver hair in a neat bun and round gold spectacles
.
这决定最终效果,因此应花一句话润色,而不是直接照搬用户原话。“fox” 生成的狐狸不如“一只可爱的 Q 版狐狸,拥有温暖的橙色毛发、奶油色口鼻和深色耳尖” 好。用一句话说明颜色以及两到三个有辨识度的特征。
避免以下特征,因为每一种都会破坏该效果所依赖的对齐:
  • 肩上披着长而松散的头发。 将头发扎起或塞进帽子。两张 sheet 中画法不同,点击时吉祥物会突然跳动。这是迄今为止最常见的问题。
  • 任何比头部更宽的元素——大翅膀、宽头饰。它们会在单元格边缘被裁掉。
  • 手持道具。 法杖、马克杯、乐器。构图仅为头部和肩部。
好的示例:
a chibi robot with a mint-green boxy head and a single wide visor screen
、
a chibi grandmother with silver hair in a neat bun and round gold spectacles
。

Drawing in another style

使用其他风格绘制

Six looks are available:
colour
(the default),
ink
,
sketch
,
riso
,
paper
and
pixel
. They change only how the character is drawn -- the framing, proportions, reused body and margins are shared, so a style cannot break the alignment.
reference/prompts.md
has the paragraph for each. Swap it into both prompts for that character, and name the style again in the EXPRESSIONS prompt so the second sheet does not drift back to the default. Through the API path it is a flag:
bash
python3 <skill-dir>/scripts/mascot.py fox --style riso --describe "a chibi fox with orange fur"
Keep one style per character across both its sheets. The caveats for
ink
,
sketch
and
pixel
are at the bottom of
reference/prompts.md
-- read them before using those three.
提供六种外观:
colour
(默认)、
ink
、
sketch
、
riso
、
paper
和
pixel
。
它们只改变角色的绘制方式——构图、比例、复用的身体和边距保持一致,因此风格不会破坏对齐。
reference/prompts.md
包含每种风格对应的段落。将相应段落替换进该角色的两份 prompt 中,并在 EXPRESSIONS prompt 中再次注明风格,避免第二张 sheet 偏离默认风格。通过 API 路线时,它是一个 flag:
bash
python3 <skill-dir>/scripts/mascot.py fox --style riso --describe "a chibi fox with orange fur"
同一个角色的两张 sheet 必须保持同一种风格。使用
ink
、
sketch
和
pixel
时的注意事项位于
reference/prompts.md
底部——使用这三种风格前先阅读相关内容。

From a user's own image

根据用户自己的图像

Same loop, but for step 1 pass their image to your image tool with the REFERENCE prompt from
reference/prompts.md
. It redraws their character as a directions sheet in the style the pipeline needs. Step 2 onward is unchanged.
采用相同流程,但步骤 1 要将用户图像连同
reference/prompts.md
中的 REFERENCE prompt 一起传给图像工具。它会按照流程所需的风格,将用户的角色重新绘制为朝向 sheet。步骤 2 及之后保持不变。

Afterwards

之后

Built atlases land in
public/mascots/<name>-{directions,reactions}.webp
(or
--dest
). The source sheets stay in
characters/<name>/
so a character can be rebuilt without redrawing it; say so, and leave it to the user whether to keep or delete them.
Then Put it on the page.
构建后的 atlas 会保存到
public/mascots/<name>-{directions,reactions}.webp
(或
--dest
指定的目录)。源 sheet 保留在
characters/<name>/
,这样无需重新绘制即可再次构建角色;告知用户这一点,并由用户决定保留还是删除。
然后执行放到页面上。

Making several

制作多个

One at a time, reporting as you go.
一次制作一个,并随进度汇报。

Going deeper

深入了解

reference/design-rules.md
explains why each art rule exists, what each failure looks like, and how the two sheets are matched. Read it when a character fails in a way the script's messages do not cover.
reference/design-rules.md
解释了每项美术规则存在的原因、每种失败问题的具体表现,以及两张 sheet 是如何匹配的。当角色出现脚本消息未涵盖的问题时,请阅读该文档。