mcpField
I
ink-custom-brush-builder

ink-custom-brush-builder

github.com/android开发10.0k47 次安装2 天前更新
代码仓库

关于 ink-custom-brush-builder

这项技能指导编码 Agent 使用 Android Ink API 编程创建自定义画笔,涵盖画笔结构、输入响应、纹理及序列化,并说明 `1.1.0-alpha03` 起可用的公开 Kotlin API。

主要功能

  1. 01BrushFamily 与多涂层结构
  2. 02触控笔和触摸行为节点树
  3. 03笔尖几何形状与绘制属性配置
  4. 04纹理图层与位图存储指导
  5. 05画笔定义的编码与解码

适用场景

  1. 01构建压力响应型自定义画笔
  2. 02创建书法或纹理笔刷
  3. 03将触控笔倾斜或速度映射为笔刷行为
  4. 04持久化自定义画笔定义

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/android/skills --skill ink-custom-brush-builder

安装后在 Claude Code 中输入/ink-custom-brush-builder确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
brush-behaviors.md
brush-structure.md
examples.md
textures-and-serialization.md
references/android/develop/ui/compose/touch-input/stylus-input/
ink-api-brush-apis.md

详细介绍

Android Ink API 中的自定义笔刷基于 BrushFamily 层次结构构建:

BrushFamily
├── InputModel (BrushFamily.InputModel.SlidingWindowModel 或 PASSTHROUGH_MODEL)
└── BrushCoat[](一个或多个渲染图层)
    ├── BrushTip(形状:scaleX、scaleY、cornerRounding、rotationDegrees、slantDegrees、pinch)
    │   └── BrushBehavior[](对触控笔或触摸输入的动态响应)
    │       └── Tree:TargetNode(input = [Operators](input = SourceNode))
    └── BrushPaint(视觉外观)
        ├── SelfOverlap(ANY、ACCUMULATE 或 DISCARD)
        ├── TextureLayer[](BrushPaint.TilingTexture 或 BrushPaint.StampingTexture)
        └── BrushPaint.ColorFunction[](OpacityMultiplier 或 ReplaceColor)

将自定义 BrushFamily 与 Compose Color、size 和 epsilon 组合, 创建一个 Brush:

val brush = Brush.createWithComposeColor(
    family = myCustomFamily,
    color = Color.Black,
    size = 10f,
    epsilon = 0.1f,
)

版本和实验性 API 要求:

  • 需要 androidx.ink 1.1.0-alpha03 或更高版本:在 1.0.0(稳定版) 和 1.1.0-alpha01-alpha02 中,BrushFamily(...)、BrushCoat、BrushTip、 BrushPaint、BrushBehavior 和 androidx.ink.brush.behavior.* 节点 均标记为 @RestrictTo(LIBRARY_GROUP)(在稳定版 1.0.0 中,自定义笔刷 只能通过 BrushFamily.decode 从二进制 proto 流加载)。 从 1.1.0-alpha03 或更高版本开始,以编程方式创建自定义笔刷的 构造函数已成为公共 API(BrushPaint.TilingTexture、 BrushPaint.StampingTexture、BrushPaint.ColorFunction、 BrushFamily.InputModel.SlidingWindowModel 以及所有行为节点)。
  • 1.1.0-alpha03 或更高版本无需 @OptIn:所有公共自定义笔刷类和 ink-storage 的 BrushFamily 序列化 API(BrushFamily.encode 和 decode、 AndroidBrushFamilySerialization、BrushFamilyDecodeCallback)在 1.1.0-alpha03 或更高版本中均未添加注解(ExperimentalInkCustomBrushApi 在 1.1.0-alpha05 或更高版本中标记为 @RestrictTo(LIBRARY_GROUP),且仅在 稳定版 1.0.0 中序列化 BrushFamily 时才需要)。

工作流与任务路由

根据请求的自定义笔刷任务,遵循以下条件说明:

  • 步骤 1(依赖项):为程序化自定义笔刷设置 Android 项目时,在编辑构建文件前征求用户许可,并确认 gradle/libs.versions.toml 和 app/build.gradle.kts 中的 androidx.ink:ink-brush、androidx.ink:ink-brush-compose、androidx.ink:ink-storage 和 androidx.ink:ink-nativeloader 使用的版本为 1.1.0-alpha03 或更高版本。
  • 步骤 2(层级、笔尖形状、绘制效果与输入平滑):定义 BrushFamily 和多层涂层 BrushCoat、配置 BrushTip 几何属性(scaleX、scaleY、cornerRounding、rotationDegrees、slantDegrees、pinch)、设置 BrushPaint 属性(SelfOverlap、ColorFunction),或使用 BrushFamily.InputModel.SlidingWindowModel 平滑笔画输入时,必须遵循 brush-structure.md。创建基础 Brush 或加载 1.0.0 资源时,请参阅 Brush API。
  • 步骤 3(动态手写笔和触摸行为):使用 BrushBehavior 节点树(SourceNode、DampingNode、NoiseNode、ResponseNode、TargetNode、PolarTargetNode)让笔刷根据手写笔压力、倾斜角度、速度、方向或程序化噪声动态响应时,必须遵循 brush-behaviors.md。
  • 步骤 4(纹理与序列化):添加 BrushPaint.TilingTexture 或 BrushPaint.StampingTexture 图层、实现 TextureBitmapStore,或编码和解码自定义 BrushFamily 定义(BrushFamily.encode 和 decode、AndroidBrushFamilySerialization、BrushFamilyDecodeCallback)时,必须遵循 textures-and-serialization.md。告知用户需要将哪些纹理图像文件(例如 app/src/main/res/drawable-nodpi/pencil_grain.png)添加到项目中,并在 TextureBitmapStore 中注册。
  • 步骤 5(完整笔刷配方):从零构建完整的压力感应笔、书法笔尖、阴影铅笔、水彩晕染笔刷或多层涂层阴影笔刷时,请从 examples.md 中可直接复制的实现开始。
  • Compose 绘图表面、橡皮擦或持久化:设置 Compose 绘图表面、使用 InProgressStrokes 进行湿笔画和干笔画渲染、基于几何形状擦除笔画或使用 Room 持久化笔画时,建议使用 ink-app-builder 技能。

反模式

  • 绝不要使用原始的 ink.proto.* 构建器来构造笔刷——始终使用公开的 Kotlin 构造函数(来自 androidx.ink.brush.* 的 BrushFamily、BrushCoat、BrushTip、BrushPaint、BrushBehavior)。
  • 绝不要在触摸监听器中手动缩放笔画宽度来实现压力或倾斜角度灵敏度——应使用 BrushBehavior,将 SourceNode.Source.NORMALIZED_PRESSURE 或 TILT_IN_RADIANS 映射到 TargetNode.Target.SIZE_MULTIPLIER 或 WIDTH_MULTIPLIER。
  • **绝不要使用手动 Canvas 位图盖印或 BitmapShader**来制作纹理笔刷——应使用带有 TextureBitmapStore 的 BrushPaint.TilingTexture 或 BrushPaint.StampingTexture。
  • 绝不要在最后一个(或唯一一个)TextureLayer 上使用 BlendMode.SRC_OVER——应使用 BlendMode.MODULATE、DST_IN、DST_OUT、SRC_ATOP 或 SRC_IN,以避免边缘抗锯齿和 OPACITY_MULTIPLIER 行为被覆盖。
  • 绝不要将 BrushFamily 序列化为 JSON、Gson、Moshi 或 Parcelable——始终使用 BrushFamily.encode 和 BrushFamily.decode,或使用来自 androidx.ink.storage 的 AndroidBrushFamilySerialization。
  • 绝不要手动实现贝塞尔曲线(quadTo、cubicTo)平滑——应配置 BrushFamily.InputModel.SlidingWindowModel 来平滑输入,并使用 DampingNode 来平滑行为。
  • **绝不要在绘制循环中使用 Random.nextFloat**来实现有机的笔画抖动——应在 BrushBehavior 中添加随笔画距离变化的 NoiseNode。

评论

支持 Markdown