mcpField
I
ink-custom-brush-builder

ink-custom-brush-builder

github.com/android開発10.0k47 回インストール2 日前に更新
リポジトリ

ink-custom-brush-builder について

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[] (1 つ以上のレンダリングレイヤー)
    ├── 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、およびすべての behavior ノード)。
  • 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 に従ってください。ユーザーのプロジェクトに追加し、TextureBitmapStore に登録するテクスチャ画像ファイル(app/src/main/res/drawable-nodpi/pencil_grain.png など)をユーザーに伝えてください。
  • ステップ 5(ブラシの完全なレシピ):筆圧対応のペン、カリグラフィー用ペン先、陰影用鉛筆、水彩のにじみ、または複数のコートから成るシャドウブラシを一から作成する場合は、examples.md にあるコピーしてすぐ使える実装を出発点にしてください。
  • Compose の描画サーフェス、消しゴム、または永続化:Compose の描画サーフェスのセットアップ、InProgressStrokes のウェット/ドライ描画、ジオメトリベースの消去、または Room によるストロークの永続化については、ink-app-builder スキルを提案してください。

避けるべきパターン

  • ブラシの構築に raw 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 を絶対に使用しないでください――エッジのアンチエイリアスや OPACITY_MULTIPLIER の動作が上書きされないよう、BlendMode.MODULATE、DST_IN、DST_OUT、SRC_ATOP、または SRC_IN を使用してください。
  • BrushFamily を JSON、Gson、Moshi、または Parcelable としてシリアル化しないでください――必ず BrushFamily.encode と BrushFamily.decode、または androidx.ink.storage の AndroidBrushFamilySerialization を使用してください。
  • 手動でベジェ曲線(quadTo、cubicTo)の平滑化を実装しないでください――入力の平滑化には BrushFamily.InputModel.SlidingWindowModel を、動作の平滑化には DampingNode を設定してください。
  • 有機的なストロークの揺らぎを加えるために、描画ループ内で Random.nextFloat を使用しないでください――BrushBehavior でストローク距離に応じて変化する NoiseNode を追加してください。

コメント