HarmonyOS 鸿蒙Next中根据ID从一点到另一点到动画设计
HarmonyOS 鸿蒙Next中根据ID从一点到另一点到动画设计 工具类util:
import { Animator as animator, AnimatorResult, AnimatorOptions, Offset, componentUtils, UIContext } from '@kit.ArkUI'
export class AnimateMoveById {
constructor(fromPosId: string, toPosId: string, uiContext: UIContext, currentPos: Offset,
animatorOptions?: AnimatorOptions, onFinish?: () => void, onCancel?: ()=> void) {
this.fromPosId = fromPosId
this.toPosId = toPosId
this.uiContext = uiContext
this.currentPos = currentPos
if (animatorOptions) {
this.controller = animator.create(animatorOptions)
} else {
this.controller = animator.create({
// 建议使用 this.getUIContext.creatAnimator()接口
duration: 3000,
easing: "ease",
delay: 0,
fill: "forwards",
direction: "normal",
iterations: 1,
begin: 0.0,
end: 100.0
})
}
if(onFinish){
this.controller.onFinish = onFinish
}
if(onCancel){
this.controller.onCancel = onCancel
}
}
controller: AnimatorResult | undefined = undefined
fromPosId: string = ''
toPosId: string = ''
fromPos: Offset | null = null
toPos: Offset | null = null
currentPos: Offset = { x: 0, y: 0 }
uiContext: UIContext = new UIContext()
play(): AnimateMoveById {
this.fromPos = componentUtils.getRectangleById(this.fromPosId).windowOffset
this.toPos = componentUtils.getRectangleById(this.toPosId).windowOffset
this.currentPos!!.x = this.uiContext.px2vp(this.fromPos.x)
this.currentPos!!.y = this.uiContext.px2vp(this.fromPos.y)
let ox = this.currentPos!!.x
let oy = this.currentPos!!.y
if (this.controller) {
this.controller.onFrame = (value: number) => {
if (this.currentPos) {
this.currentPos!!.x =
this.uiContext.px2vp((this.toPos!!.x - this.fromPos!!.x) * value / 100.0) + ox
this.currentPos!!.y =
this.uiContext.px2vp((this.toPos!!.y - this.fromPos!!.y) * value / 100.0) + oy
}
}
this.controller.play()
}
return this
}
}
使用时:
let options: AnimatorOptions = {
duration: 6000,
easing: "ease",
delay: 0,
fill: "forwards",
direction: "normal",
iterations: 1,
begin: 0.0,
end: 100.0
}
let a = new AnimateMoveById('0', '1', this.getUIContext(), this.currentPos!!, options, () => {
toast.show('动画结束了!')
}, () => {
toast.show('取消动画回调')
})
this.animateText = '这是一个动画'
// a.controller!!.onCancel = () => {
// toast.show('取消动画回调')
// }
// if(a.controller){
// a.controller.onFinish = () =>{
// toast.show('动画结束了!')
// }
// }
a.play()
// setTimeout(() => {
// a.controller?.cancel()
// }, 2000)
})
更多关于HarmonyOS 鸿蒙Next中根据ID从一点到另一点到动画设计的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
在HarmonyOS Next中,可通过animateTo
方法实现基于ID的组件间动画。使用globalThis
或组件上下文获取目标ID的引用,配置位置、平移等属性变化。通过animation
属性定义动画曲线与时长,例如使用animateTo
执行位移。具体实现需结合ArkUI声明式语法与状态管理驱动动画过程。
更多关于HarmonyOS 鸿蒙Next中根据ID从一点到另一点到动画设计的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,通过组件ID实现动画移动是可行的,但代码存在几个关键问题需要修正:
- 构造函数中的
currentPos
参数类型应为Offset
引用而非值传递,否则无法实时更新位置。建议改为:
constructor(..., currentPos: Ref<Offset>, ...)
px2vp
单位转换逻辑错误,应该先计算物理像素差值再转换:
this.currentPos.x = ox + this.uiContext.px2vp((this.toPos.x - this.fromPos.x) * value / 100)
this.currentPos.y = oy + this.uiContext.px2vp((this.toPos.y - this.fromPos.y) * value / 100)
-
建议使用
getUIContext().createAnimator()
替代直接调用animator.create,确保动画与当前UI上下文关联 -
需要确保源和目标组件已通过.id()方法设置有效ID,且组件已完成布局(建议在onReady后执行动画)
修正后的play()方法应包含位置获取的null检查,避免运行时错误。