1# 减少动画丢帧 2 3在播放动画或者生成动画时,画面产生停滞而导致帧率过低的现象,称为动画丢帧。 4 5播放动画时,系统需要在一个刷新周期内完成动画变化曲线的计算,完成组件布局绘制等操作。建议使用系统提供的动画接口,只需设置曲线类型、终点位置、时长等信息,就能够满足常用的动画功能,减少UI主线程的负载。 6 7反例:应用使用了自定义动画,动画曲线计算过程很容易引起UI线程高负载,易导致丢帧。 8 9```typescript 10@Entry 11@Component 12struct AttrAnimationExample0 { 13 @State widthSize: number = 200 14 @State heightSize: number = 100 15 @State flag: boolean = true 16 17 computeSize() { 18 let duration = 2000 19 let period = 16 20 let widthSizeEnd = 0 21 let heightSizeEnd = 0 22 if (this.flag) { 23 widthSizeEnd = 100 24 heightSizeEnd = 50 25 } else { 26 widthSizeEnd = 200 27 heightSizeEnd = 100 28 } 29 let doTimes = duration / period 30 let deltaHeight = (heightSizeEnd - this.heightSize) / doTimes 31 let deltaWeight = (widthSizeEnd - this.widthSize) / doTimes 32 for (let i = 1; i <= doTimes; i++) { 33 let t = period * (i); 34 setTimeout(() => { 35 this.heightSize = this.heightSize + deltaHeight 36 this.widthSize = this.widthSize + deltaWeight 37 }, t) 38 } 39 this.flag = !this.flag 40 } 41 42 build() { 43 Column() { 44 Button('click me') 45 .onClick(() => { 46 let delay = 500 47 setTimeout(() => { this.computeSize() }, delay) 48 }) 49 .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff) 50 }.width('100%').margin({ top: 5 }) 51 } 52} 53``` 54 55## 使用系统提供的属性动效API 56 57建议:通过系统提供的属性动效API实现上述动效功能。 58 59```typescript 60@Entry 61@Component 62struct AttrAnimationExample1 { 63 @State widthSize: number = 200 64 @State heightSize: number = 100 65 @State flag: boolean = true 66 67 build() { 68 Column() { 69 Button('click me') 70 .onClick((event?: ClickEvent | undefined) => { 71 if (this.flag) { 72 this.widthSize = 100 73 this.heightSize = 50 74 } else { 75 this.widthSize = 200 76 this.heightSize = 100 77 } 78 this.flag = !this.flag 79 }) 80 .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff) 81 .animation({ 82 duration: 2000, // 动画时长 83 curve: Curve.Linear, // 动画曲线 84 delay: 500, // 动画延迟 85 iterations: 1, // 播放次数 86 playMode: PlayMode.Normal // 动画模式 87 }) // 对Button组件的宽高属性进行动画配置 88 }.width('100%').margin({ top: 5 }) 89 } 90} 91``` 92 93更详细的API文档请参考:[属性动画](../reference/arkui-ts/ts-animatorproperty.md)。 94 95## 使用系统提供的显式动效API 96 97建议:通过系统提供的显式动效API实现上述动效功能。 98 99```typescript 100@Entry 101@Component 102struct AnimateToExample2 { 103 @State widthSize: number = 200; 104 @State heightSize: number = 100; 105 @State flag: boolean = true; 106 107 build() { 108 Column() { 109 Button('click me') 110 .onClick((event?: ClickEvent | undefined) => { 111 if (this.flag) { 112 animateTo({ 113 duration: 2000, // 动画时长 114 curve: Curve.Linear, // 动画曲线 115 delay: 500, // 动画延迟 116 iterations: 1, // 播放次数 117 playMode: PlayMode.Normal // 动画模式 118 }, () => { 119 this.widthSize = 100; 120 this.heightSize = 50; 121 }) 122 } else { 123 animateTo({ 124 duration: 2000, // 动画时长 125 curve: Curve.Linear, // 动画曲线 126 delay: 500, // 动画延迟 127 iterations: 1, // 播放次数 128 playMode: PlayMode.Normal // 动画模式 129 }, () => { 130 this.widthSize = 200; 131 this.heightSize = 100; 132 }) 133 } 134 this.flag = !this.flag; 135 }) 136 .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff) 137 }.width('100%').margin({ top: 5 }) 138 } 139} 140``` 141 142更详细的API文档请参考:[显式动画](../reference/arkui-ts/ts-explicit-animation.md)。