如何用React Native Skia实现带柔化过渡遮罩的图片模糊效果?
React Native Skia实现RestaurantCard流畅玻璃态模糊渐变效果
之前的硬裁剪、固定区域模糊方案无法实现平滑过渡,核心原因是这类方式只能创建边界生硬的模糊区域。要实现底部90px全模糊、向上逐渐消失的柔化效果,正确思路是通过Mask结合渐变控制模糊层的可见度,同时叠加渐变覆盖层,具体实现如下:
完整代码实现
import { Canvas, SkiaImage, Rect, LinearGradient, Mask, Blur, vec } from '@shopify/react-native-skia'; const RestaurantCard = ({ cardWidth, cardHeight, skiaImage }) => { // 底部全模糊区域高度 const fullBlurHeight = 90; // 模糊渐变过渡区域高度(数值越大过渡越平缓) const blurFadeHeight = 180; // 渐变起始Y坐标 const blurStartY = cardHeight - fullBlurHeight - blurFadeHeight; // 模糊层遮罩渐变:用#d9d9d9实现三站透明度过渡 const blurMaskGradient = LinearGradient( vec(0, blurStartY), vec(0, cardHeight), [ 'rgba(217, 217, 217, 0)', // 渐变顶部:完全透明(无模糊) 'rgba(217, 217, 217, 0)', // 过渡起点:保持透明 'rgba(217, 217, 217, 1)', // 过渡终点:完全不透明(全模糊) ], [0, 0.6, 1] // 渐变位置:0对应渐变起点,0.6对应全模糊区域起始点,1对应底部 ); // 半透明黑色覆盖层渐变:同步模糊过渡范围,最终40%不透明度 const overlayGradient = LinearGradient( vec(0, blurStartY), vec(0, cardHeight), [ 'rgba(0, 0, 0, 0)', // 渐变顶部:完全透明 'rgba(0, 0, 0, 0.2)', // 过渡中点:20%不透明度 'rgba(0, 0, 0, 0.4)', // 底部:40%不透明度 ], [0, 0.6, 1] ); return ( <Canvas style={{ flex: 1 }}> {/* 1. 渲染原始图片 */} <SkiaImage image={skiaImage} x={0} y={0} width={cardWidth} height={cardHeight} fit="cover" /> {/* 2. 渐变模糊层:用Mask控制模糊可见范围 */} <Mask mask={blurMaskGradient}> <Blur blur={10} mode="normal"> <SkiaImage image={skiaImage} x={0} y={0} width={cardWidth} height={cardHeight} fit="cover" /> </Blur> </Mask> {/* 3. 半透明黑色覆盖层 */} <Rect x={0} y={blurStartY} width={cardWidth} height={blurFadeHeight + fullBlurHeight}> {overlayGradient} </Rect> </Canvas> ); }; export default RestaurantCard;
关键逻辑说明
- 模糊层控制:
- 先对整张图片应用
Blur(模糊度10),再通过Mask组件结合自定义渐变,让模糊层从渐变起点开始向上完全透明(保留原图清晰),向下逐渐过渡到完全不透明(底部90px全模糊)。 - 渐变颜色使用
#d9d9d9的RGBA值,严格匹配你要求的三站渐变需求。
- 先对整张图片应用
- 覆盖层同步过渡:
- 单独创建矩形区域,应用和模糊层同方向的线性渐变,从完全透明过渡到40%不透明的黑色,强化玻璃态的层次感。
- 参数可调:
blurFadeHeight控制渐变过渡的平缓程度,fullBlurHeight控制底部全模糊区域的高度,可根据视觉需求灵活调整。
内容的提问来源于stack exchange,提问作者Mohammed Al Deek
相关产品推荐
相关产品推荐

