گرادیانهای مش با استفاده از یک شبکه دوبعدی از تکهها، انتقال رنگهای پیچیده و چند جهته ایجاد میکنند. برخلاف گرادیانهای خطی یا شعاعی، گرادیانهای مش به آرامی رنگها را در یک شبکه درونیابی میکنند. از گرادیانهای مش برای ایجاد عناصر زیباییشناختی روان و ارگانیک در رابط کاربری خود استفاده کنید.

مفاهیم کلیدی
برای ساخت یک گرادیان مش، ابعاد شبکه، رئوس و انتقال رنگ بین نقاط را تعریف کنید:
- ابعاد شبکه: شبکه در امتداد محورهای عمودی و افقی به تکههایی تقسیم میشود. یک شبکه از
rowsوcolumnsشامل (ردیفها+۱)×(ستونها+۱) رأس است. به عنوان مثال، یک شبکه ۱×۱ از ۴ رأس تشکیل شده است که یک تکه را تشکیل میدهند. - مختصات نرمالشده: تمام موقعیتهای رأس از یک سیستم مختصات نرمالشده استفاده میکنند که در آن
(0f, 0f)نشان دهنده بالا-چپ و(1f, 1f)نشان دهنده پایین-راست مرزهای ترسیم است. - نقاط کنترل بزیه (مماسها): هر رأس شامل حداکثر چهار نقطه کنترل بزیه اختیاری است. این مماسها انحنای لبه بین رأسهای همسایه را مشخص میکنند. اگر
Offset.Unspecifiedاستفاده کنید، Compose مماسها را استنباط میکند تا انتقالهای نرم در سراسر تکهها تضمین شود. هر سلول شبکه که توسط ۴ رأس به همراه نقاط کنترل آنها تشکیل شده است، یک تکه بزیه ایجاد میکند. - درونیابی رنگ: این چارچوب، رنگهای بین رئوس اصلی را محاسبه میکند. برای درونیابی Catmull-Rom برای تغییر رنگهای نرمتر،
hasBicubicColorرا رویtrueو برای درونیابی دوخطی رویfalseتنظیم کنید.
با MeshGradientPainter نقاشی کنید
در Jetpack Compose، از MeshGradientPainter برای رندر کردن یک گرادیان مش استفاده کنید. MeshGradientPainter روی بوم نقاشی میکند.
یک گرادیان مش ساده ایجاد کنید
برای ایجاد یک گرادیان مش استاتیک پایه، با مشخص کردن ابعاد MeshGradientPainter و استفاده از تابع setVertex درون بلوک پیکربندی، آن را مقداردهی اولیه کنید تا نقاط گوشه خود را موقعیتیابی کرده و به آنها رنگ اختصاص دهید.
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) )

از نقاط کنترل خاص Bezier استفاده کنید
به طور پیشفرض، مولد مش محاسبات پیچیدهای را برای روان نگه داشتن انتقالهای شبکه انجام میدهد. با این حال، اگر میخواهید بخشهای رنگی خاصی را به صورت انتخابی فشار دهید، بکشید یا به شدت فشار دهید، میتوانید مماسها را روی هر رأس واحد به طور صریح سفارشی کنید.
انحرافات کنترلی نسبت به موقعیت رأس میزبان اندازهگیری میشوند.
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) )

ایجاد شبکههای پیشرفته
این مثال یک شبکه ۳ در ۳ را نشان میدهد، به این معنی که ۱۶ نقطه وجود دارد که باید مشخص شوند و نقاط میانی با انحرافهای مختلف تنظیم شدهاند:
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) // ... )

متحرک سازی یک گرادیان مش
از آنجا که پارامتر block لامبدا از MeshGradientPainter درون یک DrawScope اجرا میشود، میتواند حالتهای تغییرپذیر را بخواند و مشاهده کند. میتوانید موقعیتها یا رنگها را در طول زمان بدون تخصیص مجدد شیدرها یا بیتمپها متحرکسازی کنید.
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) )