OpenHarmony动画添加交互效果的实用方案
一、交互设计思路与事件绑定
二、ArkTS声明式UI的显式动画交互
@Entry
@Component
struct CardPressDemo {
@State pressed: boolean = false
@State scale: number = 1
@State shadow: number = 4
build() {
Column({ space: 20 }) {
Text('ArkTS 显式动画交互')
.fontSize(20)
Stack({ alignContent: Alignment.Center }) {
// 交互目标:带阴影的卡片
Column()
.width(160)
.height(100)
.backgroundColor(Color.White)
.borderRadius(12)
.shadow({ radius: this.shadow, color: '#40000000', offsetY: 2 })
.scale({ x: this.scale, y: this.scale })
.onClick(() => {
// 点击:放大 + 加深阴影
animateTo({ duration: 180, curve: Curve.EaseOut }, () => {
this.scale = 0.96
this.shadow = 12
})
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
// 抬起/取消:恢复
animateTo({ duration: 180, curve: Curve.EaseOut }, () => {
this.scale = 1
this.shadow = 4
})
}
})
Text('点我')
.fontSize(16)
.fontColor('#333')
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.padding(20)
}
}
三、JS FA模型的组件与帧动画交互
<!-- index.hml -->
<div class="container">
<!-- 图片点击阴影反馈 -->
<div class="card" onclick="onCardClick('img')"
ontouchstart="setShadow('img', true)"
ontouchend="setShadow('img', false)">
<image class="main-img {{imgClass}}" src="common/images/demo.png" />
</div>
<!-- 帧动画点击播放 -->
<div class="card" onclick="playFrameAnim('anim')">
<image-animator id="anim"
class="animator"
images="{{frameList}}"
duration="{{frameDuration}}"
iteration="1" />
</div>
</div>
// index.js
export default {
data: {
imgClass: '',
frameList: [
{ src: 'common/images/frame_01.png' },
{ src: 'common/images/frame_02.png' },
{ src: 'common/images/frame_03.png' }
],
frameDuration: 80
},
setShadow(type, flag) {
if (type === 'img') {
this.imgClass = flag ? 'main-img-touch' : ''
}
},
playFrameAnim(id) {
const anim = this.$element(id)
if (anim) {
anim.start() // 触发帧动画播放
}
}
}
四、Lottie动画的交互控制
// LottieView.ets
import lottie from '@ohos/lottie'
@Entry
@Component
struct LottieDemo {
@State times: number = 0
private animateItem: any = null
private controller: CanvasRenderingContext2D = new CanvasRenderingContext2D()
private path: string = 'common/politeChicky.json'
private textArray: string[] = ['Hello', 'Lottie', 'OpenHarmony']
loadAnimation(autoplay: boolean) {
if (this.animateItem) {
this.animateItem.destroy()
this.animateItem = null
}
this.animateItem = lottie.loadAnimation({
container: this.controller,
renderer: 'canvas',
loop: false,
autoplay: autoplay,
name: 'lottieAnim',
path: this.path,
initialSegment: [0, 60] // 示例:播放前60帧
})
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
Canvas(this.controller)
.width(200)
.height(200)
.backgroundColor('#F5F5F5')
.borderRadius(12)
.onClick(() => {
this.loadAnimation(true) // 点击播放
this.times = (this.times + 1) % this.textArray.length
})
.onReady(() => {
this.loadAnimation(false) // 初始化不自动播放
})
Text(this.textArray[this.times])
.fontSize(18)
.fontColor(Color.White)
.margin({ top: 16 })
}
.margin({ top: 40 })
}
}
五、与后端数据联动的动画
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。