ส่วนต่อไปนี้แสดงวิธีรวม 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, ) { // ... } }
ทำให้ขอบด้านซ้ายและขวาของตัวควบคุมแนวนอนจางลง
ในทำนองเดียวกัน หากต้องการดึงดูดความสนใจไปที่กึ่งกลางของคอมโพเนนต์ที่เลื่อนหรือลากได้ในแนวนอน เช่น ตัวเลือกวงล้อ ภาพสไลด์ หรือมาตราส่วน ให้ใช้ 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` // ... } // ... } } }
สร้างการเบลอแนวทแยงด้วย 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)) }, ) // ... } }
สร้างสปอตไลท์ที่โฟกัสด้วย 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), ) { // ... } }
สร้างมาสก์เบลอที่กำหนดเองด้วยเฉดสี
สำหรับการกระจายการเบลอเชิงพื้นที่ที่ซับซ้อนนอกเหนือจากการไล่ระดับสีเชิงเส้นหรือการไล่ระดับสีแบบรัศมี เช่น รูปแบบที่ซ้ำกัน รูปร่างที่กำหนดเอง หรือนอยส์เชิงกระบวนการ ให้ส่ง 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), ) }