Oluşturma'daki Brush
, bir nesnenin ekranda nasıl çizildiğini tanımlar: Çizim alanında çizilen renkleri (ör. daire, kare, yol) belirler. Ç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, çizim stilini çizilen içeriğe uygulamak için Modifier.background()
, TextStyle
veya DrawScope
çizim çağrılarıyla kullanılabilir.
Örneğin, DrawScope
'te daire çizmek için yatay degrade fırçası uygulanabilir:
val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) Canvas( modifier = Modifier.size(200.dp), onDraw = { drawCircle(brush) } )
Gradyan fırçaları
Farklı degrade efektleri elde etmek için kullanılabilecek birçok yerleşik degrade fırçası vardır. Bu fırçalar, gradyan oluşturmak istediğiniz renklerin listesini belirtmenize olanak tanır.
Kullanılabilen degrade fırçalarının ve bunların çıktılarının listesi:
Gradyan Fırça Türü | Çıkış |
---|---|
Brush.horizontalGradient(colorList) |
|
Brush.linearGradient(colorList) |
|
Brush.verticalGradient(colorList) |
|
Brush.sweepGradient(colorList)
Not: Renkler arasında sorunsuz 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ştirme
Renklerin degradede nasıl görüneceğini özelleştirmek için her birinin colorStops
değerini değiştirebilirsiniz. colorStops
, 0 ile 1 arasında bir kesirli sayı olarak belirtilmelidir. 1'den büyük değerler, bu renklerin degradenin bir parçası olarak oluşturulmamasına neden olur.
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
çiftinde tanımlandığı gibi sağlanan ofsette dağıtılır ve kırmızı ve maviden daha az sarı olur.
TileMode
ile bir kalıbı tekrarlama
Her degrade fırçanın üzerine TileMode
ayarlama seçeneği vardır. Eğim için bir başlangıç ve bitiş noktası ayarlamadıysanız TileMode
simgesini fark etmeyebilirsiniz. Varsayılan olarak tüm alanı doldurur. TileMode
, yalnızca alanın boyutu fırça boyutundan büyükse degradeyi karolar.
endX
50.dp
olarak ve boyut 200.dp
olarak ayarlandığından aşağıdaki kod, degrade desenini 4 kez tekrarlar:
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 ) ) )
Aşağıda, farklı karo modlarının yukarıdaki HorizontalGradient
örneğinde ne yaptığını gösteren bir tablo verilmiştir:
TileMode | Çıkış |
---|---|
TileMode.Repeated : Kenar, son renkten ilk renge doğru tekrarlanır. |
|
TileMode.Mirror : Kenar, son renkten ilk renge doğru yansıtılır. |
|
TileMode.Clamp : Kenar, son renge sabitlenir. Ardından, bölgenin geri kalanı için en yakın rengi boyar. |
|
TileMode.Decal : Yalnızca sınırların boyutuna kadar oluşturulur. TileMode.Decal , orijinal sınırların dışındaki içeriği örneklemek için şeffaf siyahtan yararlanırken TileMode.Clamp kenar rengini örnekler. |
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ştirme
Fırçanızın çizileceği alanın boyutunu biliyorsanız endX
karosunu yukarıdaki TileMode
bölümünde gördüğümüz gibi ayarlayabilirsiniz. Bir DrawScope
içindeyseniz alanın boyutunu öğrenmek için size
mülkünü kullanabilirsiniz.
Çizim alanınızın boyutunu bilmiyorsanız (örneğin, Brush
metne atanmışsa) Shader
'ü genişletebilir ve createShader
işlevinde çizim alanının boyutunu kullanabilirsiniz.
Bu örnekte, deseni 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) )
Dairesel gradyanlar gibi diğer gradyanların fırça boyutunu da değiştirebilirsiniz. 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, radyal gradyanın merkezi daha küçük boyutun (genişlik veya yükseklik) merkezi olarak görünür:
Box( modifier = Modifier .fillMaxSize() .background( Brush.radialGradient( listOf(Color(0xFF2be4dc), Color(0xFF243484)) ) ) )
Dairesel gradyan, yarıçap boyutunu maksimum boyuta ayarlayacak şekilde 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. Varsayılan olarak Brush
, boyut Brush
'ün son oluşturulmasından farklıysa veya gölgelendiricinin oluşturulmasında kullanılan bir durum nesnesi değiştiyse Shader
'ünü dahili olarak yeniden ayarlar.
Aşağıdaki kod, çizim alanının boyutu değiştikçe gölgelendiriciyi üç farklı boyutta üç kez oluşturur:
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 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 sonucunda aşağıdakiler gösterilir:
Metnin artık pikselleri boyamak için ImageBitmap
kullanılarak da oluşturulduğunu unutmayın.
Gelişmiş örnek: Özel fırça
AGSL RuntimeShader
fırçası
AGSL, GLSL gölgelendirici özelliklerinin bir alt kümesini sunar. Gölgelendiriciler AGSL ile yazılabilir ve Oluştur'da bir fırçayla kullanılabilir.
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, çizim alanının sol alt kısmına (vec2(0, 1)
) olan mesafeyi hesaplar ve mesafeye göre iki renk arasında mix
yapar. Bu işlem, renk geçişi efekti oluşturur.
Ardından, Gölgelendirici Fırça'yı oluşturun ve resolution
(çizim alanının boyutu) ile özel degradenizin girişi olarak kullanmak istediğiniz color
ve color2
için tek tipleri ayarlayın:
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:
Tümüyle matematik tabanlı hesaplamalar olduğundan gölgelendiricilerle yalnızca gradyanlardan çok daha fazlasını yapabileceğinizi belirtmek isteriz. 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şturma bölümünde fırçayla metin renklendirmeyi animasyonlu hale getirme 🖌️
- Compose'da Özel Grafikler ve Düzenler - Android Dev Summit 2022
- JetLagged Sample - RuntimeShader Brush
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Grafik Değiştiricileri
- Oluşturma'daki grafikler
- Metin stili