Communitygithub.com

jovd83/原型手绘皮肤技能

为 Angular/React/Vue 及静态 Web 应用提供可逆、非破坏性的手绘风格皮肤(Balsamiq、Sharpie、Pencil、Doodle、Blueprint),支持 0-100% 手绘度调节与交互式叠加层。仅影响外观与感受。

原型手绘皮肤技能 是什么?

该技能允许开发者为正在开发的 Web 应用附加一层手绘风格的“皮肤”,使其外观看起来像草图或原型,从而在客户演示时传递“尚未完成”的信号。它仅修改应用的样式和入口 HTML 文件,完全不触及组件逻辑、路由或模板,因此是纯附加且可完全撤销的。技能支持五种手绘风格(如 Balsamiq 灰阶线框、Sharpie 粗马克笔等),并通过一个 0-100% 的手绘度滑块控制线条的抖动程度。此外,还提供了一个可选的交互式叠加层,让用户或客户能够实时切换风格和手绘度,并支持添加水印。该技能兼容 Angular、React、Vue 以及静态 HTML 项目,实现方式简单:添加一份 CSS 样式表、一段 SVG 滤镜定义,并在 HTML 根元素上设置两个属性即可。如需恢复到原始界面,只需删除这两个属性。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add jovd83/prototype-sketching-skill

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

原型手绘皮肤技能 preview

文档

原型手绘皮肤技能 是做什么的?

让一个真实运行的 Web 应用看起来像是手绘的,这样客户就能明白它仍是原型,而非最终产品。这仅是外观与感受的皮肤,纯附加且完全可逆。

范围护栏(请先阅读,切勿违反)

  1. 只触碰样式入口和 index.html。 追加一个样式表、粘贴一个 SVG 块、设置两个属性。除此之外不做任何事。
  2. 切勿编辑 组件、模板、.ts/.tsx/.jsx/.vue 逻辑、路由、状态、服务或测试。
  3. 切勿替换 组件为手绘组件库(如 wired-elements)——那会重写标记,禁止。
  4. 切勿重新着色或扭曲 必须保持清晰的 Logo、照片、图表或图标——请使用 opt-out 类。
  5. 回退必须简单:删除 <html> 的两个属性即可关闭整个皮肤。

工作原理(一种思维模型)

  • 一个样式表 assets/sketch-skin.css 定义了全部 5 种样式及手绘度梯度。
  • 一个 SVG 块 assets/sketch-filters.html 定义了抖动滤镜(#sketch-25 … #sketch-100)。
  • 激活方式是在 <html> 上设置两个属性:data-sketch="<style>" 和 data-sketch-level="<0|25|50|75|100>"。
  • 外观来源于:手写字体替换 + 手绘边框(不规则圆角、平填充) + 一个SVG 位移滤镜,其强度即为手绘度。字体负责文本,滤镜只抖动边框装饰(绝不模糊文本)。

快速开始(请按顺序操作)

  1. 确认请求仅为皮肤。 如果用户需要行为/布局变更,立即停止——这超出范围。
  2. 识别框架,找到其全局样式表和 index.html(参见下方配置表)。
  3. 选择一种样式(见“样式”表格)和一个级别(0、25、50、75 或 100)。
  4. 将皮肤 CSS 添加到项目的全局样式:
    • 将 assets/sketch-skin.css 复制到项目中(例如 src/styles.scss)或使用 @import 导入。字体 @import 已包含在该文件中(在线使用)。
  5. 粘贴 SVG 滤镜:将 assets/sketch-filters.html 的内容粘贴到 index.html 中紧随 <body> 开始标签之后的位置。(必须——filter: url(#sketch-…) 只有在此定义存在于 DOM 中才能生效。)
  6. 激活:编辑 index.html 中的 <html> 标签:
    <html lang="en" data-sketch="balsamiq" data-sketch-level="50">
    
  7. 在浏览器中验证。要恢复,删除 data-sketch* 两个属性(追加的 CSS/SVG 可以保持不动——没有属性它们不会产生任何效果)。

样式

data-sketch外观字体适用场景
balsamiq干净灰阶线框,扁平盒子Balsamiq Sans默认的“这是原型”效果
sharpie粗黑马克笔,重描边Permanent Marker白板/工作坊草图
pencil浅石墨色,柔和笔触Gaegu温和的“纸上铅笔”草稿
doodle俏皮,浅色点缀Short Stack友好、非正式的概念
blueprint蓝纸上的白墨水Patrick Hand技术“画板”感觉

手绘度级别

data-sketch-level 控制线条的抖动程度。它会选择不同的 SVG 位移滤镜:

级别效果
0手绘边框 + 字体,但线条直而稳定(最干净)
25轻微抖动
50明显手绘(推荐默认值)
75松散、充满活力的草图
100非常粗糙,最大程度的“涂鸦”

如果设置了 data-sketch 但省略了 data-sketch-level,皮肤默认使用级别 50。

对角线水印(可选)

要将整个屏幕标记为草稿,可在 <html> 上添加第三个属性,包含要显示的文本:

<html data-sketch="balsamiq" data-sketch-level="50" data-sketch-watermark="草稿">

data-sketch-watermark 会在视口对角线上绘制一个淡淡的、手写体的单词。它是一个固定的、不可交互的图层(pointer-events: none),因此不会阻挡点击,不会改变布局,并且在页面和路由切换时保持不变。任何文本都可以(草稿、原型、机密、客户名称……)。删除该属性即可关闭。使用叠加层时,水印文本字段会实时设置它。

模态框、弹出框与 SPA 导航

由于皮肤通过 <html> 上的属性激活,并使用全局的 [data-sketch] … 选择器进行样式化,因此激活之后出现的任何内容都会自动继承——对话框、弹出层、下拉菜单、工具提示和 Toast(包括 Portal 挂载的)以及单页应用中的每个导航页面。无需逐个组件或逐个路由进行配置。

两点保持一致:

  • 选择器列表已涵盖 dialog、[popover]、[role="dialog"]、[aria-modal="true"]、.modal、.popover、菜单、工具提示和 Toast,以及原生的 ::backdrop。
  • 叠加层脚本会监视 <body>,如果框架在路由切换时替换了 body,它会重新注入 SVG 滤镜,从而确保抖动不会在无声中消失。(对于静态属性模型,将 sketch-filters.html 粘贴到 <body> 之后一次即可;SPA 框架会挂载到一个子根节点上,并保持其完整。)

框架注入配置

该皮肤与框架无关。以下是精确的目标位置;完整细节请参考 references/implementation.md。

栈CSS 添加位置SVG 粘贴位置属性设置位置
Angularsrc/styles.scss(或 styles.css)src/index.html 中 <body> 之后src/index.html 中的 <html>
React / Vitesrc/index.css(在 main.tsx 中导入)index.html 中 <body> 之后index.html 中的 <html>
Vuesrc/assets/main.css(在 main.ts 中导入)index.html 中 <body> 之后index.html 中的 <html>
静态 HTML在 <head> 中链接 sketch-skin.cssindex.html 中 <body> 之后index.html 中的 <html>

保持特定资源清晰(opt-out)

皮肤不会编辑标记,但如果用户明确要求保护某个元素(Logo、图表),唯一允许的标记更改是向该单个元素添加 opt-out 钩子:

<img src="logo.svg" class="no-sketch" alt="Logo">

.no-sketch(或 data-no-sketch)会移除该元素的抖动滤镜和颜色覆盖。请谨慎使用,并仅在用户提出要求时使用。

交互式预览叠加层(可选)

当用户希望实时切换样式(例如向客户展示切换效果)时,请使用叠加层而非静态属性:

  1. 将 assets/sketch-skin.css 添加到全局样式(同快速开始)。
  2. 在 </body> 之前添加一个脚本标签:
    <script src="sketch-toggle.js" defer></script>
    
  3. 完成。脚本会渲染一个浮动面板,包含关闭 + 每个主题的单选按钮、一个0-100% 手绘度滑块和一个水印文本字段,实时切换 <html> 属性,并将选择保存在 localStorage 中。它会自动注入 SVG 滤镜(如果 SPA 替换了 body,还会重新注入),因此快速开始的第 5 步(粘贴 sketch-filters.html)不再需要。

这仍然是仅皮肤、非破坏性的——脚本只是设置属性。删除标签即可禁用。当需求是“让我/客户切换样式”时选择此模型;对于固定、截图稳定的外观,请使用静态属性。

截图画廊

README.md 使用 demo/screenshots/ 中的 PNG 展示了每种样式及 0→100% 的梯度。这些图片是预先渲染的;生成它们的交互式演示应用和 Playwright 截图脚本位于项目的开发源码中,不会与安装的技能一起打包。技能本身仅包含 assets/ + references/ ——无需构建步骤,无依赖。

示例

示例 1 — Angular 演示,Balsamiq 风格,中等手绘

  • 输入:“让这个 Angular 应用看起来像 Balsamiq 线框,用于明天的演示。”
  • 操作:将 sketch-skin.css 追加到 src/styles.scss;将滤镜粘贴到 src/index.html;设置 <html data-sketch="balsamiq" data-sketch-level="50">。
  • 结果:应用运行完全一样;渲染为灰阶线框。

示例 2 — React,最大锐利马克笔

  • 输入:“React 应用,完全白板标记笔外观,非常粗糙。”
  • 操作:在 main.tsx 中导入 sketch-skin.css;将滤镜粘贴到 index.html;设置 data-sketch="sharpie" data-sketch-level="100"。

示例 3 — 关闭皮肤

  • 输入:“切换回真实的 UI。”
  • 操作:从 <html> 中删除 data-sketch 和 data-sketch-level。完成——不需要其他更改。

故障排除

症状原因修复
盒子看起来手绘但线条完全笔直SVG 滤镜不在 DOM 中,或级别为 0确认 sketch-filters.html 已粘贴到 <body> 之后;将级别设为 ≥ 25
完全没有变化属性缺失或 CSS 未加载验证 <html data-sketch="…"> 存在且 sketch-skin.css 在全局样式中
文本看起来模糊滤镜应用于文本/整个 <body>不要将 filter: 添加到 body 或文本;皮肤仅过滤边框装饰——请重新复制未经修改的 sketch-skin.css
字体不是手写体离线/Google Fonts 被阻止自托管字体——请参见 assets/fonts/README.md
页面在大型表格/网格上感觉卡顿feDisplacementMap 对大型 DOM 的计算成本降低级别,或缩小抖动选择器列表的范围(见 references/implementation.md)
Logo 变得去饱和/抖动该资源未设置 opt-out向该单个元素添加 class="no-sketch"
图标字体 / SVG 图标消失过于激进的扁平化向图标容器添加 no-sketch,或参见 references/implementation.md 中的图标注释

参考文件(仅在需要时阅读)

  • references/styles.md — 每种样式的精确字体/调色板/描边规范,以及如何添加新样式。
  • references/implementation.md — SVG 滤镜数学、按框架的逐步指导、选择器调优、离线字体、性能、回退细节。

相关技能