Jetpack Compose Canvas如何绘制带霓虹渐变描边的圆角矩形
Jetpack Compose 绘制红-白-红渐变霓虹描边圆角矩形方案
核心实现逻辑
- 保证轮廓规整:全程使用Compose Canvas内置的
drawRoundRect原生API绘制,不自定义手绘路径,描边模式设为Stroke,最终效果和原生绘制的圆角矩形轮廓完全一致,无手绘质感偏差。 - 渐变描边实现:通过
Brush配置红→白→红渐变,默认提供水平线性渐变实现,可按需替换为扫掠渐变实现沿轮廓环绕的渐变效果。 - 霓虹发光效果:分层绘制,底层先画大宽度、高斯模糊的半透明描边作为外发光层,上层叠加小宽度、无模糊的清晰描边作为轮廓主体,两层叠加即可得到通透的霓虹发光效果。
可直接复用的实现代码
import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.PaintingStyle import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @Composable fun NeonOutlineRoundRect( modifier: Modifier = Modifier, cornerRadius: Dp = 16.dp, mainStrokeWidth: Dp = 4.dp, glowStrokeWidth: Dp = 12.dp, glowBlurRadius: Dp = 8.dp ) { val density = LocalDensity.current // 提前转换dp为px,避免绘制过程重复计算 val cornerRadiusPx = with(density) { cornerRadius.toPx() } val mainStrokePx = with(density) { mainStrokeWidth.toPx() } val glowStrokePx = with(density) { glowStrokeWidth.toPx() } val blurRadiusPx = with(density) { glowBlurRadius.toPx() } Canvas(modifier = modifier) { // 红-白-红水平线性渐变,需要沿轮廓环绕的话替换为Brush.sweepGradient即可 val neonGradient = Brush.linearGradient( colors = listOf(Color(0xFFFF0000), Color(0xFFFFFFFF), Color(0xFFFF0000)), start = Offset(0f, size.height / 2), end = Offset(size.width, size.height / 2) ) // 绘制外发光层 val glowPaint = Paint().apply { style = PaintingStyle.Stroke strokeWidth = glowStrokePx shader = neonGradient.asShader() alpha = 0.6f // 配置高斯模糊实现发光扩散效果 asFrameworkPaint().maskFilter = android.graphics.BlurMaskFilter( blurRadiusPx, android.graphics.BlurMaskFilter.Blur.NORMAL ) } drawIntoCanvas { canvas -> canvas.drawRoundRect( left = 0f, top = 0f, right = size.width, bottom = size.height, radiusX = cornerRadiusPx, radiusY = cornerRadiusPx, paint = glowPaint ) } // 绘制上层清晰轮廓,保证边缘锐利规整 drawRoundRect( brush = neonGradient, topLeft = Offset.Zero, size = size, cornerRadius = CornerRadius(cornerRadiusPx, cornerRadiusPx), style = Stroke(width = mainStrokePx), blendMode = BlendMode.SrcOver ) } } // 调用示例 // NeonOutlineRoundRect(modifier = Modifier.size(240.dp, 120.dp))
调整说明
- 如果需要渐变沿圆角矩形轮廓环绕流动,将
linearGradient替换为Brush.sweepGradient,把渐变中心点设为矩形中心即可。 - 可根据实际视觉需求调整
cornerRadius(圆角大小)、mainStrokeWidth(主体描边宽度)、glowStrokeWidth(发光层宽度)、glowBlurRadius(发光模糊程度)四个参数,外发光层的alpha值也可以按需修改,数值越高发光越亮。 - 如果需要更强的发光层次感,可以在外发光层下方再加一层更宽、模糊度更高、透明度更低的发光层,霓虹效果会更真实。
- 该实现完全基于官方原生绘制API,不存在自定义路径的边缘误差,轮廓和原生
drawRoundRect绘制的填充圆角矩形边缘完全对齐。
内容的提问来源于stack exchange,提问作者chrrissoft
相关产品推荐
相关产品推荐

