1# 出现/消失转场 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @CCFFWW--> 5<!--Designer: @yangfan229--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9 10[transition](../reference/apis-arkui/arkui-ts/ts-transition-animation-component.md)是基础的组件转场接口,用于实现一个组件出现或者消失时的动画效果。可以通过[TransitionEffect对象](../reference/apis-arkui/arkui-ts/ts-transition-animation-component.md#transitioneffect10对象说明)的组合使用,定义出各式效果。 11 12 13 **表1** 转场效果接口 14 15| 转场效果 | 说明 | 动画 | 16| -------- | -------- | -------- | 17| IDENTITY | 禁用转场效果。 | 无。 | 18| OPACITY | 默认的转场效果,透明度转场。 | 出现时透明度从0到1,消失时透明度从1到0。 | 19| SLIDE | 滑动转场效果。 | 出现时从窗口左侧滑入,消失时从窗口右侧滑出。 | 20| translate | 通过设置组件平移创建转场效果。 | 出现时为translate接口设置的值到默认值0,消失时为默认值0到translate接口设置的值。 | 21| rotate | 通过设置组件旋转创建转场效果。 | 出现时为rotate接口设置的值到默认值0,消失时为默认值0到rotate接口设置的值。 | 22| opacity | 通过设置透明度参数创建转场效果。 | 出现时为opacity设置的值到默认透明度1,消失时为默认透明度1到opacity设置的值。 | 23| move | 通过[TransitionEdge](../reference/apis-arkui/arkui-ts/ts-transition-animation-component.md#transitionedge10)创建从窗口哪条边缘出来的效果。 | 出现时从TransitionEdge方向滑入,消失时滑出到TransitionEdge方向。 | 24| asymmetric | 通过此方法组合非对称的出现消失转场效果。<br/>- appear:出现转场的效果。<br/>- disappear:消失转场的效果。 | 出现时采用appear设置的TransitionEffect出现效果,消失时采用disappear设置的TransitionEffect消失效果。 | 25| combine | 组合其他TransitionEffect。 | 组合其他TransitionEffect,一起生效。 | 26| animation | 定义转场效果的动画参数:<br/>- 如果不定义会跟随animateTo的动画参数。<br/>- 不支持通过控件的animation接口配置动画参数。<br/>- TransitionEffect中animation的onFinish不生效。 | 调用顺序时从上往下,上面TransitionEffect的animation也会作用到下面TransitionEffect。 | 27 28 291. 创建TransitionEffect。 30 31 ```ts 32 // 出现时会是所有转场效果的出现效果叠加,消失时会是所有消失转场效果的叠加 33 // 说明各个effect跟随的动画参数 34 private effect: object = 35 TransitionEffect.OPACITY // 创建了透明度转场效果,这里没有调用animation接口,会跟随animateTo的动画参数 36 // 通过combine方法,添加缩放转场效果,并指定了springMotion(0.6, 1.2)曲线 37 .combine(TransitionEffect.scale({ x: 0, y: 0 }).animation({ curve: curves.springMotion(0.6, 1.2) })) 38 // 添加旋转转场效果,这里的动画参数会跟随上面的TransitionEffect,也就是springMotion(0.6, 1.2) 39 .combine(TransitionEffect.rotate({ angle: 90 })) 40 // 添加平移转场效果,动画参数会跟随其之上带animation的TransitionEffect,也就是springMotion(0.6, 1.2) 41 .combine(TransitionEffect.translate({ x: 150, y: 150 })) 42 // 添加move转场效果,并指定了springMotion曲线 43 .combine(TransitionEffect.move(TransitionEdge.END)).animation({curve: curves.springMotion()}) 44 // 添加非对称的转场效果,由于这里没有设置animation,会跟随上面的TransitionEffect的animation效果,也就是springMotion 45 .combine(TransitionEffect.asymmetric(TransitionEffect.scale({ x: 0, y: 0 }), TransitionEffect.rotate({ angle: 90 }))); 46 ``` 47 482. 将转场效果通过[transition](../reference/apis-arkui/arkui-ts/ts-transition-animation-component.md)接口设置到组件。 49 50 ```ts 51 Text('test') 52 .transition(this.effect) 53 ``` 54 553. 新增或者删除组件触发转场。 56 57 ```ts 58 @State isPresent: boolean = true; 59 // ... 60 if (this.isPresent) { 61 Text('test') 62 .transition(this.effect) 63 } 64 // ... 65 // 控制新增或者删除组件 66 // 方式一:将控制变量放到animateTo闭包内,未通过animation接口定义动画参数的TransitionEffect将跟随animateTo的动画参数 67 this.getUIContext()?.animateTo({ curve: curves.springMotion() }, () => { 68 this.isPresent = false; 69 }) 70 71 // 方式二:直接控制删除或者新增组件,动画参数由TransitionEffect的animation接口配置 72 this.isPresent = false; 73 ``` 74 75 76 完整的示例代码和效果如下,示例中采用直接删除或新增组件的方式触发转场,也可以替换为在animateTo闭包内改变控制变量触发转场。 77 78```ts 79import { curves } from '@kit.ArkUI'; 80 81@Entry 82@Component 83struct TransitionEffectDemo { 84 @State isPresent: boolean = false; 85 // 第一步,创建TransitionEffect 86 private effect: TransitionEffect = 87 // 创建默认透明度转场效果,并指定了springMotion(0.6, 0.8)曲线 88 TransitionEffect.OPACITY.animation({ 89 curve: curves.springMotion(0.6, 0.8) 90 })// 通过combine方法,这里的动画参数会跟随上面的TransitionEffect,也就是springMotion(0.6, 0.8) 91 .combine(TransitionEffect.scale({ 92 x: 0, 93 y: 0 94 }))// 添加旋转转场效果,这里的动画参数会跟随上面带animation的TransitionEffect,也就是springMotion(0.6, 0.8) 95 .combine(TransitionEffect.rotate({ angle: 90 }))// 添加平移转场效果,这里的动画参数使用指定的springMotion() 96 .combine(TransitionEffect.translate({ y: 150 }) 97 .animation({ curve: curves.springMotion() }))// 添加move转场效果,这里的动画参数会跟随上面的TransitionEffect,也就是springMotion() 98 .combine(TransitionEffect.move(TransitionEdge.END)); 99 100 build() { 101 Stack() { 102 if (this.isPresent) { 103 Column() { 104 Text('ArkUI') 105 .fontWeight(FontWeight.Bold) 106 .fontSize(20) 107 .fontColor(Color.White) 108 } 109 .justifyContent(FlexAlign.Center) 110 .width(150) 111 .height(150) 112 .borderRadius(10) 113 .backgroundColor(0xf56c6c) 114 // 第二步:将转场效果通过transition接口设置到组件 115 .transition(this.effect) 116 } 117 118 // 边框 119 Column() 120 .width(155) 121 .height(155) 122 .border({ 123 width: 5, 124 radius: 10, 125 color: Color.Black 126 }) 127 128 // 第三步:新增或者删除组件触发转场,控制新增或者删除组件 129 Button('Click') 130 .margin({ top: 320 }) 131 .onClick(() => { 132 this.isPresent = !this.isPresent; 133 }) 134 } 135 .width('100%') 136 .height('60%') 137 } 138} 139``` 140 141 142 143 144 145 146对多个组件添加转场效果时,可以在animation动画参数中配置不同的delay值,实现组件渐次出现消失的效果: 147 148```ts 149const ITEM_COUNTS = 9; 150const ITEM_COLOR = '#ED6F21'; 151const INTERVAL = 30; 152const DURATION = 300; 153 154@Entry 155@Component 156struct Index1 { 157 @State isGridShow: boolean = false; 158 private dataArray: number[] = new Array(ITEM_COUNTS); 159 160 aboutToAppear(): void { 161 for (let i = 0; i < ITEM_COUNTS; i++) { 162 this.dataArray[i] = i; 163 } 164 } 165 166 build() { 167 Stack() { 168 if (this.isGridShow) { 169 Grid() { 170 ForEach(this.dataArray, (item: number, index: number) => { 171 GridItem() { 172 Stack() { 173 Text((item + 1).toString()) 174 } 175 .size({ width: 50, height: 50 }) 176 .backgroundColor(ITEM_COLOR) 177 .transition(TransitionEffect.OPACITY 178 .combine(TransitionEffect.scale({ x: 0.5, y: 0.5 }))// 对每个方格的转场添加delay,实现组件的渐次出现消失效果 179 .animation({ duration: DURATION, curve: Curve.Friction, delay: INTERVAL * index })) 180 .borderRadius(10) 181 } 182 // 消失时,如果不对方格的所有父控件添加转场效果,则方格的消失转场不会生效 183 // 此处让方格的父控件在出现消失转场时一直以0.99的透明度显示,使得方格的转场效果不受影响 184 .transition(TransitionEffect.opacity(0.99)) 185 }, (item: number) => item.toString()) 186 } 187 .columnsTemplate('1fr 1fr 1fr') 188 .rowsGap(15) 189 .columnsGap(15) 190 .size({ width: 180, height: 180 }) 191 // 消失时,如果不对方格的所有父控件添加转场效果,则方格的消失转场不会生效 192 // 此处让父控件在出现消失转场时一直以0.99的透明度显示,使得方格的转场效果不受影响 193 .transition(TransitionEffect.opacity(0.99)) 194 } 195 } 196 .size({ width: '100%', height: '100%' }) 197 .onClick(() => { 198 this.getUIContext()?.animateTo({ 199 duration: DURATION + INTERVAL * (ITEM_COUNTS - 1), 200 curve: Curve.Friction 201 }, () => { 202 this.isGridShow = !this.isGridShow; 203 }) 204 }) 205 } 206} 207``` 208 209