• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 模糊
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @CCFFWW-->
5<!--Designer: @yangfan229-->
6<!--Tester: @lxl007-->
7<!--Adviser: @HelloCrease-->
8
9动画效果可以丰富界面的细节,提升UI界面的真实感和品质感。例如,模糊和阴影效果可以让物体看起来更加立体,使得动画更加生动。ArkUI提供了丰富的效果接口,开发者可快速打造出精致、个性化的效果。本章中主要对常用的模糊、阴影和色彩效果等效果接口进行了介绍。
10
11
12模糊可以用来体现界面空间的纵深感,区分前后元素的层级关系。
13
14
15| 接口                                                         | 说明                                         |
16| ------------------------------------------------------------ | -------------------------------------------- |
17| [backdropBlur](../reference/apis-arkui/arkui-ts/ts-universal-attributes-background.md#backdropblur) | 为当前组件添加背景模糊效果,入参为模糊半径。 |
18| [blur](../reference/apis-arkui/arkui-ts/ts-universal-attributes-image-effect.md#blur) | 为当前组件添加内容模糊效果,入参为模糊半径。 |
19| [backgroundBlurStyle](../reference/apis-arkui/arkui-ts/ts-universal-attributes-background.md#backgroundblurstyle9) | 为当前组件添加背景模糊效果,入参为模糊样式。 |
20| [foregroundBlurStyle](../reference/apis-arkui/arkui-ts/ts-universal-attributes-foreground-blur-style.md#foregroundblurstyle) | 为当前组件添加内容模糊效果,入参为模糊样式。 |
21| [motionBlur](../reference/apis-arkui/arkui-ts/ts-universal-attributes-motionBlur.md#motionblur) | 为当前组件添加由缩放大小或位移变化引起的运动过程中的动态模糊效果,入参为模糊半径和锚点坐标。 |
22
23>  **说明:**
24>
25>  以上接口均为实时模糊接口,每帧执行实时渲染,性能负载较大。当模糊内容与模糊半径均无需变动时,推荐采用静态模糊接口[blur](../reference/apis-arkgraphics2d/js-apis-effectKit.md#blur)。最佳实践请参考:[图像模糊动效优化-使用场景](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-fuzzy-scene-performance-optimization#section4945532519)26
27## 使用backdropBlur为组件添加背景模糊
28
29
30```ts
31@Entry
32@Component
33struct BlurEffectsExample {
34  build() {
35    Column({ space: 10 }) {
36      Text('backdropBlur')
37        .width('90%')
38        .height('90%')
39        .fontSize(20)
40        .fontColor(Color.White)
41        .textAlign(TextAlign.Center)
42        .backdropBlur(10)// 对背景进行模糊
43        .backgroundImage($r('app.media.share'))
44        .backgroundImageSize({ width: 400, height: 300 })
45    }
46    .width('100%')
47    .height('50%')
48    .margin({ top: 20 })
49  }
50}
51```
52
53
54
55![zh-cn_image_0000001599812870](figures/zh-cn_image_0000001599812870.png)
56
57
58## 使用blur为组件添加内容模糊
59
60
61```ts
62@Entry
63@Component
64struct Index1 {
65  @State radius: number = 0;
66  @State text: string = '';
67  @State y: string = '手指不在屏幕上';
68
69  aboutToAppear() {
70    this.text = "按住屏幕上下滑动\n" + "当前手指所在y轴位置 : " + this.y +
71      "\n" + "当前图片模糊程度为 : " + this.radius;
72  }
73
74  build() {
75    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
76      Text(this.text)
77        .height(200)
78        .fontSize(20)
79        .fontWeight(FontWeight.Bold)
80        .fontFamily("cursive")
81        .fontStyle(FontStyle.Italic)
82      Image($r("app.media.wall"))
83        .blur(this.radius)// 使用blur接口为照片组件添加内容模糊效果
84        .height('100%')
85        .width("100%")
86        .objectFit(ImageFit.Cover)
87    }.height('100%')
88    .width("100%")
89    .onTouch((event?: TouchEvent) => {
90      if (event) {
91        if (event.type === TouchType.Move) {
92          this.y = Number(event.touches[0].y.toString()).toString();
93          this.radius = Number(this.y) / 10; // 根据跟手过程中的滑动距离修改模糊半径,配合模糊接口,形成跟手模糊效果
94        }
95        if (event.type === TouchType.Up) {
96          this.radius = 0;
97          this.y = '手指离开屏幕';
98        }
99      }
100      this.text = "按住屏幕上下滑动\n" + "当前手指所在y轴位置 : " + this.y +
101        "\n" + "当前图片模糊程度为 : " + this.radius;
102    })
103  }
104}
105```
106
107
108
109![zh-cn_image_0000001599813588](figures/zh-cn_image_0000001599813588.gif)
110
111
112## 使用backgroundBlurStyle为组件添加背景模糊效果
113
114
115```ts
116@Entry
117@Component
118struct BackDropBlurStyleDemo {
119  build() {
120    Grid() {
121      GridItem() {
122        Column() {
123          Column() {
124            Text('原图')
125              .fontSize(20)
126              .fontColor(Color.White)
127              .textAlign(TextAlign.Center)
128              .width('100%')
129              .height('100%')
130          }
131          .height(100)
132          .aspectRatio(1)
133          .borderRadius(10)
134          .backgroundImage($r('app.media.share'))
135
136          Text('原图')
137            .fontSize(12)
138            .fontColor(Color.Black)
139        }
140        .height('100%')
141        .justifyContent(FlexAlign.Start)
142      }
143      .width(200)
144      .height(200)
145
146      GridItem() {
147        Column() {
148          Column() {
149            Text('Thin')
150              .fontSize(20)
151              .fontColor(Color.White)
152              .textAlign(TextAlign.Center)
153              .width('100%')
154              .height('100%')
155          }
156          .height(100)
157          .aspectRatio(1)
158          .borderRadius(10)
159          .backgroundImage($r('app.media.share'))
160          // BlurStyle.Thin: 为组件添加轻薄材质模糊效果
161          // ThemeColorMode.LIGHT: 固定使用浅色模式效果
162          // AdaptiveColor.DEFAULT: 不使用取色模糊,使用默认的颜色作为蒙版颜色
163          // scale: 背景材质模糊效果程度,默认值是1
164          .backgroundBlurStyle(BlurStyle.Thin, {
165            colorMode: ThemeColorMode.LIGHT,
166            adaptiveColor: AdaptiveColor.DEFAULT,
167            scale: 0.1
168          })
169
170          Text('Thin')
171            .fontSize(12)
172            .fontColor(Color.Black)
173        }
174        .height('100%')
175        .justifyContent(FlexAlign.Start)
176      }
177      .width(200)
178      .height(200)
179
180      GridItem() {
181        Column() {
182          Column() {
183            Text('Regular')
184              .fontSize(20)
185              .fontColor(Color.White)
186              .textAlign(TextAlign.Center)
187              .width('100%')
188              .height('100%')
189          }
190          .height(100)
191          .aspectRatio(1)
192          .borderRadius(10)
193          .backgroundImage($r('app.media.share'))
194          .backgroundBlurStyle(BlurStyle.Regular, {
195            colorMode: ThemeColorMode.LIGHT,
196            adaptiveColor: AdaptiveColor.DEFAULT,
197            scale: 0.1
198          })
199
200          Text('Regular')
201            .fontSize(12)
202            .fontColor(Color.Black)
203        }
204        .height('100%')
205        .justifyContent(FlexAlign.Start)
206      }
207      .width(200)
208      .height(200)
209
210      GridItem() {
211        Column() {
212          Column() {
213            Text('Thick')
214              .fontSize(20)
215              .fontColor(Color.White)
216              .textAlign(TextAlign.Center)
217              .width('100%')
218              .height('100%')
219          }
220          .height(100)
221          .aspectRatio(1)
222          .borderRadius(10)
223          .backgroundImage($r('app.media.share'))
224          .backgroundBlurStyle(BlurStyle.Thick, {
225            colorMode: ThemeColorMode.LIGHT,
226            adaptiveColor: AdaptiveColor.DEFAULT,
227            scale: 0.1
228          })
229
230          Text('Thick')
231            .fontSize(12)
232            .fontColor(Color.Black)
233        }
234        .height('100%')
235        .justifyContent(FlexAlign.Start)
236      }
237      .width(200)
238      .height(200)
239
240      GridItem() {
241        Column() {
242          Column() {
243            Text('BACKGROUND_THIN')
244              .fontSize(12)
245              .fontColor(Color.White)
246              .textAlign(TextAlign.Center)
247              .width('100%')
248              .height('100%')
249          }
250          .height(100)
251          .aspectRatio(1)
252          .borderRadius(10)
253          .backgroundImage($r('app.media.share'))
254          .backgroundBlurStyle(BlurStyle.BACKGROUND_THIN, {
255            colorMode: ThemeColorMode.LIGHT,
256            adaptiveColor: AdaptiveColor.DEFAULT,
257            scale: 0.1
258          })
259
260          Text('BACKGROUND_THIN')
261            .fontSize(12)
262            .fontColor(Color.Black)
263        }
264        .height('100%')
265        .justifyContent(FlexAlign.Start)
266      }
267      .width(200)
268      .height(200)
269
270      GridItem() {
271        Column() {
272          Column() {
273            Text('BACKGROUND_REGULAR')
274              .fontSize(12)
275              .fontColor(Color.White)
276              .textAlign(TextAlign.Center)
277              .width('100%')
278              .height('100%')
279          }
280          .height(100)
281          .aspectRatio(1)
282          .borderRadius(10)
283          .backgroundImage($r('app.media.share'))
284          .backgroundBlurStyle(BlurStyle.BACKGROUND_REGULAR, {
285            colorMode: ThemeColorMode.LIGHT,
286            adaptiveColor: AdaptiveColor.DEFAULT,
287            scale: 0.1
288          })
289
290          Text('BACKGROUND_REGULAR')
291            .fontSize(12)
292            .fontColor(Color.Black)
293        }
294        .height('100%')
295        .justifyContent(FlexAlign.Start)
296      }
297      .width(200)
298      .height(200)
299
300      GridItem() {
301        Column() {
302          Column() {
303            Text('BACKGROUND_THICK')
304              .fontSize(12)
305              .fontColor(Color.White)
306              .textAlign(TextAlign.Center)
307              .width('100%')
308              .height('100%')
309          }
310          .height(100)
311          .aspectRatio(1)
312          .borderRadius(10)
313          .backgroundImage($r('app.media.share'))
314          .backgroundBlurStyle(BlurStyle.BACKGROUND_THICK, {
315            colorMode: ThemeColorMode.LIGHT,
316            adaptiveColor: AdaptiveColor.DEFAULT,
317            scale: 0.1
318          })
319
320          Text('BACKGROUND_THICK')
321            .fontSize(12)
322            .fontColor(Color.Black)
323        }
324        .height('100%')
325        .justifyContent(FlexAlign.Start)
326      }
327      .width(200)
328      .height(200)
329
330      GridItem() {
331        Column() {
332          Column() {
333            Text('BACKGROUND_ULTRA_THICK')
334              .fontSize(12)
335              .fontColor(Color.White)
336              .textAlign(TextAlign.Center)
337              .width('100%')
338              .height('100%')
339          }
340          .height(100)
341          .aspectRatio(1)
342          .borderRadius(10)
343          .backgroundImage($r('app.media.share'))
344          .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK, {
345            colorMode: ThemeColorMode.LIGHT,
346            adaptiveColor: AdaptiveColor.DEFAULT,
347            scale: 0.1
348          })
349
350          Text('BACKGROUND_ULTRA_THICK')
351            .fontSize(12)
352            .fontColor(Color.Black)
353        }
354        .height('100%')
355        .justifyContent(FlexAlign.Start)
356      }
357      .width(200)
358      .height(200)
359    }
360    .columnsTemplate('1fr 1fr')
361    .rowsTemplate('1fr 1fr 1fr 1fr')
362    .width('100%')
363    .height('100%')
364    .margin({ top: 40 })
365  }
366}
367```
368
369
370
371![zh-cn_image_0000001649455517](figures/zh-cn_image_0000001649455517.png)
372
373
374
375## 使用foregroundBlurStyle为组件添加内容模糊效果
376
377
378```ts
379@Entry
380@Component
381struct ForegroundBlurStyleDemo {
382  build() {
383    Grid() {
384      GridItem() {
385        Column() {
386          Column() {
387            Text('原图')
388              .fontSize(20)
389              .fontColor(Color.White)
390              .textAlign(TextAlign.Center)
391              .width('100%')
392              .height('100%')
393          }
394          .height(100)
395          .aspectRatio(1)
396          .borderRadius(10)
397          .backgroundImage($r('app.media.share'))
398
399          Text('原图')
400            .fontSize(12)
401            .fontColor(Color.Black)
402        }
403        .height('100%')
404        .justifyContent(FlexAlign.Start)
405      }
406      .width(200)
407      .height(200)
408
409      GridItem() {
410        Column() {
411          Column() {
412            Text('Thin')
413              .fontSize(20)
414              .fontColor(Color.White)
415              .textAlign(TextAlign.Center)
416              .width('100%')
417              .height('100%')
418          }
419          .height(100)
420          .aspectRatio(1)
421          .borderRadius(10)
422          .backgroundImage($r('app.media.share'))
423          // BlurStyle.Thin: 为组件添加轻薄材质模糊效果
424          // ThemeColorMode.LIGHT: 固定使用浅色模式效果
425          // AdaptiveColor.DEFAULT: 不使用取色模糊,使用默认的颜色作为蒙版颜色
426          // scale: 背景材质模糊效果程度,默认值是1
427          .foregroundBlurStyle(BlurStyle.Thin, {
428            colorMode: ThemeColorMode.LIGHT,
429            adaptiveColor: AdaptiveColor.DEFAULT,
430            scale: 0.1
431          })
432
433          Text('Thin')
434            .fontSize(12)
435            .fontColor(Color.Black)
436        }
437        .height('100%')
438        .justifyContent(FlexAlign.Start)
439      }
440      .width(200)
441      .height(200)
442
443      GridItem() {
444        Column() {
445          Column() {
446            Text('Regular')
447              .fontSize(20)
448              .fontColor(Color.White)
449              .textAlign(TextAlign.Center)
450              .width('100%')
451              .height('100%')
452          }
453          .height(100)
454          .aspectRatio(1)
455          .borderRadius(10)
456          .backgroundImage($r('app.media.share'))
457          .foregroundBlurStyle(BlurStyle.Regular, {
458            colorMode: ThemeColorMode.LIGHT,
459            adaptiveColor: AdaptiveColor.DEFAULT,
460            scale: 0.1
461          })
462
463          Text('Regular')
464            .fontSize(12)
465            .fontColor(Color.Black)
466        }
467        .height('100%')
468        .justifyContent(FlexAlign.Start)
469      }
470      .width(200)
471      .height(200)
472
473      GridItem() {
474        Column() {
475          Column() {
476            Text('Thick')
477              .fontSize(20)
478              .fontColor(Color.White)
479              .textAlign(TextAlign.Center)
480              .width('100%')
481              .height('100%')
482          }
483          .height(100)
484          .aspectRatio(1)
485          .borderRadius(10)
486          .backgroundImage($r('app.media.share'))
487          .foregroundBlurStyle(BlurStyle.Thick, {
488            colorMode: ThemeColorMode.LIGHT,
489            adaptiveColor: AdaptiveColor.DEFAULT,
490            scale: 0.1
491          })
492
493          Text('Thick')
494            .fontSize(12)
495            .fontColor(Color.Black)
496        }
497        .height('100%')
498        .justifyContent(FlexAlign.Start)
499      }
500      .width(200)
501      .height(200)
502
503      GridItem() {
504        Column() {
505          Column() {
506            Text('BACKGROUND_THIN')
507              .fontSize(12)
508              .fontColor(Color.White)
509              .textAlign(TextAlign.Center)
510              .width('100%')
511              .height('100%')
512          }
513          .height(100)
514          .aspectRatio(1)
515          .borderRadius(10)
516          .backgroundImage($r('app.media.share'))
517          .foregroundBlurStyle(BlurStyle.BACKGROUND_THIN, {
518            colorMode: ThemeColorMode.LIGHT,
519            adaptiveColor: AdaptiveColor.DEFAULT,
520            scale: 0.1
521          })
522
523          Text('BACKGROUND_THIN')
524            .fontSize(12)
525            .fontColor(Color.Black)
526        }
527        .height('100%')
528        .justifyContent(FlexAlign.Start)
529      }
530      .width(200)
531      .height(200)
532
533      GridItem() {
534        Column() {
535          Column() {
536            Text('BACKGROUND_REGULAR')
537              .fontSize(12)
538              .fontColor(Color.White)
539              .textAlign(TextAlign.Center)
540              .width('100%')
541              .height('100%')
542          }
543          .height(100)
544          .aspectRatio(1)
545          .borderRadius(10)
546          .backgroundImage($r('app.media.share'))
547          .foregroundBlurStyle(BlurStyle.BACKGROUND_REGULAR, {
548            colorMode: ThemeColorMode.LIGHT,
549            adaptiveColor: AdaptiveColor.DEFAULT,
550            scale: 0.1
551          })
552
553          Text('BACKGROUND_REGULAR')
554            .fontSize(12)
555            .fontColor(Color.Black)
556        }
557        .height('100%')
558        .justifyContent(FlexAlign.Start)
559      }
560      .width(200)
561      .height(200)
562
563      GridItem() {
564        Column() {
565          Column() {
566            Text('BACKGROUND_THICK')
567              .fontSize(12)
568              .fontColor(Color.White)
569              .textAlign(TextAlign.Center)
570              .width('100%')
571              .height('100%')
572          }
573          .height(100)
574          .aspectRatio(1)
575          .borderRadius(10)
576          .backgroundImage($r('app.media.share'))
577          .foregroundBlurStyle(BlurStyle.BACKGROUND_THICK, {
578            colorMode: ThemeColorMode.LIGHT,
579            adaptiveColor: AdaptiveColor.DEFAULT,
580            scale: 0.1
581          })
582
583          Text('BACKGROUND_THICK')
584            .fontSize(12)
585            .fontColor(Color.Black)
586        }
587        .height('100%')
588        .justifyContent(FlexAlign.Start)
589      }
590      .width(200)
591      .height(200)
592
593      GridItem() {
594        Column() {
595          Column() {
596            Text('BACKGROUND_ULTRA_THICK')
597              .fontSize(12)
598              .fontColor(Color.White)
599              .textAlign(TextAlign.Center)
600              .width('100%')
601              .height('100%')
602          }
603          .height(100)
604          .aspectRatio(1)
605          .borderRadius(10)
606          .backgroundImage($r('app.media.share'))
607          .foregroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK, {
608            colorMode: ThemeColorMode.LIGHT,
609            adaptiveColor: AdaptiveColor.DEFAULT,
610            scale: 0.1
611          })
612
613          Text('BACKGROUND_ULTRA_THICK')
614            .fontSize(12)
615            .fontColor(Color.Black)
616        }
617        .height('100%')
618        .justifyContent(FlexAlign.Start)
619      }
620      .width(200)
621      .height(200)
622    }
623    .columnsTemplate('1fr 1fr')
624    .rowsTemplate('1fr 1fr 1fr 1fr')
625    .width('100%')
626    .height('100%')
627    .margin({ top: 40 })
628  }
629}
630```
631
632
633
634![zh-cn_image_0000001599658168](figures/zh-cn_image_0000001599658168.png)
635
636
637## 使用motionBlur为组件添加运动模糊效果
638
639```ts
640import { curves } from '@kit.ArkUI';
641
642@Entry
643@Component
644struct motionBlurTest {
645  @State widthSize: number = 400;
646  @State heightSize: number = 320;
647  @State flag: boolean = true;
648  @State radius: number = 0;
649  @State x: number = 0;
650  @State y: number = 0;
651
652  build() {
653    Column() {
654      Column() {
655        Image($r('app.media.testImg'))
656          .width(this.widthSize)
657          .height(this.heightSize)
658          .onClick(() => {
659            this.radius = 5;
660            this.x = 0.5;
661            this.y = 0.5;
662            if (this.flag) {
663              this.widthSize = 100;
664              this.heightSize = 80;
665            } else {
666              this.widthSize = 400;
667              this.heightSize = 320;
668            }
669            this.flag = !this.flag;
670          })
671          .animation({
672            duration: 2000,
673            curve: curves.springCurve(10, 1, 228, 30),
674            onFinish: () => {
675              this.radius = 0;
676            }
677          })
678          .motionBlur({ radius: this.radius, anchor: { x: this.x, y: this.y } })
679      }
680    }.width('100%').margin({ top: 5 })
681  }
682}
683```
684
685![motionBlurTest](figures/motionBlur.gif)