API кистей

API Brush предоставляют инструменты для определения визуального стиля штрихов. Вы можете создавать кисти разных цветов, размеров и семейств, чтобы добиться разнообразного внешнего вида.

Создать кисть

Чтобы создать кисть, используйте сопутствующие методы Compose Brush с именованными аргументами, такими как Brush.Companion.createWithComposeColor. Этот класс позволяет задать следующие свойства:

  • family – стиль кисти, аналогичный гарнитуре или шрифту в тексте. Возможные значения BrushFamily приведены в разделе StockBrushes.
  • color – цвет кисти. Цвет можно задать с помощью объекта ColorLong.
  • size – общая толщина штрихов, созданных кистью.
  • epsilon – наименьшее расстояние, при котором две точки должны считаться визуально различимыми для целей геометрии генерации штрихов. Соотношение эпсилона и точек штриха определяет, насколько можно увеличить штрих без артефактов, за счет памяти. Рекомендуем начать с 1 пикселя для единиц штриха и 0, 1 для эпсилона. Чем выше значение эпсилон, тем меньше памяти используется, но тем раньше появляются артефакты в виде треугольников при увеличении масштаба. Поэкспериментируйте, чтобы найти подходящее значение для вашего случая.

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

Изменение свойств кисти

Вы можете создать копию существующей кисти с помощью метода copyWithComposeColor(), который позволяет изменить любое из свойств кисти.

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

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

Пользовательские кисти

Хотя StockBrushes предоставляет универсальный набор стандартных кистей, Ink API также предлагает расширенный путь для создания совершенно новых поведений кистей для уникальных художественных эффектов или для репликации определенных существующих кистей для обратной совместимости.

Специальный объект BrushFamily загружается из сериализованного формата. Требуемый формат – двоичная кодировка буфера протокола BrushFamily, сжатая с помощью gzip. Это позволяет загружать и использовать файлы пользовательских кистей уже сегодня. После десериализации специальный объект BrushFamily можно использовать для создания нового объекта Brush с определенным цветом и размером, как и любое из семейств 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
)