Compose'daki Brush
simgesi ekranda bir öğenin nasıl çizildiğini açıklar:
çizim alanında çizilen renkleri belirler (ör. bir daire,
kare, yol). Çizim için yararlı olan birkaç yerleşik fırça (ör. LinearGradient
, RadialGradient
veya düz SolidColor
fırça) vardır.
Fırçalar Modifier.background()
, TextStyle
veya
DrawScope
boyama stilini içeriğe uygulamak için çağrılar çizer
biraz farklıdır.
Örneğin, arka planda bir daire çizmek için yatay bir gradyan fırçası
DrawScope
:
val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) Canvas( modifier = Modifier.size(200.dp), onDraw = { drawCircle(brush) } )
Gradyan fırçaları
Farklı tasarımlar elde etmek için kullanabileceğiniz birçok yerleşik gradyan fırçası hoş geldiniz. Bu fırçalar, görmek istediğiniz renklerin listesini belirtmenize oluşturmak istiyorum.
Kullanılabilen gradyan fırçalarının listesi ve karşılık gelen çıkışları:
Gradyan Fırça Türü | Çıkış |
---|---|
Brush.horizontalGradient(colorList) |
|
Brush.linearGradient(colorList) |
|
Brush.verticalGradient(colorList) |
|
Brush.sweepGradient(colorList)
Not: Renkler arasında yumuşak bir geçiş elde etmek için son rengi başlangıç rengine ayarlayın. |
|
Brush.radialGradient(colorList) |
colorStops
ile renklerin dağılımını değiştirin
Renklerin renk geçişinde nasıl görüneceğini özelleştirmek için
Her biri için colorStops
değer. colorStops
, kesir olarak belirtilmelidir.
0 ile 1 arasında olmalıdır. 1'den büyük değerler bu renklerin oluşturulmamasına neden olur
olarak ayarlayabilirsiniz.
Renk duraklarını, bir rengin daha az veya daha fazla olması gibi farklı miktarlara sahip olacak şekilde yapılandırabilirsiniz:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) Box( modifier = Modifier .requiredSize(200.dp) .background(Brush.horizontalGradient(colorStops = colorStops)) )
Renkler, colorStop
içinde tanımlandığı şekilde sağlanan ofsette dağıtılır
sarı ve maviden daha az sarı olduğunu unutmayın.
TileMode
ile bir kalıbı tekrarlama
Her gradyan fırçasının üzerinde bir TileMode
ayarlama seçeneği vardır. Yapamazsınız
renk geçişi için bir başlangıç ve bitiş ayarlamadıysanız TileMode
varsayılan olarak tüm alanı dolduracaktır. TileMode
, yalnızca alanın boyutu fırça boyutundan büyükse degradeyi karolar.
endX
değeri yüksek olduğundan, aşağıdaki kod gradyan kalıbını 4 kez tekrarlayacaktır:
50.dp
olarak ve boyut 200.dp
olarak ayarlandı:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val tileSize = with(LocalDensity.current) { 50.dp.toPx() } Box( modifier = Modifier .requiredSize(200.dp) .background( Brush.horizontalGradient( listColors, endX = tileSize, tileMode = TileMode.Repeated ) ) )
Farklı karo modlarının
Yukarıda HorizontalGradient
örnek:
Döşeme Modu | Çıkış |
---|---|
TileMode.Repeated : Kenar, son renkten başa doğru tekrarlanır. |
|
TileMode.Mirror : Kenar, son renkten başa doğru yansıtılır. |
|
TileMode.Clamp : Kenar, son renge sabitlenmiş. Ardından bölgenin geri kalanına en yakın renge boyanır. |
|
TileMode.Decal : Yalnızca sınırların boyutuna kadar oluşturulur. TileMode.Decal , içeriği orijinal sınırların dışında örneklemek için şeffaf siyahtan yararlanırken, TileMode.Clamp kenar renginden örnekler alır. |
TileMode
, diğer yönlü gradyanlar için benzer şekilde çalışır. Tek fark, tekrarın gerçekleştiği yöndür.
Fırça Boyutunu Değiştir
Fırçanızın çizileceği alanın boyutunu biliyorsanız
endX
öğesini, yukarıdaki TileMode
bölümünde gördüğümüz gibi ayarlayın. Bir
DrawScope
ise alanın boyutunu öğrenmek için size
özelliğini kullanabilirsiniz.
Çizim alanınızın boyutunu bilmiyorsanız (örneğin
Brush
, Metin'e atandı) Shader
ve şu boyutta bir boyut kullanabilirsiniz:
createShader
işlevindeki çizim alanı.
Bu örnekte, kalıbı 4 kez tekrarlamak için boyutu 4'e bölün:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val customBrush = remember { object : ShaderBrush() { override fun createShader(size: Size): Shader { return LinearGradientShader( colors = listColors, from = Offset.Zero, to = Offset(size.width / 4f, 0f), tileMode = TileMode.Mirror ) } } } Box( modifier = Modifier .requiredSize(200.dp) .background(customBrush) )
Ayrıca, dairesel renk gibi başka bir renk geçişinin fırça boyutunu da değiştirebilirsiniz.
renk geçişlerini kullanabilirsiniz. Boyut ve merkez belirtmezseniz gradyan, DrawScope
öğesinin tüm sınırlarını kaplar ve radyal gradyanın merkezi varsayılan olarak DrawScope
sınırlarının ortasına yerleştirilir. Bu durumda dairesel renk geçişinin
ortadaki değer, daha küçük boyutun (genişlik veya
yükseklik):
Box( modifier = Modifier .fillMaxSize() .background( Brush.radialGradient( listOf(Color(0xFF2be4dc), Color(0xFF243484)) ) ) )
Yarıçap boyutunu maksimum boyuta ayarlamak için dairesel renk geçişi değiştirildiğinde, daha iyi bir dairesel gradyan efekti oluşturduğunu görebilirsiniz:
val largeRadialGradient = object : ShaderBrush() { override fun createShader(size: Size): Shader { val biggerDimension = maxOf(size.height, size.width) return RadialGradientShader( colors = listOf(Color(0xFF2be4dc), Color(0xFF243484)), center = size.center, radius = biggerDimension / 2f, colorStops = listOf(0f, 0.95f) ) } } Box( modifier = Modifier .fillMaxSize() .background(largeRadialGradient) )
Gölgelendiricinin oluşturulmasına iletilen gerçek boyutun, çağrıldığı yerden belirlendiğini belirtmek gerekir. Brush
varsayılan olarak şunları yapar:
boyutu öncekinden farklıysa Shader
öğesinin dahili olarak yeniden ayrılmasını
Brush
öğesinin oluşturulması veya gölgelendirici oluşturulurken kullanılan bir durum nesnesi
değiştirildi.
Aşağıdaki kod, gölgelendiriciyi farklı boyutlarla üç farklı kez oluşturur boyutunu değiştirme:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) val brush = Brush.horizontalGradient(colorStops = colorStops) Box( modifier = Modifier .requiredSize(200.dp) .drawBehind { drawRect(brush = brush) // will allocate a shader to occupy the 200 x 200 dp drawing area inset(10f) { /* Will allocate a shader to occupy the 180 x 180 dp drawing area as the inset scope reduces the drawing area by 10 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) inset(5f) { /* will allocate a shader to occupy the 170 x 170 dp drawing area as the inset scope reduces the drawing area by 5 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) } } } )
Bir resmi fırça olarak kullanma
ImageBitmap'i Brush
olarak kullanmak için resmi ImageBitmap
olarak yükleyin,
ve bir ImageShader
fırçası oluşturun:
val imageBrush = ShaderBrush(ImageShader(ImageBitmap.imageResource(id = R.drawable.dog))) // Use ImageShader Brush with background Box( modifier = Modifier .requiredSize(200.dp) .background(imageBrush) ) // Use ImageShader Brush with TextStyle Text( text = "Hello Android!", style = TextStyle( brush = imageBrush, fontWeight = FontWeight.ExtraBold, fontSize = 36.sp ) ) // Use ImageShader Brush with DrawScope#drawCircle() Canvas(onDraw = { drawCircle(imageBrush) }, modifier = Modifier.size(200.dp))
Fırça, birkaç farklı çizim türüne uygulanır: arka plan, metin ve kanvas. Bu işlem şu sonucu verir:
Metnin artık metni boyamak için ImageBitmap
kullanılarak da oluşturulduğuna dikkat edin.
piksel cinsinden belirtin.
Gelişmiş örnek: Özel fırça
AGSL RuntimeShader
fırçası
AGSL, GLSL Gölgelendirici özelliklerinin bir alt kümesini sunar. Gölgelendirici AGSL ile yazılmış ve Compose'da Fırçayla kullanılmış.
Bir gölgelendirici fırçası oluşturmak için önce gölgelendiriciyi AGSL gölgelendirici dizesi olarak tanımlayın:
@Language("AGSL") val CUSTOM_SHADER = """ uniform float2 resolution; layout(color) uniform half4 color; layout(color) uniform half4 color2; half4 main(in float2 fragCoord) { float2 uv = fragCoord/resolution.xy; float mixValue = distance(uv, vec2(0, 1)); return mix(color, color2, mixValue); } """.trimIndent()
Yukarıdaki gölgelendirici iki giriş rengi alır ve alttan mesafeyi hesaplar
çizim alanının solunda (vec2(0, 1)
) ve iki renk arasında mix
yapar
mesafeye göre değişir. Bu şekilde bir gradyan efekti oluşturulur.
Ardından, Gölgelendirici Fırçası'nı oluşturun ve resolution
için üniformaları ayarlayın - boyut
ve giriş olarak kullanmak istediğiniz color
ve color2
için
özel renk geçişiniz:
val Coral = Color(0xFFF3A397) val LightYellow = Color(0xFFF8EE94) @RequiresApi(Build.VERSION_CODES.TIRAMISU) @Composable @Preview fun ShaderBrushExample() { Box( modifier = Modifier .drawWithCache { val shader = RuntimeShader(CUSTOM_SHADER) val shaderBrush = ShaderBrush(shader) shader.setFloatUniform("resolution", size.width, size.height) onDrawBehind { shader.setColorUniform( "color", android.graphics.Color.valueOf( LightYellow.red, LightYellow.green, LightYellow .blue, LightYellow.alpha ) ) shader.setColorUniform( "color2", android.graphics.Color.valueOf( Coral.red, Coral.green, Coral.blue, Coral.alpha ) ) drawRect(shaderBrush) } } .fillMaxWidth() .height(200.dp) ) }
Bu komutu çalıştırdığınızda ekranda aşağıdakilerin oluşturulduğunu görebilirsiniz:
Gölgelendiricilerle, renk geçişlerinden çok daha fazlasını yapabileceğinizi belirtmekte fayda var. çünkü hepsi matematik tabanlı hesaplamalarda. AGSL hakkında daha fazla bilgi için AGSL dokümanlarına göz atın.
Ek kaynaklar
Oluşturma'da Fırça'yı kullanmayla ilgili daha fazla örnek için aşağıdaki kaynaklara göz atın:
- Oluştur'da fırçayla metin boyama 🖌️
- Compose'da Özel Grafikler ve Düzenler - Android Dev Summit 2022
- JetLagged Sample - RuntimeShader Fırçası
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Grafik Değiştiriciler
- Compose'daki grafikler
- Metni biçimlendirme