محو کردن در Compose

جلوه‌های محو کردن جزئیات دیداری را نرم می‌کنند، عمق میدان عکاسی ایجاد می‌کنند، و تمرکز را به عناصر میانای کاربر در پیش‌زمینه جلب می‌کنند. در Jetpack Compose، از Modifier.blur برای محو کردن محتوای ترسیم‌شده در داخل یک composable، ازجمله تصاویر، اشکال، نوشتار، و محفظه‌های چیدمان استفاده کنید. اعمال Modifier.blur باعث می‌شود ترکیب‌پذیر در لایه گرافیکی جداگانه‌ای رندر شود.

سمت راست: تصویر اصلی. مرکز: تصویر با تاری یکنواخت اعمال‌شده در کل سطح. سمت چپ: تصویر با محوی تدریجی که در بالا واضح است و به‌سمت پایین افزایش می‌یابد.
شکل ۱. سمت راست: تصویر اصلی. مرکز: تصویر با تاری یکنواخت اعمال‌شده در کل سطح. سمت چپ: تصویر با محوی تدریجی که در بالا واضح است و به‌سمت پایین افزایش می‌یابد.

بسته به اهداف طراحی‌تان، می‌توانید محوشدگی را به دو روش تغییر دهید:

  • محو کردن یکنواخت: شعاع محو کردن ثابتی را در کل ترکیب‌پذیر اعمال می‌کند، چه به‌طور مساوی در هر دو محور یا با شعاع‌های افقی و عمودی مستقل (radiusX، radiusY).
  • محو کردن تدریجی: شعاع محو کردن را به‌صورت فضایی در سراسر ترکیب‌پذیر بااستفاده از شیب‌های رنگی BlurRadiusSpec یا Shader سفارشی تغییر می‌دهد.

اعمال کردن محو کردن یکنواخت

برای اعمال محوی ثابت در کل composable، شعاع Dp را به Modifier.blur ارسال کنید. یک مقدار radius را برای محو کردن یکسان محتوا در امتداد محورهای افقی (X) و عمودی (Y) ارسال کنید:

@Composable
fun UniformBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                radius = 8.dp,
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

سگی که به‌طور یکنواخت در هر دو محور افقی و عمودی محو شده است.
شکل ۲. سگی که به‌طور یکنواخت در هر دو محور افقی و عمودی محو شده است.

برای ایجاد جلوه محوشدگی حرکتی جهت‌دار، مقادیر radiusX و radiusY جداگانه‌ای را به Modifier.blur ارسال کنید. برای اعمال جلوه محو کردن، هر دو radiusX و radiusY باید بزرگ‌تر از 0.dp باشند، همان‌طور که در مثال زیر نشان داده شده است:

@Composable
fun DirectionalBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                radiusX = 10.dp,
                radiusY = 2.dp,
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

سگی با جلوه محو کردن حرکت افقی قوی.
شکل ۳.‏ تصویر مربعی از سگی با جلوه محوشدگی حرکتی افقی قوی.

اعمال کردن محوی تدریجی

محو کردن تدریجی شعاع محو کردن را در سراسر یک ترکیب‌پذیر تغییر می‌دهد و یک گذار روان بین مناطق واضح و محو ایجاد می‌کند.

BlurRadiusSpec را به Modifier.blur بدهید. برای مثال، از BlurRadiusSpec.verticalGradient با startRadius = 0.dp و endRadius = 6.dp استفاده کنید تا بالای تصویر واضح بماند و به‌تدریج به‌سمت پایین محو شود، همان‌طور که در مثال زیر نشان داده شده است:

@Composable
fun ProgressiveBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                // Sharp at the top (0.dp), progressively blurred toward the bottom (6.dp)
                blurRadiusSpec = BlurRadiusSpec.verticalGradient(
                    startRadius = 0.dp,
                    endRadius = 6.dp,
                ),
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

سگی که در بالا واضح است و به‌تدریج در پایین محو می‌شود.
شکل ۴. تصویری از یک سگ که در بالا واضح است و به‌تدریج در پایین محو می‌شود.

مشخص کردن گرادیان‌های محو با BlurRadiusSpec

در BlurRadiusSpec، اندازه‌گیری‌ها در Dp تنظیم می‌شوند و به‌طور خودکار با اندازه لایه و تراکم نمایش هنگام ترسیم تنظیم می‌شوند. محوشدگی‌های متغیر فضایی پس‌از تبدیل به ۱۵۰ پیکسل محدود می‌شوند، درحالی‌که BlurRadiusSpec.uniform محدودیتی ندارد.

جدول زیر عملکردهای کارخانه‌ای دردسترس در BlurRadiusSpec را فهرست می‌کند:

کارخانه BlurRadiusSpec شرح
BlurRadiusSpec.verticalGradient شعاع محوشدگی را به‌صورت عمودی از بالا (0f) به پایین (1f) در سراسر لایه به‌آرامی تغییر می‌دهد.
BlurRadiusSpec.horizontalGradient شعاع محوشدگی را به‌آرامی به‌صورت افقی از لبه چپ (0f) به لبه راست (1f) تغییر می‌دهد.
BlurRadiusSpec.linearGradient گذار محو جهت‌دار را در امتداد خط مستقیمی که مختصات DpOffset خاصی را به هم متصل می‌کند اعمال می‌کند.
BlurRadiusSpec.radialGradient ماتی را از نقطه کانونی به‌سمت مرز fallOffRadius پخش می‌کند.
BlurRadiusSpec.uniform شعاع محوی یکسانی را در کل لایه اعمال می‌کند.
BlurRadiusSpec.shader از کانال آلفای Shader سفارشی برای کنترل و مقیاس‌بندی maxRadius در هر پیکسل استفاده می‌کند.

سفارشی‌سازی توزیع محو کردن با BlurStop

محوشدگی‌های گرادیان استاندارد به‌صورت خطی بین 0f و 1f درون‌یابی می‌شوند. برای سفارشی‌سازی توزیع محو کردن در سراسر یک سطح، مانند محو کردن چندین لبه یا کاملاً واضح نگه داشتن بخش میانی، یک List<BlurStop> حاوی ۲ تا ۱۶ ورودی BlurStop را به verticalGradient، horizontalGradient، linearGradient، یا radialGradient ارسال کنید. برای هر ورودی BlurStop، موارد زیر را تعریف کنید:

  • fraction: موقعیت نسبی درطول گرادیان از 0.0f تا 1.0f. ایستگاه‌ها به‌طور خودکار براساس کسر مرتب می‌شوند.
  • radius: شعاع محو شدن در Dp که در آن موقعیت کسری اعمال شده است.

برای مثال، چهار توقف لبه‌های بالا و پایین تصویر را محو می‌کند، درحالی‌که وسط تصویر کاملاً واضح باقی می‌ماند، همان‌طور که در مثال زیر نشان داده شده است:

@Composable
fun MultiStopBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                // Blurred at the top and bottom edges, sharp in the middle (0.3f..0.7f)
                blurRadiusSpec = BlurRadiusSpec.verticalGradient(
                    stops = listOf(
                        BlurStop(fraction = 0.0f, radius = 20.dp),
                        BlurStop(fraction = 0.3f, radius = 0.dp),
                        BlurStop(fraction = 0.7f, radius = 0.dp),
                        BlurStop(fraction = 1.0f, radius = 20.dp),
                    ),
                ),
                edgeTreatment = BlurredEdgeTreatment.Unbounded,
            ),
    )
}

سگی با لبه‌های بالا و پایین محوشده، درحالی‌که نوار افقی میانی در کانون واضح قرار دارد.
شکل ۵. تصویری از یک سگ با لبه‌های بالا و پایین محوشده، درحالی‌که نوار افقی میانی در فوکوس واضح قرار دارد.

پیکربندی ویژگی‌های لایه با BlurScope

به‌جای ارسال مستقیم blurRadiusSpec، می‌توانید یک بلوک پیکربندی را به Modifier.blur { ... } ارسال کنید. این بلوک در BlurScope اجرا می‌شود، که به شما دسترسی مستقیم به تراکم چیدمان و ویژگی‌های زیر را می‌دهد:

  • size: DpSize: عرض و ارتفاع اندازه‌گیری‌شده لایه محوشده در Dp، که فضای مختصات را برای هندسه گرادیان تعریف می‌کند.
  • ‫blurRadiusSpec: BlurRadiusSpec: پیکربندی شعاع محو شدن در سراسر سطح. پیش‌فرض‌ها به BlurRadiusSpec.uniform(0.dp) (بدون محو کردن).
  • edgeTreatment: BlurredEdgeTreatment: استراتژی مورداستفاده برای نمونه‌برداری و برش پیکسل‌های خارج از مرزهای محتوا. پیش‌فرض‌ها به BlurredEdgeTreatment.Rectangle.
  • alpha: Float: ماتی لایه محوشده در محدوده 0f..1f. پیش‌فرض‌ها به 1f.

چون بلوک BlurScope درطول فاز لایه گرافیکی، پس‌از اندازه‌گیری و چیدمان، اجرا می‌شود، می‌توانید هندسه گرادیان را از size بدون راه‌اندازی بازترکیب محاسبه کنید.

کنترل برش لبه با BlurredEdgeTreatment

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

BlurredEdgeTreatment با هر دو محو کردن یکنواخت و تدریجی کار می‌کند:

BlurredEdgeTreatment رفتار خروجی
‫BlurredEdgeTreatment.Rectangle (پیش‌فرض) نتیجه محو کردن را به مرزهای مستطیلی محتوای اصلی برش می‌دهد و نزدیک‌ترین پیکسل‌های لبه را نمونه‌برداری می‌کند (TileMode.Clamp). تصویر محو سگی که در یک مرز مستطیلی واضح برش خورده است.
BlurredEdgeTreatment(shape) نتیجه محوشدگی را به Shape مشخص‌شده (مانند RoundedCornerShape(8.dp)) برش می‌دهد و نزدیک‌ترین پیکسل‌های لبه (TileMode.Clamp) را نمونه‌برداری می‌کند. نتیجه محوشدگی را در مرز شکل واضح نگه می‌دارد بدون اینکه از مرزهای اصلی فراتر رود. تصویر محو سگی که به شکل گوشه گرد با لبه‌های تیز برش خورده است.
BlurredEdgeTreatment.Unbounded نتیجه محو کردن (TileMode.Decal) را برش نمی‌دهد. پیکسل‌های خارج از محدوده محتوا، سیاه شفاف را نمونه‌برداری می‌کنند و باعث می‌شوند لبه‌های بیرونی تصویر فراتر از محدوده‌های اصلی، محو و تار به‌نظر برسند. تصویر محو سگی که لبه‌های آن به‌آرامی فراتر از مرزهای اصلی محو می‌شود.

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