(七)ArkTS 动画效果实现

2025-03-12 22:52:51
182次阅读
0个评论

ArkTS 动画效果实现

一、动画基础概念

动画类型与原理

在 ArkTS 开发中,动画是赋予应用生动交互体验的关键手段。动画主要分为补间动画和属性动画。补间动画通过定义起始状态和结束状态,由系统自动计算中间过渡帧,实现动画效果,其原理基于对图形的平移、旋转、缩放等基本变换操作。例如,一个按钮从屏幕左侧移动到右侧的动画,只需定义按钮的初始位置(左侧)和最终位置(右侧),系统会在动画执行期间自动计算并渲染按钮在不同时刻的中间位置。

属性动画则更为灵活,它可以对任意对象的属性进行动画操作,不仅限于图形的变换。属性动画通过改变对象的属性值,如颜色、透明度、自定义属性等,来实现动画效果。其原理是在一段时间内,按照设定的动画曲线,逐步改变目标属性的值,从而呈现出动画效果。比如,让一个图片的透明度从 1 逐渐变为 0,实现图片淡入淡出的动画。

动画的生命周期

动画具有完整的生命周期,包括初始化、开始、运行、结束和取消等阶段。在初始化阶段,动画的参数,如持续时间、动画曲线、起始和结束值等被设置。当动画开始时,它进入运行阶段,按照设定的规则逐步改变目标对象的属性。在运行过程中,动画可以被暂停、恢复或取消。当动画到达结束状态时,会触发相应的结束回调函数,开发者可以在此处进行一些清理操作或触发后续的逻辑。例如,在一个图片旋转动画结束后,显示一段文字说明。

二、基础动画效果

平移动画

平移动画是最常见的动画效果之一,用于改变对象在屏幕上的位置。在 ArkTS 中,通过animate函数结合translate属性来实现平移动画。例如,使一个按钮从初始位置向右平移 200 像素: @Entry @Component struct TranslateAnimationExample { @State isAnimated: boolean = false; toggleAnimation() { this.isAnimated =!this.isAnimated; } build() { Button('点击平移') .translate({ x: this.isAnimated? 200 : 0, y: 0 }) .animate({ duration: 500, curve: AnimationCurve.Linear }) .onClick(this.toggleAnimation.bind(this)); } } 在上述代码中,通过点击按钮,isAnimated状态变量切换,从而改变按钮的x轴平移距离。animate函数设置了动画的持续时间为 500 毫秒,动画曲线为线性(AnimationCurve.Linear),使按钮匀速平移。

缩放动画

缩放动画用于改变对象的大小。在 ArkTS 中,通过scale属性实现缩放动画。例如,让一个图片在点击时放大 1.5 倍: @Entry @Component struct ScaleAnimationExample { @State isScaled: boolean = false; toggleScale() { this.isScaled =!this.isScaled; } build() { Image('example.jpg') .scale({ x: this.isScaled? 1.5 : 1, y: this.isScaled? 1.5 : 1 }) .animate({ duration: 300, curve: AnimationCurve.EaseInOut }) .onClick(this.toggleScale.bind(this)); } }

这里,图片的scale属性根据isScaled状态变量的值改变,animate函数设置了动画时长为 300 毫秒,动画曲线为缓入缓出(AnimationCurve.EaseInOut),使缩放动画更加自然。

三、复杂动画组合

动画序列与并行

在实际应用中,常常需要将多个动画组合使用,以实现更丰富的效果。动画序列是指多个动画依次执行。例如,先让一个元素平移,平移结束后再进行缩放动画。可以通过sequence函数来实现: @Entry @Component struct SequentialAnimationExample { @State isAnimated: boolean = false; startAnimation() { this.isAnimated = true; } build() { Rectangle() .width(100) .height(100) .fill(Color.Blue) .translate({ x: this.isAnimated? 200 : 0, y: 0 }) .animate({ duration: 500, curve: AnimationCurve.Linear }) .scale({ x: this.isAnimated? 2 : 1, y: this.isAnimated? 2 : 1 }) .animate(sequence([ { duration: 500, curve: AnimationCurve.Linear }, { duration: 300, curve: AnimationCurve.EaseInOut, delay: 500 } ])) .onClick(this.startAnimation.bind(this)); } }

在这段代码中,矩形先进行 500 毫秒的线性平移动画,然后延迟 500 毫秒后,进行 300 毫秒的缓入缓出缩放动画。 动画并行则是多个动画同时执行。使用parallel函数可以实现,例如,让一个元素同时进行平移和旋转动画: @Entry @Component struct ParallelAnimationExample { @State isAnimated: boolean = false; startAnimation() { this.isAnimated = true; } build() { Circle() .width(100) .height(100) .fill(Color.Red) .translate({ x: this.isAnimated? 150 : 0, y: 0 }) .rotate({ angle: this.isAnimated? 360 : 0 }) .animate(parallel([ { duration: 800, curve: AnimationCurve.Linear }, { duration: 800, curve: AnimationCurve.Linear } ])) .onClick(this.startAnimation.bind(this)); } }

此代码中,圆形在 800 毫秒内同时进行线性平移和线性旋转动画。

关键帧动画实现

关键帧动画允许开发者精确控制动画在不同时间点的状态。通过定义多个关键帧,每个关键帧包含特定时间点的属性值,系统会在关键帧之间进行插值计算,生成平滑的动画效果。例如,创建一个沿不规则路径移动的动画: @Entry @Component struct KeyframeAnimationExample { @State isAnimated: boolean = false; startAnimation() { this.isAnimated = true; } build() { Image('icon.png') .translate({ x: this.isAnimated? 0 : 0, y: this.isAnimated? 0 : 0 }) .animate({ duration: 1500, curve: AnimationCurve.Linear, keyframes: [ { offset: 0, value: { x: 0, y: 0 } }, { offset: 0.3, value: { x: 100, y: 50 } }, { offset: 0.7, value: { x: 150, y: 150 } }, { offset: 1, value: { x: 200, y: 100 } } ] }) .onClick(this.startAnimation.bind(this)); } }

收藏00

登录 后评论。没有帐号? 注册 一个。