模糊
动画效果可以丰富界面的细节,提升UI界面的真实感和品质感。例如,模糊和阴影效果可以让物体看起来更加立体,使得动画更加生动。ArkUI提供了丰富的效果接口,开发者可快速打造出精致、个性化的效果。本章主要介绍常用的模糊、阴影和色彩效果等接口。
模糊效果可以体现界面空间的纵深感,区分前后元素的层级关系。
| 接口 | 说明 |
|---|---|
| backdropBlur | 为当前组件添加背景模糊效果,入参为模糊半径。 |
| blur | 为当前组件添加内容模糊效果,入参为模糊半径。 |
| backgroundBlurStyle | 为当前组件添加背景模糊效果,入参为模糊样式。 |
| foregroundBlurStyle | 为当前组件添加内容模糊效果,入参为模糊样式。 |
| motionBlur | 为当前组件添加由缩放大小或位移变化引起的运动过程中的动态模糊效果,入参为模糊半径和锚点坐标。 |
以上接口均为实时模糊接口,每帧执行实时渲染,性能负载较大。当模糊内容与模糊半径均无需变动时,推荐采用静态模糊接口blur。最佳实践请参考:图像模糊动效优化-使用场景。
使用backdropBlur为组件添加背景模糊
@Entry
@Component
struct BlurEffectsExample {
build() {
Column({ space: 10 }) {
Text('backdropBlur')
.width('90%')
.height('90%')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.backdropBlur(10)// 对背景进行模糊
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundImageSize({ width: 400, height: 300 })
}
.width('100%')
.height('50%')
.margin({ top: 20 })
}
}

使用blur为组件添加内容模糊
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct Index {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
@State radius: number = 0;
@State text: string = '';
@State y: Resource | string = this.context.resourceManager.getStringSync($r('app.string.animation_blur_text1').id);// 请在resources\base\element\string.json文件中配置name为'animation_blur_text1',value为非空字符串的资源
aboutToAppear() {
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text2',value为非空字符串的资源
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text3',value为非空字符串的资源
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text4',value为非空字符串的资源
this.text = this.context.resourceManager.getStringSync($r('app.string.animation_blur_text2').id) +
"\n" + this.context.resourceManager.getStringSync($r('app.string.animation_blur_text3').id) + this.y +
"\n" + this.context.resourceManager.getStringSync($r('app.string.animation_blur_text4').id) + this.radius;
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Text(this.text)
.height(200)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontFamily("cursive")
.fontStyle(FontStyle.Italic)
// 请将$r('app.media.bg')替换为实际资源文件
Image($r("app.media.bg"))
.blur(this.radius)// 使用blur接口为照片组件添加内容模糊效果
.height('100%')
.width("100%")
.objectFit(ImageFit.Cover)
}.height('100%')
.width("100%")
.onTouch((event?: TouchEvent) => {
if (event) {
if (event.type === TouchType.Move) {
this.y = Number(event.touches[0].y.toString()).toString();
this.radius = Number(this.y) / 10; // 根据跟手过程中的滑动距离修改模糊半径,配合模糊接口,形成跟手模糊效果
}
if (event.type === TouchType.Up) {
this.radius = 0;
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text1',value为非空字符串的资源
this.y = this.context.resourceManager.getStringSync($r('app.string.animation_blur_text1').id);
}
}
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text2',value为非空字符串的资源
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text3',value为非空字符串的资源
// 请在resources\base\element\string.json文件中配置name为'animation_blur_text4',value为非空字符串的资源
this.text = this.context.resourceManager.getStringSync($r('app.string.animation_blur_text2').id) + "\n" + this.context.resourceManager.getStringSync($r('app.string.animation_blur_text3').id) + this.y +
"\n" + this.context.resourceManager.getStringSync($r('app.string.animation_blur_text4').id) + this.radius;
})
}
}

使用backgroundBlurStyle为组件添加背景模糊效果
@Entry
@Component
struct BackDropBlurStyleDemo {
build() {
Grid() {
GridItem() {
Column() {
Column() {
// 请将$r('app.string.originalImage')替换为实际资源文件,在本示例中该资源文件的value值为"原图"
Text($r('app.string.originalImage'))
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
// 请将$r('app.string.originalImage')替换为实际资源文件,在本示例中该资源文件的value值为"原图"
Text($r('app.string.originalImage'))
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.margin({ top: 20 })
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Thin')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
// BlurStyle.Thin: 为组件添加轻薄材质模糊效果
// ThemeColorMode.LIGHT: 固定使用浅色模式效果
// AdaptiveColor.DEFAULT: 不使用取色模糊,使用默认的颜色作为蒙版颜色
// scale: 背景材质模糊效果程度,默认值是1
.backgroundBlurStyle(BlurStyle.Thin, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Thin')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.margin({ top: 20 })
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Regular')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.Regular, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Regular')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Thick')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.Thick, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Thick')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_THIN')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.BACKGROUND_THIN, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_THIN')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_REGULAR')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.BACKGROUND_REGULAR, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_REGULAR')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_THICK')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.BACKGROUND_THICK, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_THICK')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_ULTRA_THICK')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_ULTRA_THICK')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
}
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.width('100%')
.height('100%')
.margin({ top: 40 })
}
}

使用foregroundBlurStyle为组件添加内容模糊效果
@Entry
@Component
struct ForegroundBlurStyleDemo {
build() {
Grid() {
GridItem() {
Column() {
Column() {
// 请将$r('app.string.originalImage')替换为实际资源文件,在本示例中该资源文件的value值为"原图"
Text($r('app.string.originalImage'))
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
// 请将$r('app.string.originalImage')替换为实际资源文件,在本示例中该资源文件的value值为"原图"
Text($r('app.string.originalImage'))
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Thin')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
// BlurStyle.Thin: 为组件添加轻薄材质模糊效果
// ThemeColorMode.LIGHT: 固定使用浅色模式效果
// AdaptiveColor.DEFAULT: 不使用取色模糊,使用默认的颜色作为蒙版颜色
// scale: 背景材质模糊效果程度,默认值是1
.foregroundBlurStyle(BlurStyle.Thin, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Thin')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Regular')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.Regular, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Regular')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('Thick')
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.Thick, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('Thick')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_THIN')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.BACKGROUND_THIN, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_THIN')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_REGULAR')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.BACKGROUND_REGULAR, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_REGULAR')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_THICK')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.BACKGROUND_THICK, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_THICK')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
GridItem() {
Column() {
Column() {
Text('BACKGROUND_ULTRA_THICK')
.fontSize(12)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width('100%')
.height('100%')
}
.height(100)
.aspectRatio(1)
.borderRadius(10)
// 请将$r('app.media.bg')替换为实际资源文件
.backgroundImage($r('app.media.bg'))
.foregroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK, {
colorMode: ThemeColorMode.LIGHT,
adaptiveColor: AdaptiveColor.DEFAULT,
scale: 0.1
})
Text('BACKGROUND_ULTRA_THICK')
.fontSize(12)
.fontColor(Color.Black)
}
.height('100%')
.justifyContent(FlexAlign.Start)
}
.width(200)
.height(200)
}
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.width('100%')
.height('100%')
.margin({ top: 40 })
}
}

使用motionBlur为组件添加运动模糊效果
import { curves } from '@kit.ArkUI';
@Entry
@Component
struct motionBlurTest {
@State widthSize: number = 300;
@State heightSize: number = 240;
@State flag: boolean = true;
@State radius: number = 0;
@State x: number = 0.5;
@State y: number = 0.5;
build() {
Column() {
Column() {
// 请将$r('app.media.testImg')替换为实际资源文件
Image($r('app.media.testImg'))
.width(this.widthSize)
.height(this.heightSize)
.scale({ x: this.flag ? 1 : 0.8,y: this.flag ? 1 : 0.8 ,centerX: '50%', centerY: '50%' })
.onClick(() => {
this.radius = 50;
this.x = 0.5;
this.y = 0.5;
this.flag = !this.flag;
})
.animation({
duration: 2000,
iterations: 1,
playMode: PlayMode.Alternate,
onFinish: () => {
this.radius = 0;
}
})
.motionBlur({ radius: this.radius, anchor: { x: this.x, y: this.y } })
}
}.width('100%').margin({ top: 50 })
}
}
