Interfejsy Brush API

Interfejsy API Brush udostępniają narzędzia do definiowania stylu wizualnego pociągnięć. Możesz tworzyć pędzle o różnych kolorach, rozmiarach i rodzinach, aby uzyskać różne efekty.

Tworzenie pędzla

Aby utworzyć pędzel, użyj metod towarzyszących Compose Brush z nazwanymi argumentami, takimi jak Brush.Companion.createWithComposeColor. Ta klasa umożliwia ustawienie tych właściwości:

  • family: styl pędzla, analogiczny do kroju pisma lub czcionki w tekście. Dostępne wartości BrushFamily znajdziesz w StockBrushes.
  • color: kolor pędzla. Kolor możesz ustawić za pomocą ColorLong.
  • size: ogólna grubość pociągnięć utworzonych za pomocą pędzla.
  • epsilon: najmniejsza odległość, przy której 2 punkty powinny być uznawane za wizualnie odrębne na potrzeby geometrii generowania pociągnięć. Stosunek epsilonu do punktów pociągnięcia określa, jak bardzo można powiększyć pociągnięcie bez artefaktów, kosztem pamięci. Dobrym punktem wyjścia dla jednostek pociągnięcia jest 1 px, a dla epsilona – 0,1. Wyższe wartości epsilon zużywają mniej pamięci, ale pozwalają na mniejsze powiększenie, zanim pojawią się artefakty trójkątów. Eksperymentuj, aby znaleźć odpowiednią wartość dla swojego przypadku użycia.

val brush = Brush.createWithComposeColor(
    family = StockBrushes.pressurePen(),
    color = Color.Black,
    size = 5F,
    epsilon = 0.1F
)

Modyfikowanie właściwości pędzla

Możesz utworzyć kopię istniejącego pędzla za pomocą metody copyWithComposeColor(), która umożliwia zmianę dowolnych właściwości pędzla.

val redBrush = Brush.createWithComposeColor(
    family = StockBrushes.pressurePen(),
    color = Color.Red,
    size = 5F,
    epsilon = 0.1F
)

val blueBrush = redBrush.copyWithComposeColor(color = Color.Blue)

Pędzle niestandardowe

StockBrushes udostępnia wszechstronny zestaw popularnych pędzli, ale interfejs Ink API oferuje też zaawansowaną ścieżkę tworzenia zupełnie nowych zachowań pędzli, które pozwalają uzyskać unikalne efekty artystyczne lub odtworzyć konkretne istniejące pędzle w celu zapewnienia zgodności wstecznej.

Niestandardowy element BrushFamily jest wczytywany z formatu zserializowanego. Wymagany format to skompresowane gzipem kodowanie binarne bufora protokołu BrushFamily. Dzięki temu możesz już dziś wczytywać i używać niestandardowych plików pędzli. Po deserializacji niestandardowy obiekt BrushFamily może służyć do utworzenia nowego obiektu Brush o określonym kolorze i rozmiarze, tak jak w przypadku dowolnej rodziny StockBrushes.

class CustomBrushes(val context: Context) {

    companion object {
        private const val TAG = "CustomBrushes"
    }

    val brushes by lazy { loadCustomBrushes() }

    @OptIn(ExperimentalInkCustomBrushApi::class)
    private fun loadCustomBrushes(): List<CustomBrush> {
        val brushFiles = mapOf(
            "Calligraphy" to (R.raw.calligraphy to R.drawable.draw_24px),
            "Flag Banner" to (R.raw.flag_banner to R.drawable.flag_24px),
            "Graffiti" to (R.raw.graffiti to R.drawable.format_paint_24px),
            // ...
        )

        val loadedBrushes = brushFiles.mapNotNull { (name, pair) ->
            val (resourceId, icon) = pair
            val brushFamily = context.resources.openRawResource(resourceId).use { inputStream ->
                BrushFamily.decode(inputStream)
            }
            CustomBrush(name, icon, brushFamily)
        }
        return loadedBrushes
    }
}

data class CustomBrush(
    val name: String,
    val icon: Int,
    val brushFamily: BrushFamily
)