关于 makepad-2.0-vector
面向 Makepad 2.0 开发者的矢量图形技能,介绍如何在 Splash 中创建分辨率无关的图形。内容涵盖内联 Vector 图形、外部 SVG、渐变、滤镜、变换和 Tween 属性动画。
主要功能
- 01定义内联矢量形状与路径
- 02加载外部 SVG 文件
- 03支持渐变、滤镜和变换
- 04使用 Tween 为形状属性添加动画
- 05说明 Vector、Svg 与 SDF2D 的用途
适用场景
- 01制作界面图标和插图
- 02在应用中使用外部 SVG 素材
- 03为矢量指示器和图形添加动画
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ zhanghandong/ makepad-skills --skill makepad-2.0-vector安装后在 Claude Code 中输入/makepad-2.0-vector确认已加载。
附带文件references/vector-reference.md
详细介绍
Makepad 2.0 矢量图形技能
版本: makepad-widgets(dev branch)| 最后更新: 2026-03-03
概述
Vector 控件使用类似 SVG 的语法绘制与分辨率无关的矢量图形。它支持路径、形状、渐变、滤镜、分组、变换,以及通过 Tween 实现属性动画。
在 Splash 中使用 SVG 的两种方式:
Vector{}- 在 Splash 中内联定义形状(路径、矩形、圆形等)Svg{}- 通过crate_resource()或http_resource()加载外部.svg文件,并可选择启用动画和自定义 GPU 着色器
文档
详细文档请参阅本地文件:
./references/vector-reference.md- 完整的 Vector API、形状、渐变、滤镜和动画
基本用法
Vector{
width: 48 height: 48
viewbox: vec4(0 0 24 24)
Path{
d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"
fill: false
stroke: #4488ff
stroke_width: 2.0
stroke_linecap: "round"
stroke_linejoin: "round"
}
}
关键属性
| 属性 | 描述 | 示例 |
|---|---|---|
width / height | 控件尺寸,单位为像素 | 48 |
viewbox | 以 vec4 表示的 SVG viewBox | vec4(0 0 24 24) |
关键说明:形状属性与控件属性
Vector 形状使用 SVG 风格的属性,而不是 draw_bg.* 控件属性:
// CORRECT — SVG properties
Path{d:"M 0 0 L 10 10" stroke:#x66aaff stroke_width:2.5}
Circle{cx:10 cy:10 r:5 fill:#x44ddaa}
// WRONG — these do nothing on Vector shapes!
Path{d:"..." draw_bg.stroke_color:#x66aaff draw_bg.stroke_width:2.}
Circle{cx:10 cy:10 r:5 draw_bg.fill_color:#x44ddaa}
形状类型
路径(SVG 路径数据)
Path{
d: "M10 10 L20 20 L10 20 Z"
fill: #f00
stroke: #000
stroke_width: 1.5
}
内置形状
Rect{x: 0 y: 0 width: 100 height: 50 fill: #f00 rx: 5}
Circle{cx: 50 cy: 50 r: 25 fill: #00f}
Ellipse{cx: 50 cy: 30 rx: 40 ry: 20 fill: #0f0}
Line{x1: 0 y1: 0 x2: 100 y2: 100 stroke: #fff stroke_width: 2}
Polyline{points: "0,0 50,25 100,0" fill: false stroke: #fff}
Polygon{points: "50,0 100,100 0,100" fill: #f0f}
渐变
线性渐变
Gradient{
id: "myGrad"
x1: 0 y1: 0 x2: 1 y2: 1
Stop{offset: 0 color: #ff0000}
Stop{offset: 1 color: #0000ff}
}
Path{d: "..." fill: "url(#myGrad)"}
径向渐变
RadGradient{
id: "radGrad"
cx: 0.5 cy: 0.5 r: 0.5
Stop{offset: 0 color: #ffffff}
Stop{offset: 1 color: #000000}
}
分组与变换
Group{
transform: "translate(10 20) rotate(45 50 50)"
opacity: 0.8
Circle{cx: 0 cy: 0 r: 10 fill: #f00}
Rect{x: 20 y: 0 width: 20 height: 20 fill: #0f0}
}
滤镜
Filter{
id: "shadow"
DropShadow{dx: 2 dy: 2 blur: 4 color: #0008}
}
Path{d: "..." fill: #fff filter: "url(#shadow)"}
Tween 动画(SVG 属性动画)
关键说明: Tween 是一个属性值,而不是容器。它会将形状属性(fill、stroke、opacity、cx、cy、r 等)替换为动画值。
基本语法
// Animate opacity (pulse effect)
Circle{cx:8 cy:8 r:6 fill:#x44ddaa opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:true}}
// Animate position (moving dot)
Circle{cx:Tween{from:20 to:380 dur:3.0 loop_:true} cy:25 r:5 fill:#x66aaff}
// Animate color
Circle{fill:Tween{from:#x44ddaa to:#x6688dd dur:3.0 loop_:true} cx:10 cy:10 r:8}
// Animate stroke
Path{d:"M 0 0 L 100 0" stroke:Tween{from:#x333333 to:#x66aaff dur:2.0 loop_:true} stroke_width:2.}
关键说明:loop_ 必须是布尔值
// CORRECT — indefinite loop
opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:true}
// CORRECT — play 3 times
opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:3.0}
// WRONG — string doesn't trigger Indefinite, plays only once!
opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:"indefinite"}
Tween 属性
| 属性 | 类型 | 描述 | 默认值 |
|---|---|---|---|
from | value | 起始值(颜色、浮点数、字符串) | - |
to | value | 结束值 | - |
values | Vec | 关键帧值(可替代 from/to) | - |
dur | f32 | 持续时间,单位为秒 | 1.0 |
begin | f32 | 延迟偏移,单位为秒 | 0.0 |
loop_ | bool/f32 | true = 无限循环,浮点数 = 重复次数 | 1.0 |
calc | string | "discrete"、"paced"、"spline" | "linear" |
fill_mode | string | "freeze" 或 "remove" | "remove" |
可动画属性
任何形状属性都可以使用 Tween 实现动画:
fill、stroke— 颜色动画stroke_width、opacity、stroke_opacity— 浮点数动画cx、cy、r(Circle)— 位置/尺寸动画d(Path)— 路径变形动画
常见模式
脉冲指示器:
Vector{width:16 height:16
Circle{cx:8 cy:8 r:6 fill:#x44ddaa opacity:Tween{from:0.3 to:1.0 dur:1.5 loop_:true}}
}
沿直线移动的点:
Vector{width:Fill height:40
Path{d:"M 20 20 L 380 20" stroke:#x333355 stroke_width:1.}
Circle{cx:Tween{from:20 to:380 dur:3.0 loop_:true} cy:20 r:4 fill:Tween{from:#x44ddaa to:#xffaa44 dur:3.0 loop_:true}}
}
延迟顺序动画:
Circle{cx:8 cy:8 r:6 fill:#x44ddaa opacity:Tween{from:0.3 to:1.0 dur:1.5 begin:0.0 loop_:true}}
Circle{cx:8 cy:8 r:6 fill:#xffaa44 opacity:Tween{from:0.3 to:1.0 dur:1.5 begin:0.5 loop_:true}}
Circle{cx:8 cy:8 r:6 fill:#x6688dd opacity:Tween{from:0.3 to:1.0 dur:1.5 begin:1.0 loop_:true}}
Tween 与 Animator 的区别
| 特性 | Tween(Vector) | Animator(控件) |
|---|---|---|
| 作用范围 | SVG 形状属性 | 控件着色器的 instance 变量 |
| 语法 | 替换属性值 | animator: Animator{...} 代码块 |
| 触发方式 | 渲染时自动触发 | 状态转换(悬停等) |
| 循环 | loop_:true | Loop {duration: 1.0} |
| 用途 | SVG 动画 | UI 悬停/焦点/激活效果 |
图标模式(常用)
Makepad 2.0 中的大多数 Vector 控件都将 SVG 路径用于图标:
let IconCheck = Vector{width: 18 height: 18 viewbox: vec4(0 0 24 24)
Path{d: "M20 6L9 17L4 12" fill: false stroke: theme.color_highlight stroke_width: 2.5
stroke_linecap: "round" stroke_linejoin: "round"}
}
let IconTrash = Vector{width: 14 height: 14 viewbox: vec4(0 0 24 24)
Path{d: "M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" fill: false stroke: theme.color_label_inner_inactive stroke_width: 1.8 stroke_linecap: "round" stroke_linejoin: "round"}
}
搭配主题颜色使用,确保在浅色/深色模式下保持一致的样式。
Vector、Svg 与 SDF2D
| 特性 | Vector{} | Svg{} | SDF2D 着色器 |
|---|---|---|---|
| 输入 | Splash 中的内联形状 | 外部 .svg 文件 | 着色器代码 |
| SVG 路径数据 | 是(d: "...") | 是(从文件解析) | 否 |
| 渐变 | let 绑定 | SVG <defs> | 手动 |
| 滤镜 | Filter{DropShadow{}} | SVG <filter> | 手动 |
| 动画 | Tween{} | SVG <animate> + animating: true | 着色器统一变量 |
| 自定义 GPU 着色器 | shader_id | draw_svg +: {get_color: fn(){...}} | 完全控制 |
| URL 加载 | 否 | 是(http_resource()) | 否 |
| 分辨率无关 | 是 | 是 | 是 |
| 性能 | 适用于静态内容 | 适用于复杂 SVG | 最适用于动画 |
使用 Vector{}: 内联图标、插图、程序化矢量图形
使用 Svg{}: 加载预制 SVG 文件、复杂 SVG 资源、来自 URL 的 SVG
使用 SDF2D: 动画形状、悬停效果、自定义控件背景
十六进制颜色转义
使用包含字母“e”的十六进制颜色时,请在前面加上 #x:
// WRONG - parser misreads 'e' as exponent
stroke: #2ecc71
// CORRECT
stroke: #x2ecc71
最佳实践
- 使用
viewbox定义不受控件尺寸影响的坐标空间 - 使用主题颜色 设置图标描边/填充,以支持深色/浅色模式
- 使用
let绑定 定义可复用的图标 - 保持路径简洁——复杂的 SVG 路径可能影响性能
- 使用
fill: false创建仅描边图标(最常见的模式) - 设置
stroke_linecap: "round"让图标线条的端点更平滑
评论
支持 Markdown