Örgü renk geçişleri, yamalardan oluşan bir 2D ızgara kullanarak karmaşık ve çok yönlü renk geçişleri oluşturur. Doğrusal veya radyal renk geçişlerinin aksine, örgü renk geçişleri renkleri bir ızgara üzerinde sorunsuz bir şekilde enterpolasyon yapar. Kullanıcı arayüzünüzde akıcı ve doğal estetik öğeler oluşturmak için örgü renk geçişlerini kullanın.
Temel kavramlar
Örgü renk geçişi oluşturmak için ızgara boyutlarını, köşe noktalarını ve noktalar arasındaki renk geçişlerini tanımlayın:
- Izgara boyutları: Ağ, dikey ve yatay eksenler boyunca yamalara bölünür.
rowsvecolumnsiçeren bir ızgara (satır+1)×(sütun+1) köşe içerir. Örneğin, 1x1 örgü, bir yama oluşturan 4 köşeden oluşur. - Normalleştirilmiş koordinatlar: Tüm köşe konumları,
(0f, 0f)'nin sol üstü ve(1f, 1f)'ün çizim sınırlarının sağ altını temsil ettiği normalleştirilmiş bir koordinat sistemi kullanır. - Bezier kontrol noktaları (teğetler): Her köşe, en fazla dört isteğe bağlı bezier kontrol noktası içerir. Bu teğetler, komşu köşeler arasındaki kenar eğriliğini belirtir.
Offset.Unspecifiedkullanırsanız Compose, yamalar arasında sorunsuz geçişler sağlamak için teğetleri çıkarır. 4 köşe ve kontrol noktalarıyla oluşturulan her ızgara hücresi, bir bezier yaması oluşturur. - Renk enterpolasyonu: Çerçeve, ana köşeler arasındaki renkleri hesaplar. Daha yumuşak renk geçişleri için Catmull-Rom
enterpolasyonu için
hasBicubicColordeğerinitrue, çift doğrusal enterpolasyon içinfalseolarak ayarlayın.
MeshGradientPainter ile çizim yapma
Jetpack Compose'da, ağ renk geçişi oluşturmak için
MeshGradientPainter
kullanın. MeshGradientPainter tuval üzerinde çizim yapıyor.
Basit bir örgü gradyanı oluşturma
Temel bir statik ağ gradyanı oluşturmak için boyutlarını belirterek bir MeshGradientPainter başlatın ve köşe noktalarınızı konumlandırıp onlara renk atamak için yapılandırma bloğunun içindeki setVertex işlevini kullanın.
val rows = 1 val columns = 1 val gradientPainter = remember { MeshGradientPainter(rows, columns) { // Parameters: row, column, position, color setVertex(0, 0, Offset(0f, 0f), Color.Red) // Top-Left setVertex(0, 1, Offset(1f, 0f), Color.Blue) // Top-Right setVertex(1, 0, Offset(0f, 1f), Color.Green) // Bottom-Left setVertex(1, 1, Offset(1f, 1f), Color.Yellow) // Bottom-Right } } Box( modifier = modifier .aspectRatio(16/9f) .fillMaxWidth() .paint(gradientPainter) )
Belirli Bezier kontrol noktalarını kullanma
Varsayılan olarak, ızgara geçişlerinin sorunsuz olması için örgü oluşturucu karmaşık hesaplamalar yapar. Ancak belirli renk bölümlerini seçerek itmek, çekmek veya keskin bir şekilde sıkıştırmak istiyorsanız herhangi bir tek tepe noktasındaki teğetleri açıkça özelleştirebilirsiniz.
Kontrol ofsetleri, ana köşe noktasının konumuna göre ölçülür.
val customTangentPainter = remember { MeshGradientPainter(rows = 1, columns = 1) { // Tweak the top-left vertex to curve outwards to the right and bottom setVertex( row = 0, column = 0, position = Offset(0f, 0f), color = Color.Magenta, rightControlPoint = Offset(0.4f, 0.1f), bottomControlPoint = Offset(0.1f, 0.4f) ) // Other points can remain unspecified to use default inferred fallback tangents setVertex(0, 1, Offset(1f, 0f), Color.Cyan) setVertex(1, 0, Offset(0f, 1f), Color.Blue) setVertex(1, 1, Offset(1f, 1f), Color.Black) } } Box( modifier = modifier .aspectRatio(16/9f) .fillMaxWidth() .paint(customTangentPainter) )
Gelişmiş kılavuzlar oluşturma
Bu örnekte 3x3 bir ızgara gösterilmektedir. Bu, ortadaki noktalar farklı uzaklıklarla ayarlanmış şekilde 16 noktanın belirtilmesi gerektiği anlamına gelir:
val points = remember { listOf( Offset(0.0f, 0.0f), Offset(0.3f, 0.0f), Offset(0.7f, 0.0f), Offset(1.0f, 0.0f), Offset(0.0f, 0.3f), Offset(0.2f, 0.4f), Offset(0.7f, 0.2f), Offset(1.0f, 0.3f), Offset(0.0f, 0.7f), Offset(0.3f, 0.8f), Offset(0.7f, 0.6f), Offset(1.0f, 0.7f), Offset(0.0f, 1.0f), Offset(0.3f, 1.0f), Offset(0.7f, 1.0f), Offset(1.0f, 1.0f) ) } val gradientPainter = remember { MeshGradientPainter(rows = 3, columns = 3) { // Row 0 setVertex(0, 0, points[0], yellow) setVertex(0, 1, points[1], orange) setVertex(0, 2, points[2], yellow) setVertex(0, 3, points[3], purple) // Row 1 setVertex(1, 0, points[4], pink) setVertex(1, 1, points[5], yellow) setVertex(1, 2, points[6], pink) setVertex(1, 3, points[7], purple) // Row 2 setVertex(2, 0, points[8], indigo) setVertex(2, 1, points[9], pink) setVertex(2, 2, points[10], purple) setVertex(2, 3, points[11], indigo) // Row 3 setVertex(3, 0, points[12], purple) setVertex(3, 1, points[13], indigo) setVertex(3, 2, points[14], pink) setVertex(3, 3, points[15], yellow) } } Box( modifier = modifier.padding(32.dp) .aspectRatio(16 / 9f) .fillMaxWidth() .paint(gradientPainter) // ... )
Örgü gradyanını canlandırma
MeshGradientPainter öğesinin block lambda parametresi DrawScope içinde yürütüldüğünden, değiştirilebilir durumu okuyabilir ve gözlemleyebilir. Gölgelendiricileri veya bit eşlemleri yeniden ayırmadan konumları ya da renkleri zaman içinde canlandırabilirsiniz.
val infiniteTransition = rememberInfiniteTransition(label = "meshMovement") val animatedOffset by infiniteTransition.animateFloat( initialValue = -0.1f, targetValue = 0.1f, animationSpec = infiniteRepeatable( animation = tween(2500, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "offset" ) val coral = Color(255, 90, 90) val peach = Color(255, 139, 90) val amber = Color(255, 169, 90) val sunshine = Color(255, 212, 90) val indigo = Color(0xFF5856D6) val pink = Color(0xFFFF2D55) val gradientPainter = remember { MeshGradientPainter(rows = 3, columns = 3) { // Row 0 setVertex(0, 0, Offset(0.0f, 0.0f), indigo) setVertex(0, 1, Offset(0.3f, 0.0f), peach) setVertex(0, 2, Offset(0.7f, 0.0f), amber) setVertex(0, 3, Offset(1.0f, 0.0f), sunshine) // Row 1 setVertex(1, 0, Offset(0.0f, 0.3f), pink) setVertex(1, 1, Offset(0.2f, 0.4f) + Offset(animatedOffset, animatedOffset), coral) setVertex(1, 2, Offset(0.7f, 0.2f) + Offset(animatedOffset, animatedOffset), peach) setVertex(1, 3, Offset(1.0f, 0.3f), indigo) // Row 2 setVertex(2, 0, Offset(0.0f, 0.7f), coral) setVertex(2, 1, Offset(0.3f, 0.8f) + Offset(animatedOffset, 0f), pink) setVertex(2, 2, Offset(0.7f, 0.6f) + Offset(animatedOffset, 0f), sunshine) setVertex(2, 3, Offset(1.0f, 0.7f), amber) // Row 3 setVertex(3, 0, Offset(0.0f, 1.0f), sunshine) setVertex(3, 1, Offset(0.3f, 1.0f), amber) setVertex(3, 2, Offset(0.7f, 1.0f), pink) setVertex(3, 3, Offset(1.0f, 1.0f), indigo) } } Box( modifier = modifier.padding(32.dp) .safeContentPadding() .aspectRatio(16 / 9f) .fillMaxWidth() .paint(gradientPainter) )