กรณีการใช้งานทั่วไปของการเบลอ

ส่วนต่อไปนี้แสดงวิธีรวม Modifier.blur, BlurRadiusSpec, BlurStop และ BlurScope สำหรับรูปแบบ UI ทั่วไป ดูข้อมูลเบื้องต้นเกี่ยวกับ API เหล่านี้ได้ที่การเบลอใน Compose

เบลอขอบของเนื้อหาที่เลื่อนหรือลากได้

เมื่อแสดงรายการแบบเลื่อน ภาพสไลด์ หรือเครื่องมือเลือก คุณสามารถใช้การเบลอแบบต่อเนื่องหลายจุดเพื่อทำให้รายการที่อยู่ใกล้ขอบคอนเทนเนอร์ดูนุ่มนวลขึ้น ขณะเดียวกันก็ยังคงโฟกัสบริเวณตรงกลางที่ใช้งานอยู่ให้คมชัด

ทำให้ขอบด้านบนและด้านล่างของรายการที่เลื่อนได้จางลง

หากต้องการทำให้รายการดูนุ่มนวลขึ้นขณะเลื่อนเข้าและออกจากวิวพอร์ตของรายการแนวตั้ง ให้ใช้ BlurRadiusSpec.verticalGradient กับรายการ BlurStop ใน LazyColumn ในตัวอย่างต่อไปนี้ซึ่งเลื่อนเนื้อเพลงทีละบรรทัด 0.dp จะหยุดระหว่าง 0.42f และ 0.58f เพื่อให้บรรทัดที่ใช้งานอยู่ตรงกลางคมชัด ขณะที่บรรทัดด้านบนและด้านล่างจะค่อยๆ เบลอออก

@Composable
fun SongListTopBottomBlurExample(lyrics: List<String>) {
    // ...
    LazyColumn(
        state = listState,
        flingBehavior = flingBehavior,
        modifier = Modifier
            .width(330.dp)
            .height(480.dp)
            .padding(horizontal = 24.dp)
            .blur(
                blurRadiusSpec = BlurRadiusSpec.verticalGradient(
                    stops = listOf(
                        BlurStop(fraction = 0.00f, radius = 18.dp), // Heavily blurred top edge
                        BlurStop(fraction = 0.24f, radius = 8.dp), // Soft upper transition
                        BlurStop(fraction = 0.42f, radius = 0.dp), // Sharp center focus starts
                        BlurStop(fraction = 0.58f, radius = 0.dp), // Sharp center focus ends
                        BlurStop(fraction = 0.76f, radius = 8.dp), // Soft lower transition
                        BlurStop(fraction = 1.00f, radius = 18.dp), // Heavily blurred bottom edge
                    ),
                ),
                edgeTreatment = BlurredEdgeTreatment.Unbounded,
            ),
        contentPadding = PaddingValues(vertical = 36.dp),
        verticalArrangement = Arrangement.spacedBy(26.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        // ...
    }
}

รูปที่ 1 รายการบรรทัดเนื้อเพลงแนวตั้งที่บรรทัดบนและล่างเบลอและจางลง ขณะที่บรรทัดตรงกลางชัดเจน

ทำให้ขอบด้านซ้ายและขวาของตัวควบคุมแนวนอนจางลง

ในทำนองเดียวกัน หากต้องการดึงดูดความสนใจไปที่กึ่งกลางของคอมโพเนนต์ที่เลื่อนหรือลากได้ในแนวนอน เช่น ตัวเลือกวงล้อ ภาพสไลด์ หรือมาตราส่วน ให้ใช้ BlurRadiusSpec.horizontalGradient กับรายการ BlurStop ในเครื่องชั่งน้ำหนักแบบลากได้ต่อไปนี้ ขอบด้านซ้ายและขวาจะเบลอ ขณะที่ขีดและตัวเลขใกล้กับเข็มชี้ตรงกลางจะคมชัดอย่างสมบูรณ์

@Composable
fun HorizontalScaleBlurExample() {
    var selectedValue by remember { mutableFloatStateOf(65.0f) }
    val animatedValue by animateFloatAsState(
        targetValue = selectedValue,
        animationSpec = tween(durationMillis = 900, easing = FastOutSlowInEasing),
        label = "horizontalScaleSmoothScroll",
    )
    Column(
        modifier = Modifier
            .width(340.dp)
            .background(Color(0xFF0F172A), RoundedCornerShape(24.dp))
            .padding(vertical = 24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Text(
            text = "${(animatedValue * 10).roundToInt() / 10.0} kg",
            color = Color.White,
            fontSize = 44.sp,
            fontWeight = FontWeight.Black,
        )
        Spacer(Modifier.height(16.dp))
        Box(
            // ...
        ) {
            // Ruler ticks blurred at the left and right edges, sharp at center
            Canvas(
                modifier = Modifier
                    .fillMaxSize()
                    .blur(
                        blurRadiusSpec = BlurRadiusSpec.horizontalGradient(
                            stops = listOf(
                                BlurStop(fraction = 0.00f, radius = 14.dp),
                                BlurStop(fraction = 0.28f, radius = 0.dp),
                                BlurStop(fraction = 0.72f, radius = 0.dp),
                                BlurStop(fraction = 1.00f, radius = 14.dp),
                            ),
                        ),
                        edgeTreatment = BlurredEdgeTreatment.Unbounded,
                    ),
            ) {
                // Draw horizontal ruler ticks offset by `animatedValue`
                // ...
            }
            // ...
        }
    }
}

รูปที่ 2 วิดเจ็ตมาตรวัดไม้บรรทัดแนวนอนที่แสดงเครื่องหมายขีดแบบเบลอใกล้ขอบและเครื่องหมายขีดแบบคมชัดใกล้เข็มชี้

สร้างการเบลอแนวทแยงด้วย linearGradient

BlurRadiusSpec.linearGradient จะเปลี่ยนรัศมีการเบลอตามส่วนของเส้นตรงระหว่างค่า start และ end DpOffset ในพื้นที่พิกัดของเลเยอร์ ภายในบล็อก lambda Modifier.blur คุณสามารถอ่าน BlurScope.size เพื่อเรียกใช้การเบลอแบบไล่ระดับแนวทแยงในรูปภาพหลักจากมุมซ้ายบนไปยังมุมขวาล่าง โดยคงวัตถุที่มุมซ้ายบนให้คมชัดอย่างสมบูรณ์ ขณะเดียวกันก็เบลอพื้นที่ด้านขวาล่างหลังข้อความที่วางซ้อนกันแบบไล่ระดับ

@Composable
fun DiagonalLinearBlurCardExample() {
    Box(
        modifier = Modifier
            .wrapContentSize()
            .background(Color(0xFFF8FAFC))
            .padding(10.dp),
    ) {
        Image(
            painter = painterResource(id = R.drawable.dog),
            contentDescription = stringResource(id = R.string.dog_content_description),
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .size(width = 300.dp, height = 380.dp)
                .blur {
                    blurRadiusSpec = BlurRadiusSpec.linearGradient(
                        start = DpOffset(0.dp, 0.dp),
                        end = DpOffset(size.width, size.height),
                        stops = listOf(
                            BlurStop(fraction = 0.00f, radius = 0.dp),
                            BlurStop(fraction = 0.50f, radius = 0.dp),
                            BlurStop(fraction = 0.75f, radius = 14.dp),
                            BlurStop(fraction = 1.00f, radius = 28.dp),
                        ),
                    )
                    edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(24.dp))
                },
        )
        // ...
    }
}

ภาพสุนัขที่คมชัดที่มุมซ้ายบนและค่อยๆ เบลอไปทางมุมขวาล่าง โดยมีข้อความชื่อและคำบรรยายสีขาวคมชัดซ้อนทับบนบริเวณที่เบลอ
รูปที่ 3 ภาพสุนัขที่คมชัดที่มุมซ้ายบนและค่อยๆ เบลอไปทางมุมขวาล่าง โดยมีข้อความชื่อและคำบรรยายสีขาวที่คมชัดวางซ้อนอยู่บนบริเวณที่เบลอ

สร้างสปอตไลท์ที่โฟกัสด้วย radialGradient

BlurRadiusSpec.radialGradient สร้างเอฟเฟกต์สปอตไลท์วงกลมโดยการปรับรัศมีการเบลอออกจากจุดโฟกัส กำหนด center เป็น DpOffset และ fallOffRadius เป็นระยะทาง Dp จาก center ที่ไปถึง endRadius หากคุณปล่อย center ไว้เป็น DpOffset.Unspecified การไล่ระดับสีจะอยู่ตรงกลางของ Composable และหากคุณปล่อย fallOffRadius ไว้เป็น Dp.Unspecified ระบบจะใช้ค่าเริ่มต้นเป็นครึ่งหนึ่งของมิติข้อมูลที่เล็กกว่าของเลเยอร์

ตัวอย่างเช่น การใช้ BlurRadiusSpec.radialGradient กับข้อความและอัปเดต center จากเหตุการณ์การลากเคอร์เซอร์ช่วยให้ผู้ใช้ลากสปอตไลท์การอ่านทรงกลมไปตามย่อหน้าได้พร้อมกับเบลอข้อความโดยรอบ ดังที่แสดงในตัวอย่างต่อไปนี้

@Composable
fun RadialSpotlightTextExample() {
    var touchOffset by remember { mutableStateOf(Offset.Unspecified) }
    Box(
        modifier = Modifier
            .size(width = 330.dp, height = 340.dp)
            .background(Color(0xFF0F172A), RoundedCornerShape(20.dp))
            .pointerInput(Unit) {
                detectDragGestures(
                    onDragStart = { offset -> touchOffset = offset },
                    onDrag = { change, _ -> touchOffset = change.position },
                )
            }
            .blur {
                val spotlightCenter = if (touchOffset.isSpecified) {
                    DpOffset(touchOffset.x.toDp(), touchOffset.y.toDp())
                } else {
                    DpOffset(x = size.width / 2, y = size.height / 2)
                }
                blurRadiusSpec = BlurRadiusSpec.radialGradient(
                    startRadius = 0.dp,
                    endRadius = 10.dp,
                    center = spotlightCenter,
                    fallOffRadius = 215.dp,
                )
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(20.dp))
            }
            .padding(22.dp),
    ) {
        // ...
    }
}

รูปที่ 4 ย่อหน้าข้อความที่มีพื้นที่วงกลมของข้อความที่คมชัดรอบตัวชี้ ซึ่งจะค่อยๆ เบลอไปทางขอบของวงกลม

สร้างมาสก์เบลอที่กำหนดเองด้วยเฉดสี

สำหรับการกระจายการเบลอเชิงพื้นที่ที่ซับซ้อนนอกเหนือจากการไล่ระดับสีเชิงเส้นหรือการไล่ระดับสีแบบรัศมี เช่น รูปแบบที่ซ้ำกัน รูปร่างที่กำหนดเอง หรือนอยส์เชิงกระบวนการ ให้ส่ง Shader ที่กำหนดเอง เช่น AGSL RuntimeShader ไปยัง BlurRadiusSpec.shader เฉดสีจะประเมินในพิกัดพิกเซลของเลเยอร์จากจุดเริ่มต้นด้านซ้ายบน และช่องอัลฟาที่สุ่มตัวอย่าง (0..1) จะปรับขนาด maxRadius

สร้างตัวปรับเฉดสีและการกำหนดค่า BlurRadiusSpec.shader เพียงครั้งเดียวโดยใช้ฟังก์ชันที่ประกอบกันได้ remember เพื่อให้ระบบนำอินสแตนซ์เดียวมาใช้ซ้ำในการจัดองค์ประกอบใหม่ Compose จะเรียกใช้บล็อกการกำหนดค่าที่มีขนาดเลเยอร์ในการแก้ไขแต่ละครั้ง ซึ่งเป็นตำแหน่งที่คุณตั้งค่า Uniform ที่ขึ้นอยู่กับขนาด ดังนี้

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun ShaderBlurExample() {
    // Creates 6 diagonal frosted-glass bands across the image.
    val maskShader = remember {
        RuntimeShader(
            """
            uniform float2 size;
            half4 main(float2 coord) {
                float2 uv = coord / size;
                float band = smoothstep(0.4, 0.6, fract((uv.x + uv.y) * 3.0));
                return half4(0.0, 0.0, 0.0, half(band));
            }
            """.trimIndent(),
        )
    }
    val maskBlurSpec = remember(maskShader) {
        BlurRadiusSpec.shader(maxRadius = 24.dp) { sizePx ->
            maskShader.setFloatUniform("size", sizePx.width, sizePx.height)
            maskShader
        }
    }
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(blurRadiusSpec = maskBlurSpec),
    )
}

รูปภาพสุนัขที่มีแถบเบลอแบบกระจกฝ้าแนวทแยงซึ่งขับเคลื่อนโดยมาสก์ตัวปรับเฉดสีที่กำหนดเอง
รูปที่ 5 รูปภาพสุนัขที่มีแถบเบลอแบบกระจกฝ้าแนวทแยงซึ่งขับเคลื่อนโดยมาสก์ตัวปรับเฉดสีที่กำหนดเอง