1# 转场动画的使用(ArkTs)
2
3## 场景介绍
4日常在应用时,经常需要衔接两个场景,或者两个镜头画面之间进行切换,切换时需要呈现一种平滑过渡效果。
5
6本例将为大家介绍下如何通过转场动画实现上述过渡效果。
7
8## 效果呈现
9本例最终效果如下:
10
11| 场景                               | 效果图                                                |
12| ---------------------------------- | ----------------------------------------------------- |
13| 页面间转场--底部滑入转场           | ![BottomTransition.gif](figures/BottomTransition.gif) |
14| 页面间转场--自定义1:缩放动画转场  | ![](figures/CustomTransition.gif)                     |
15| 页面间转场---自定义2:旋转动画转场 | ![](figures/FullCustomTransition.gif)                 |
16| 组件内转场                         | ![](figures/ComponentTransition.gif)                  |
17| 共享元素转场                       | ![](figures/SharePage.gif)                            |
18
19
20
21## 运行环境
22本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
23- IDE: DevEco Studio 4.0 Beta1
24- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
25## 实现思路
26* 构建应用首页,主要由5个相同样式的功能菜单组成,通过添加路由实现主页面与对应功能页面的链接跳转。
27
28* 功能页面的实现
29
30  * 页面间转场
31
32    * 底部滑入转场
33
34      通过给pageTransition()方法定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
35
36    * 缩放动画转场
37
38      通过设置pageTransition方法,配置进行配置转场参数。
39
40    * 旋转动画转场
41
42FullCustomTransition.ets的Column组件中添加TransitionElement组件,并且定义pageTransition方法。给Clomn组件添加opacity、scale、rotate属性,定义变量animValue用来控制Clomn组件的动效,在PageTransitionEnter和PageTransitionExit组件中动态改变myProgress的值,从而控制动画效果。
43
44  * 组件间转场
45
46    * 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
47
48    * 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,从而实现组件间的转场。
49
50    * 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
51      * isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
52
53      * 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
54
55  * 共享转场
56
57      通过给两个页面“SharedItem”和“SharePage” 的Image组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
58
59## 开发步骤
601. 创建主界面。
61
62    添加媒体资源至resources > base > media目录下。
63
64    ![Transition-animation-tree.png](figures/Transition-animation-tree.png)
65
66    首页Index.ets引入首页列表常量数据:INDEX_ANIMATION_MODE(imgRes:设置按钮的背景图片,url:设置页面路由的地址),通过ForEach方法循环渲染列表常量数据。
67    具体代码如下:
68
69    ```ts
70    // entry/src/main/ets/pages/Index.ets
71
72    // 引入列表常量数据INDEX_ANIMATION_MODE
73    export const INDEX_ANIMATION_MODE = [
74      { imgRes: $r('app.media.bg_bottom_anim_transition'), url: 'pages/BottomTransition' },
75      { imgRes: $r('app.media.bg_custom1_anim_transition'), url: 'pages/CustomTransition' },
76      { imgRes: $r('app.media.bg_custom2_anim_transition'), url: 'pages/FullCustomTransition' },
77      { imgRes: $r('app.media.bg_element_anim_transition'), url: 'pages/ComponentTransition' },
78      { imgRes: $r('app.media.bg_share_anim_transition'), url: 'pages/ShareItem' }
79    ];
80
81    ...
82    Column() {
83      // ForEach循环渲染
84      ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
85        Row()
86          .backgroundImage(imgRes)
87          .backgroundImageSize(ImageSize.Cover)
88          .backgroundColor('#00000000')
89          .height(130)
90          .margin({ bottom: 30 })
91          .width('100%')
92          .borderRadius(32)
93          .onClick(() => {
94            router.pushUrl({ url: url })
95          })
96      }, item => JSON.stringify(item))
97    }
98    ```
99
100    添加其它组件,以及样式,完成UI构建。
101
102    具体代码如下:
103    ```ts
104    // entry/src/main/ets/pages/Index.ets
105    import router from '@ohos.router';
106    import hilog from '@ohos.hilog';
107    @Entry
108    @Component
109    struct Index {
110      build() {
111        Column() {
112          Text($r('app.string.main_page_title'))
113            .fontSize(30)
114            .fontWeight(FontWeight.Regular)
115            .width('100%')
116            .margin({ top: 13, bottom: 27,left: 24})
117
118          Scroll() {
119            Column() {
120              ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
121                Row()
122                  .backgroundImage(imgRes)
123                  .backgroundImageSize(ImageSize.Cover)
124                  .backgroundColor('#00000000')
125                  .height(130)
126                  .margin({ bottom: 30 })
127                  .width('100%')
128                  .borderRadius(32)
129                  .onClick(() => {
130                    router.pushUrl({ url: url })
131                      .catch(err => {
132                        hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
133                      });
134                  })
135              }, item => JSON.stringify(item))
136            }
137          }
138          .align(Alignment.Top)
139          .layoutWeight(1)
140          .scrollBar(BarState.Off)
141        }
142        .height('100%')
143        .backgroundColor('#F1F3F5')
144        .padding({left:12 , right:12})
145      }
146    }
147    ```
148
1492. 实现页面间转场。
150  * 效果1:底部滑入。
151
152    该效果的实现,主要是通过在BottomTransition.ets中设置全局pageTransition()方法,该方法中自定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
153
154    具体代码如下:
155
156    ```ts
157    // entry/src/main/ets/pages/BottomTransition.ets
158
159    @Entry
160    @Component
161    struct BottomTransition {
162      private imgRes: string | Resource = $r('app.media.bg_transition');
163      private imgFit: ImageFit = ImageFit.Fill;
164
165      build() {
166        Column() {
167          Image(this.imgRes)
168            .objectFit(this.imgFit)
169            .width('100%')
170            .height('100%')
171        }
172
173      }
174
175      // 页面转场通过全局pageTransition方法进行配置转场参数
176      pageTransition() {
177        // PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
178        PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
179        // PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
180        PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
181      }
182    }
183
184    ```
185
186  * 效果2:页面入场时淡入和放大,退场时从右下角滑出。
187
188    *  在CustomTransition.ets中设置全局pageTransition()方法。
189    *  pageTransition方法中自定义入场效果PageTransitionEnter:透明度设置从0.2到1;x、y轴缩放从0变化到1。
190    *  pageTransition方法中自定义出场效果PageTransitionExit: x、y轴的偏移量为500。
191
192    具体代码如下:
193
194    ```ts
195    // entry/src/main/ets/pages/CustomTransition.ets
196
197    @Entry
198    @Component
199    struct CustomTransition {
200      private imgRes: string | Resource = $r('app.media.bg_transition');
201      private imgFit: ImageFit = ImageFit.Fill;
202
203      build() {
204        Column() {
205          Image(this.imgRes)
206            .objectFit(this.imgFit)
207            .width('100%')
208            .height('100%')
209        }
210      }
211
212      // 页面转场通过全局pageTransition方法进行配置转场参数
213      pageTransition() {
214        // 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
215        PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
216        // 退场时x、y轴的偏移量为500
217        PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
218      }
219    }
220    ```
221
222  * 效果3:页面入场时淡入和放大,同时顺时针旋转;退场时淡出和缩小,同时逆时针旋转。
223
224    * 在FullCustomTransition.ets中添加Column组件。
225
226      * 向Column组件添加属性:opacity、scale、rotate,来控制动效的淡入淡出、缩放以及旋转效果。
227
228      * 定义变量animValue用来,通过animValue值得变化来控制Column组件的动效。
229    * 在FullCustomTransition.ets中定义全局pageTransition()方法。
230    * pageTransition方法中自定义入场效果PageTransitionEnter。
231
232      ​	animValue值实时变化,0 --> 1,从而渲染 入场时淡入、放大以及顺时针旋转效果。
233    * pageTransition方法中自定义出场效果PageTransitionExit。
234
235      ​	animValue值实时变化,1 --> 0,从而渲染 出场时淡出、缩小以及逆时针旋转效果。
236
237    具体代码如下:
238
239    ```ts
240    // entry/src/main/ets/pages/FullCustomTransition.ets
241
242    @Entry
243    @Component
244    struct FullCustomTransition {
245        @State animValue: number = 1;
246        private imgRes: string | Resource = $r('app.media.bg_transition');
247        private imgFit: ImageFit = ImageFit.Fill;
248
249        build() {
250        Column() {
251            Image(this.imgRes)
252            .objectFit(this.imgFit)
253            .width('100%')
254            .height('100%')
255        }
256        // 设置淡入、淡出效果
257        .opacity(this.animValue)
258        // 设置缩放
259        .scale({ x: this.animValue, y: this.animValue })
260        // 设置旋转角度
261        .rotate({
262            z: 1,
263            angle: 360 * this.animValue
264        })
265        }
266
267        // 页面转场通过全局pageTransition方法进行配置转场参数
268        pageTransition() {
269        PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
270            // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
271            .onEnter((type: RouteType, progress: number) => {
272            // 入场动效过程中,实时更新this.animValue的值
273            this.animValue = progress
274            });
275        PageTransitionExit({ duration: 600, curve: Curve.Smooth })
276            // 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
277            .onExit((type: RouteType, progress: number) => {
278            // 入场动效过程中,实时更新this.animValue的值
279            this.animValue = 1 - progress
280            });
281        }
282    }
283    ```
284
285
2863. 实现组件内转场。
287
288   * 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
289
290     具体代码如下:
291
292     ```ts
293     // entry/src/main/ets/pages/ComponentTransition.ets
294
295     @Entry
296     @Component
297     struct ComponentTransition {
298
299       build() {
300         Column() {
301           Row() {
302             Image($r('app.media.ic_public_back'))
303               .width(20)
304               .height(20)
305               .responseRegion({width:'100%',height: '100%'})
306               .onClick(() => {
307                 router.back();
308               })
309
310             Text($r('app.string.Component_transition_header'))
311               .fontColor(Color.Black)
312               .fontWeight(FontWeight.Regular)
313               .fontSize(25)
314               .margin({left:18,right:18})
315           }
316           .height(30)
317           .width('100%')
318           .margin({ top: 20, bottom: 27,left: 24})
319
320
321           Image($r('app.media.bg_element'))
322             .objectFit(ImageFit.Fill)
323             .borderRadius(20)
324             .margin({ bottom: 20 })
325             .width('100%')
326             .height(300)
327
328           Button($r('app.string.Component_transition_toggle'))
329             .height(40)
330             .width(120)
331             .fontColor(Color.White)
332             .backgroundColor($r('app.color.light_blue'))
333         }
334         .padding({left:20,right:20})
335         .height('100%')
336         .width('100%')
337       }
338     }
339
340     ```
341
342   * 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,来实现组件转场间。
343
344     具体代码如下:
345
346     ```ts
347     //  entry/src/main/ets/pages/ComponentTransition.ets
348     ...
349     Image($r('app.media.bg_share'))
350               .objectFit(ImageFit.Fill)
351               .borderRadius(20)
352               .margin({ bottom: 20 })
353               .height(300)
354               .width('100%')
355                // 插入动效
356               .transition({
357                 type: TransitionType.Insert,
358                 scale: { x: 0.5, y: 0.5 },
359                 opacity: 0
360               })
361                // 删除隐藏动效
362               .transition({
363                 type: TransitionType.Delete,
364                 rotate: { x: 0, y: 1, z: 0, angle: 360 },
365                 opacity: 0
366               })
367     ```
368
369
370   - 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
371
372        * isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
373
374        * 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
375
376          具体代码如下:
377
378          ```ts
379          //  entry/src/main/ets/pages/ComponentTransition.ets
380
381          ...
382          @State isShow: boolean = false;
383              ...
384              // isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
385              if (this.isShow) {
386                  Image($r('app.media.bg_share'))
387                  .objectFit(ImageFit.Fill)
388                  .borderRadius(20)
389                  .margin({ bottom: 20 })
390                  .height(300)
391                  .width('100%')
392                      // 插入动效
393                  .transition({
394                      type: TransitionType.Insert,
395                      scale: { x: 0.5, y: 0.5 },
396                      opacity: 0
397                  })
398                      // 删除隐藏动效
399                  .transition({
400                      type: TransitionType.Delete,
401                      rotate: { x: 0, y: 1, z: 0, angle: 360 },
402                      opacity: 0
403                  })
404              }
405          	...
406          		Button($r('app.string.Component_transition_toggle'))
407              	...
408                  .onClick(() => {
409                  	animateTo({ duration: 600 }, () => {
410                      this.isShow = !this.isShow;
411                  	})
412                  })
413          ```
414
415        ComponentTransition.ets的完整代码如下:
416
417        ```ts
418        //  entry/src/main/ets/pages/ComponentTransition.ets
419        import router from '@ohos.router';
420
421        @Entry
422        @Component
423        struct ComponentTransition {
424          @State isShow: boolean = false;
425
426          build() {
427            Column() {
428              // 页面title区域,含返回功能以及title显示
429              Row() {
430                Image($r('app.media.ic_public_back'))
431                  .width(20)
432                  .height(20)
433                  .responseRegion({
434                    width:'100%',
435                    height: '100%'
436                  })
437                  .onClick(() => {
438                    router.back();
439                  })
440
441                Text($r('app.string.Component_transition_header'))
442                  .fontColor(Color.Black)
443                  .fontWeight(FontWeight.Regular)
444                  .fontSize(25)
445                  .height(300)
446                  .margin({ left:18, right:18 })
447              }
448              .height(30)
449              .width('100%')
450              .margin({ top: 20, bottom: 27,left: 24})
451
452              // 页面内容区域
453              // isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
454              if (this.isShow) {
455                Image($r('app.media.bg_share'))
456                  .objectFit(ImageFit.Fill)
457                  .borderRadius(20)
458                  .margin({ bottom: 20 })
459                  .height(300)
460                  .width('100%')
461                    // 插入动效
462                  .transition({
463                    type: TransitionType.Insert,
464                    scale: { x: 0.5, y: 0.5 },
465                    opacity: 0
466                  })
467                    // 删除隐藏动效
468                  .transition({
469                    type: TransitionType.Delete,
470                    rotate: { x: 0, y: 1, z: 0, angle: 360 },
471                    opacity: 0
472                  })
473              }
474
475              Image($r('app.media.bg_element'))
476                .objectFit(ImageFit.Fill)
477                .borderRadius(20)
478                .margin({ bottom: 20 })
479                .width('100%')
480                .height(300)
481              Button($r('app.string.Component_transition_toggle'))
482                .height(40)
483                .width(120)
484                .fontColor(Color.White)
485                .backgroundColor($r('app.color.light_blue'))
486                .onClick(() => {
487                  animateTo({ duration: 600 }, () => {
488                    console.log('console-- ' +this.isShow)
489                    this.isShow = !this.isShow;
490                  })
491                })
492            }
493            .padding({
494              left:(20),
495              right:(20)
496            })
497            .height('100%')
498            .width('100%')
499          }
500        }
501        ```
502
503
5044. 实现元素共享转场。
505
506   共享元素转场通过给组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
507
508   * 通过Image、Column、Text等组件构建ShareItem.ets页面,给内容区域的Image组件设置sharedTransition属性标记该元素为共享元素,组件转场id设置为“shareID”, 同时设置共享元素转场效果。
509
510     具体代码如下:
511
512     ```ts
513     // entry/src/main/ets/pages/ShareItem.ets
514
515     import hilog from '@ohos.hilog';
516
517     @Entry
518     @Component
519     struct ShareItem {
520       // 自定义页面内容区域
521       @Builder PreviewArea() {
522         Column() {
523           Image($r('app.media.bg_transition'))
524             .width('100%')
525             .height(300)
526             .borderRadius(24)
527             .margin({ bottom: 12 })
528             // 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
529             .sharedTransition('shareId', {
530               duration: 600,
531               curve: Curve.Smooth,
532               delay: 100
533             })
534
535             .onClick(() => {
536               // 路由切换
537               router.pushUrl({ url: 'pages/SharePage' })
538                 .catch(err => {
539                   hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
540                 });
541             })
542           Text($r('app.string.Share_Item_hint'))
543             .width('100%')
544             .textAlign(TextAlign.Center)
545             .fontSize(20)
546             .fontWeight(FontWeight.Regular)
547             .fontColor($r('app.color.share_item_content_font'))
548         }
549         .borderRadius(24)
550         .backgroundColor(Color.White)
551         .width('100%')
552         .padding({ top: 13, left: 12, right: 12,bottom:12})
553       }
554
555       build() {
556         Column() {
557           // 页面title区域,含返回功能以及title显示
558           Row() {
559             Image($r('app.media.ic_public_back'))
560               .width(20)
561               .height(20)
562               .responseRegion({
563                 width:'100%',
564                 height: '100%'
565               })
566               .onClick(() => {
567                 router.back();
568               })
569
570             Text($r('app.string.Share_Item_header'))
571               .fontColor(Color.Black)
572               .fontWeight(FontWeight.Regular)
573               .fontSize(25)
574               .margin({ left:18, right:18 })
575           }
576           .height(30)
577           .width('100%')
578           .margin({ top: 20, bottom: 27,left: 24})
579           this.PreviewArea()
580         }
581         .width('100%')
582         .height('100%')
583         .backgroundColor($r('app.color.grey_light'))
584         .padding({left:12,right:12})
585       }
586     }
587     ```
588
589   * pages/SharePage.ets页面中,给Image组件设置sharedTransition属性,同时组件转场id设置为“shareID”,从而可以共享上述步骤的转场动效。
590
591        具体代码如下:
592        ```ts
593        // entry/src/main/ets/pages/SharePage.ets
594        @Entry
595        @Component
596        struct SharePage {
597            build() {
598                Column() {
599                    Image($r('app.media.bg_transition'))
600                        .objectFit(ImageFit.Fill)
601                        .width('100%')
602                        .height('100%')
603                        .sharedTransition('shareId', {
604                            duration: 600,
605                            curve: Curve.Smooth,
606                            delay: 100
607                        })
608                }
609            }
610        }
611        ```
612
613
614## 完整代码
615本例完整代码如下:
616
617应用首页: /entry/src/main/ets/pages/Index.ets618
619```ts
620// entry/src/main/ets/pages/Index.ets
621import router from '@ohos.router';
622import hilog from '@ohos.hilog';
623
624@Entry
625@Component
626struct Index {
627  build() {
628    Column() {
629      Text($r('app.string.main_page_title'))
630      .fontSize(30)
631        .fontWeight(FontWeight.Regular)
632        .width('100%')
633        .margin({ top: 13, bottom: 27,left: 24})
634
635      Scroll() {
636      	Column() {
637          ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
638            Row()
639              .backgroundImage(imgRes)
640              .backgroundImageSize(ImageSize.Cover)
641              .backgroundColor('#00000000')
642              .height(130)
643              .margin({ bottom: 30 })
644              .width('100%')
645              .borderRadius(32)
646              .onClick(() => {
647                router.pushUrl({ url: url })
648                  .catch(err => {
649                    hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
650                  });
651              })
652          }, item => JSON.stringify(item))
653        }
654      }
655      .align(Alignment.Top)
656      .layoutWeight(1)
657      .scrollBar(BarState.Off)
658    }
659    .height('100%')
660    .backgroundColor('#F1F3F5')
661    .padding({left:12 , right:12})
662  }
663}
664```
665
666底部滑出页面:/entry/src/main/ets/pages/BottomTransition.ets667
668```ts
669// entry/src/main/ets/pages/BottomTransition.ets
670
671@Entry
672@Component
673struct BottomTransition {
674  private imgRes: string | Resource = $r('app.media.bg_transition');
675  private imgFit: ImageFit = ImageFit.Fill;
676
677  build() {
678    Column() {
679      Image(this.imgRes)
680        .objectFit(this.imgFit)
681        .width('100%')
682        .height('100%')
683    }
684
685  }
686
687  // 页面转场通过全局pageTransition方法进行配置转场参数
688  pageTransition() {
689    // PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
690    PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
691    // PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
692    PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
693  }
694}
695```
696
697自定义1 缩放动画转场页面:/entry/src/main/ets/pages/CustomTransition.ets698
699```ts
700// entry/src/main/ets/pages/CustomTransition.ets
701@Entry
702@Component
703struct CustomTransition {
704  private imgRes: string | Resource = $r('app.media.bg_transition');
705  private imgFit: ImageFit = ImageFit.Fill;
706  build() {
707    Column() {
708      Image(this.imgRes)
709        .objectFit(this.imgFit)
710        .width('100%')
711        .height('100%')
712    }
713  }
714  // 页面转场通过全局pageTransition方法进行配置转场参数
715  pageTransition() {
716    // 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
717    PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
718    // 退场时x、y轴的偏移量为500
719    PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
720  }
721}
722```
723
724自定义2 旋转动画转场: /entry/src/main/ets/pages/FullCustomTransition.ets725
726```ts
727@Entry
728@Component
729struct FullCustomTransition {
730  @State animValue: number = 1;
731  private imgRes: string | Resource = $r('app.media.bg_transition');
732  private imgFit: ImageFit = ImageFit.Fill;
733  build() {
734    Column() {
735      Image(this.imgRes)
736        .objectFit(this.imgFit)
737        .width('100%')
738        .height('100%')
739    }
740    // 设置淡入、淡出效果
741    .opacity(this.animValue)
742    // 设置缩放
743    .scale({ x: this.animValue, y: this.animValue })
744    // 设置旋转角度
745    .rotate({
746      z: 1,
747      angle: 360 * this.animValue
748    	})
749   }
750  // 页面转场通过全局pageTransition方法进行配置转场参数
751  pageTransition() {
752    PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
753      // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
754      .onEnter((type: RouteType, progress: number) => {
755        // 入场动效过程中,实时更新this.animValue的值
756        this.animValue = progress
757      });
758    PageTransitionExit({ duration: 600, curve: Curve.Smooth })
759      // 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
760      .onExit((type: RouteType, progress: number) => {
761        // 入场动效过程中,实时更新this.animValue的值
762         this.animValue = 1 - progress
763      });
764   }
765}
766```
767
768组件内转场页面: /entry/src/main/ets/pages/ComponentTransition.ets769
770```ts
771 import router from '@ohos.router';
772 @Entry
773 @Component
774 struct ComponentTransition {
775      @State isShow: boolean = false;
776      build() {
777        Column() {
778          // 页面title区域,含返回功能以及title显示
779          Row() {
780            Image($r('app.media.ic_public_back'))
781              .width(20)
782              .height(20)
783              .responseRegion({
784                width:'100%',
785                height: '100%'
786              })
787              .onClick(() => {
788                router.back();
789           })
790            Text($r('app.string.Component_transition_header'))
791              .fontColor(Color.Black)
792              .fontWeight(FontWeight.Regular)
793              .fontSize(25)
794              .margin({left:18, right:18})
795          }
796          .height(30)
797          .width('100%')
798          .margin({ top: 20, bottom: 27,left: 24})
799
800          // 页面内容区域
801          // isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
802          if (this.isShow) {
803            Image($r('app.media.bg_share'))
804              .objectFit(ImageFit.Fill)
805              .borderRadius(20)
806           	  .margin({ bottom: 20 })
807              .height(300)
808              .width('100%')
809                // 插入动效
810              .transition({
811                type: TransitionType.Insert,
812                scale: { x: 0.5, y: 0.5 },
813                opacity: 0
814              })
815                // 删除隐藏动效
816              .transition({
817                type: TransitionType.Delete,
818                rotate: { x: 0, y: 1, z: 0, angle: 360 },
819                opacity: 0
820              })
821          }
822
823
824            Image($r('app.media.bg_element'))
825              .objectFit(ImageFit.Fill)
826              .borderRadius(20)
827              .margin({ bottom: 20 })
828              .width('100%')
829              .height(300)
830
831             Button($r('app.string.Component_transition_toggle'))
832               .height(40)
833               .width(120)
834               .fontColor(Color.White)
835               .backgroundColor($r('app.color.light_blue'))
836               .onClick(() => {
837                 animateTo({ duration: 600 }, () => {
838                   this.isShow = !this.isShow;
839                 })
840               })
841           }
842           .padding({left:20,right:20})
843           .height('100%')
844           .width('100%')
845         }
846  }
847```
848
849
850共享元素转场部件:/entry/src/main/ets/pages/ShareItem.ets851
852```ts
853import hilog from '@ohos.hilog';
854
855@Entry
856@Component
857struct ShareItem {
858  // 自定义页面内容区域
859  @Builder PreviewArea() {
860    Column() {
861      Image($r('app.media.bg_transition'))
862        .width('100%')
863        .height(300)
864        .borderRadius(24)
865        .margin({ bottom: 12 })
866        // 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
867        .sharedTransition('shareId', {
868          duration: 600,
869          curve: Curve.Smooth,
870          delay: 100
871        })
872
873        .onClick(() => {
874          // 路由切换
875          router.pushUrl({ url: 'pages/SharePage' })
876            .catch(err => {
877              hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
878            });
879        })
880      Text($r('app.string.Share_Item_hint'))
881        .width('100%')
882        .textAlign(TextAlign.Center)
883        .fontSize(20)
884        .fontWeight(FontWeight.Regular)
885        .fontColor($r('app.color.share_item_content_font'))
886    }
887    .borderRadius(24)
888    .backgroundColor(Color.White)
889    .width('100%')
890    .padding({ top: 13, left: 12, right: 12,bottom:12})
891  }
892
893  build() {
894    Column() {
895      // 页面title区域,含返回功能以及title显示
896      Row() {
897        Image($r('app.media.ic_public_back'))
898          .width(20)
899          .height(20)
900          .responseRegion({
901            width:'100%',
902            height: '100%'
903          })
904          .onClick(() => {
905            router.back();
906          })
907
908        Text($r('app.string.Share_Item_header'))
909          .fontColor(Color.Black)
910          .fontWeight(FontWeight.Regular)
911          .fontSize(25)
912          .margin({ left:18, right:18 })
913      }
914      .height(30)
915      .width('100%')
916      .margin({ top: 20, bottom: 27,left: 24})
917      this.PreviewArea()
918    }
919    .width('100%')
920    .height('100%')
921    .backgroundColor($r('app.color.grey_light'))
922    .padding({left:12,right:12})
923  }
924}
925```
926
927共享元素转场页面:/entry/src/main/ets/pages/SharePage.ets928
929```ts
930@Entry
931@Component
932struct SharePage {
933  build() {
934    Column() {
935      Image($r('app.media.bg_transition'))
936        .objectFit(ImageFit.Fill)
937        .width('100%')
938        .height('100%')
939        .sharedTransition('shareId', {
940          duration: 600,
941          curve: Curve.Smooth,
942          delay: 100
943        })
944    }
945  }
946}
947```
948
949 ##  参考
950
951- [图形变换](../application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-transformation.md)
952
953- [页面间转场](../application-dev/reference/apis-arkui/arkui-ts/ts-page-transition-animation.md)
954
955- [组件内转场](../application-dev/ui/arkts-shared-element-transition.md)
956
957- [共享元素转场](../application-dev/reference/apis-arkui/arkui-ts/ts-transition-animation-shared-elements.md)
958
959
960