赞
踩
动画曲线是属性关于时间的变化函数,决定属性变化时产生动画的运动轨迹。某一时刻下动画曲线的斜率代表动画的速度,对应属性变化的快慢。一条优秀的动画曲线具备连续光滑、符合用户意图、符合物理世界客观规律的特点。开发者可结合用户的使用场景和意图,为动效选取合适的动画曲线。
根据动画曲线是否符合物理世界客观规律,可将其分为物理曲线(ArkUI当前提供了多种物理弹簧曲线)和传统曲线两种类型。相比于传统曲线,物理曲线产生的运动轨迹更加符合用户认知,有助于创造自然生动的动画效果,建议开发者优先使用物理曲线。
传统曲线基于数学公式,创造形状符合开发者预期的动画曲线。以三阶贝塞尔曲线为代表,通过调整曲线控制点,可以改变曲线形状,从而带来缓入、缓出等动画效果。对于同一条传统曲线,由于不具备物理含义,其形状不会因为用户行为发生任何改变,缺少物理动画的自然感和生动感。建议优先采用物理曲线创建动画,将传统曲线作为辅助用于极少数必要场景中。
ArkUI提供了贝塞尔曲线、阶梯曲线等传统曲线接口,开发者可参照 插值计算 进行查阅。
传统曲线的示例和效果如下:
class MyCurve { public title: string; public curve: Curve; public color: Color | string; constructor(title: string, curve: Curve, color: Color | string = '') { this.title = title; this.curve = curve; this.color = color; } } const myCurves: MyCurve[] = [ new MyCurve(' Linear', Curve.Linear, '#317AF7'), new MyCurve(' Ease', Curve.Ease, '#D94838'), new MyCurve(' EaseIn', Curve.EaseIn, '#DB6B42'), new MyCurve(' EaseOut', Curve.EaseOut, '#5BA854'), new MyCurve(' EaseInOut', Curve.EaseInOut, '#317AF7'), new MyCurve(' FastOutSlowIn', Curve.FastOutSlowIn, '#D94838') ] @Entry @Component export struct CurveDemo { @State dRotate: number = 0; // 旋转角度 build() { Column() { // 曲线图例 Grid() { ForEach(myCurves, (item: MyCurve) => { GridItem() { Column() { Row() .width(30) .height(30) .borderRadius(15) .backgroundColor(item.color) Text(item.title) .fontSize(15) .fontColor(0x909399) } .width('100%') } }) } .columnsTemplate('1fr 1fr 1fr') .rowsTemplate('1fr 1fr 1fr 1fr 1fr') .padding(10) .width('100%') .height(300).margin({top:50}) Stack() { // 摆动管道 Row() .width(290) .height(290) .border({ width: 15, color: 0xE6E8EB, radius: 145 }) ForEach(myCurves, (item: MyCurve) => { // 小球 Column() { Row() .width(30) .height(30) .borderRadius(15) .backgroundColor(item.color) } .width(20) .height(300) .rotate({ angle: this.dRotate }) .animation({ duration: 2000, iterations: -1, curve: item.curve, delay: 100 }) }) } .width('100%') .height(200) .onClick(() => { this.dRotate ? null : this.dRotate = 360; }) } .width('100%') } }
阻尼弹簧曲线(以下简称弹簧曲线)对应的阻尼弹簧系统中,偏离平衡位置的物体一方面受到弹簧形变产生的反向作用力,被迫发生振动。另一方面,阻尼的存在为物体振动提供阻力。除阻尼为0的特殊情况,物体在振动过程中振幅不断减小,且最终趋于0,其轨迹对应的动画曲线自然连续。
采用弹簧曲线的动画在达终点时动画速度为0,不会产生动画“戛然而止”的观感,以避免影响用户体验。
ArkUI提供了四种阻尼弹簧曲线接口。
springMotion不提供速度设置接口,速度通过继承获得,无需开发者指定。对于某个属性,如果当前存在正在运行的springMotion或者responsiveSpringMotion类型动画,新创建的弹簧动画将停止正在运行的动画,并继承其当前时刻的动画属性值和速度作为新建动画的初始状态。此外,接口提供默认参数,便于开发者直接使用。
function springMotion(response?: number, dampingFraction?: number, overlapDuration?: number): ICurve;
当新动画的overlapDuration参数不为0,且当前属性的上一个springMotion动画还未结束时,response和dampingFraction将在overlapDuration指定的时间内,从旧动画的参数值过渡到新动画的参数值。
function responsiveSpringMotion(response?: number, dampingFraction?: number, overlapDuration?: number): ICurve;
interpolatingSpring :适合于需要指定初速度的动效场景,动画时长同样由接口参数自动计算,开发者在动画接口中指定的时长不生效。
曲线接口提供速度入参,且由于接口对应一条从0到1的阻尼弹簧曲线,实际动画值根据曲线进行插值计算。所以速度也应该为归一化速度,其值等于动画属性改变的绝对速度除以动画属性改变量。因此不适合于动画起点属性值和终点属性值相同的场景,此时动画属性改变量为0,归一化速度不存在。
function interpolatingSpring(velocity: number, mass: number, stiffness: number, damping: number): ICurve;
function springCurve(velocity: number, mass: number, stiffness: number, damping: number): ICurve;
关于弹簧曲线完整的使用示例和参考效果如下,开发者也可参考 动画衔接 ,掌握使用responsiveSpringMotion和springMotion进行手势和动画之间的衔接。
弹簧曲线的示例代码和效果如下。
import curves from '@ohos.curves'; class Spring { public title: string; public subTitle: string; public iCurve: ICurve; constructor(title: string, subTitle: string, iCurve: ICurve) { this.title = title; this.iCurve = iCurve; this.subTitle = subTitle; } } // 弹簧组件 @Component struct Motion { @Prop dRotate: number = 0 private title: string = "" private subTitle: string = "" private iCurve: ICurve | undefined = undefined build() { Column() { Circle() .translate({ y: this.dRotate }) .animation({ curve: this.iCurve, iterations: -1 }) .foregroundColor('#317AF7') .width(30) .height(30) Column() { Text(this.title) .fontColor(Color.Black) .fontSize(10).height(30) Text(this.subTitle) .fontColor(0xcccccc) .fontSize(10).width(50) } .borderWidth({ top: 1 }) .borderColor(0xf5f5f5) .width(80) .alignItems(HorizontalAlign.Center) .height(100) } .height(110) .margin({ bottom: 5 }) .alignItems(HorizontalAlign.Center) } } @Entry @Component export struct SpringCurve { @State dRotate: number = 0; private springs: Spring[] = [ new Spring('springMotion', '周期2, 阻尼0.25', curves.springMotion(1, 0.25)), new Spring('responsive' + '\n' + 'SpringMotion', '默认弹性跟手曲线', curves.responsiveSpringMotion(1, 0.25)), new Spring('interpolating' + '\n' + 'Spring', '初始速度10,质量1, 剛度228, 阻尼30', curves.interpolatingSpring(10, 1, 228, 30)), new Spring('springCurve', '初始速度10, 质量1, 剛度228, 阻尼30', curves.springCurve(10, 1, 228, 30)) ]; build() { Row() { ForEach(this.springs, (item: Spring) => { Motion({ title: item.title, subTitle: item.subTitle, iCurve: item.iCurve, dRotate: this.dRotate }) }) } .justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Bottom) .width('100%') .height(437) .margin({ top: 20 }) .onClick(() => { this.dRotate = -50; }) } }
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档用来跟着学习是非常有必要的。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
gitee.com/MNxiaona/733GH
gitee.com/MNxiaona/733GH
1.基本概念
2.构建第一个ArkTS应用
3.……
gitee.com/MNxiaona/733GH
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
gitee.com/MNxiaona/733GH
gitee.com/MNxiaona/733GH
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。