ArkUI-动画衔接
舟率率 12/6/2023 ArkUI
# arkts-animation-smoothing.md
除了运行动画之外,还承载着与用户进行实时交互的功能。当用户行为根据意图变化发生改变时,UI界面应做到即时响应。例如用户在应用启动过程中,上滑退出,那么启动动画应该立即过渡到退出动画,而不应该等启动动画完成后再退出,从而减少用户等待时间
# 案例一
import curves from '@ohos.curves';
// 判断是否进行动画衔接
class SetSlt{
public isAnimation:boolean = true
// 类的方法
public set():void{
this.isAnimation = !this.isAnimation;
}
}
@Entry
@Component
struct AnimationToAnimationDemo {
@State isHovered:boolean=false
// 第一步:声明相关状态变量
@State SetAnimation: SetSlt = new SetSlt();
build() {
Column() {
Text('ArkUI')
// 设置文本的字体粗细
.fontWeight(FontWeight.Bold)
// 设置文本的字体大小
.fontSize(12)
// 设置文本的字体颜色
.fontColor(Color.White)
// 设置文本的文本对齐方式:左对齐,居中对齐,右对齐
.textAlign(TextAlign.Center)
// 通用样式 设置元素的外边框圆角半径
.borderRadius(10)
// 通用样式 设置背景颜色
.backgroundColor(0xf56c6c)
// 通用样式 设置组件自身的宽度
.width(100)
// 通用样式 设置组件自身的高度
.height(100)
// 第二步:将状态变量设置到相关可动画属性接口
// 属性动画 设置页面过渡期间的缩放效果
.scale({ x: this.SetAnimation.isAnimation ? 2 : 1, y: this.SetAnimation.isAnimation ? 2 : 1 })
// 属性动画 设置动画曲线
.animation({ curve: curves.springMotion(0.4, 0.8) })
Button('Click')
.margin({ top: 70 })
// 点击触发
.onClick(() => {
this.SetAnimation.set()
})
Button(this.isHovered?"Hovered":"Not Hover")
.margin({ top: 50 })
.onHover((isHover:boolean)=>{
if (isHover) {
this.isHovered=isHover
}
})
.onMouse((event?: MouseEvent) => { // 设置Button的onMouse回调
if(event){
console.log('Button onMouse:\n' + '' +
'button = ' + event.button + '\n' +
'action = ' + event.action + '\n' +
'x,y = (' + event.x + ',' + event.y + ')' + '\n' +
'windowXY=(' + event.x + ',' + event.y + ')');
}
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 案例二
// 手势与动画的衔接
import curves from '@ohos.curves';
@Entry
@Component
struct SpringMotionDemo {
@State positionX: number = 100;
@State positionY: number = 100;
// 直径
diameter: number = 50;
build() {
Column() {
Row() {
// Circle 用于绘制圆形的组件
Circle({ width: this.diameter, height: this.diameter })
// 设置填充区域颜色
.fill(Color.Blue)
// 组件位置坐标
.position({ x: this.positionX, y: this.positionY })
// 触摸事件 https://docs.openharmony.cn/pages/v3.2/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-touch.md/
.onTouch((event?: TouchEvent) => {
if(event){
if (event.type === TouchType.Move) {
// 显式动画 https://docs.openharmony.cn/pages/v3.2/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md/
// 跟手过程,curve:动画曲线,使用responsiveSpringMotion曲线
animateTo({ curve: curves.responsiveSpringMotion() }, () => {
// 减去半径,以使球的中心运动到手指位置
this.positionX = event.touches[0].screenX - this.diameter / 2;
this.positionY = event.touches[0].screenY - this.diameter / 2;
console.info(`move, animateTo x:${this.positionX}, y:${this.positionY}`);
})
} else if (event.type === TouchType.Up) {
// 离手时,使用springMotion曲线
animateTo({ curve: curves.springMotion() }, () => {
this.positionX = 100;
this.positionY = 100;
console.info(`touchUp, animateTo x:100, y:100`);
})
}
}
})
}
.width("100%").height("80%")
.clip(true) // 如果球超出父组件范围,使球不可见
.backgroundColor(Color.Orange)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {
Text("拖动小球").fontSize(16)
}
.width("100%")
Row() {
Text('点击位置: [x: ' + Math.round(this.positionX) + ', y:' + Math.round(this.positionY) + ']').fontSize(16)
}
.padding(10)
.width("100%")
}.height('100%').width('100%')
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 案例三
@Entry
@Component
struct AnimateToExample {
@State widthSize: number = 250
@State heightSize: number = 100
@State rotateAngle: number = 0
private flag: boolean = true
build() {
Column() {
Button('change size')
.width(this.widthSize)
.height(this.heightSize)
.margin(30)
.onClick(() => {
if (this.flag) {
animateTo({
// 动画持续时间,单位为毫秒
duration: 2000,
// 动画曲线
curve: Curve.EaseOut,
// 动画播放次数。默认播放一次,设置为-1时表示无限次播放
iterations: 3,
// 动画播放模式,默认播放完成后重头开始播放
playMode: PlayMode.Normal,
// 动画播放完成回调
onFinish: () => {
console.info('play end')
}
}, () => {
this.widthSize = 150
this.heightSize = 60
})
} else {
animateTo({}, () => {
this.widthSize = 250
this.heightSize = 100
})
}
this.flag = !this.flag
})
// 改变旋转角度
Button('change rotate angle')
.margin(50)
// https://docs.openharmony.cn/pages/v3.2/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md/
// 图形变换
// 组件通用信息
.rotate({ x: 0, y: 0, z: 1, angle: this.rotateAngle })
.onClick(() => {
animateTo({
duration: 1200,
curve: Curve.Friction,
delay: 500,
iterations: -1, // 设置-1表示动画无限循环
playMode: PlayMode.Alternate,
onFinish: () => {
console.info('play end')
}
}, () => {
// 指定显示动效的闭包函数,在闭包函数中导致的状态变化系统会自动插入过渡动画
this.rotateAngle = 90
})
})
}.width('100%').margin({ top: 5 })
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66