赞
踩
一、ArkUI组件属性动画和显示动画
显示动画:
案例:上下左右箭头控制小鱼的游动 具体代码如下:
import router from '@ohos.router' @Entry @Component struct AnimationPage { // 小鱼坐标 @State fishX: number = 200 @State fishY: number = 180 // 小鱼角度 @State angle: number = 0 // 小鱼图片 @State src: Resource = $r('app.media.fish') // 是否开始游戏 @State isBegin: boolean = false build() { Row() { Stack() { // 返回按钮 Button('返回') .position({ x: 0, y: 0 }) .backgroundColor('#20101010') .onClick(() => { // 返回上一页 router.back() }) if (!this.isBegin) { // 开始游戏 Button('开始游戏') .onClick(() => { // 点击后显示小鱼 this.isBegin = true }) } else { // 小鱼图片 Image(this.src) .position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标 .rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }) .width(40) .height(40) //.animation({duration: 500}) // 操作按钮 Row() { Button('⬅').backgroundColor('#20101010') .onClick(() => { // this.fishX -= 20 // this.src = $r('app.media.fish_rev') // 显示动画 animateTo({ duration: 500 }, () => { this.fishX -= 20 this.src = $r('app.media.fish_rev') }) }) Column({ space: 40 }) { Button('⬆').backgroundColor('#20101010') .onClick(() => { this.fishY -= 20 }) Button('⬇').backgroundColor('#20101010') .onClick(() => { this.fishY += 20 }) } Button('➡').backgroundColor('#20101010') .onClick(() => { this.fishX += 20 this.src = $r('app.media.fish') }) } .width(240) .height(240) } } .width('100%') .height('100%') } .height('100%') } }
二、ArkUI组件转场动画
代码如下:
import router from '@ohos.router' @Entry @Component struct AnimationPage { // 小鱼坐标 @State fishX: number = 200 @State fishY: number = 180 // 小鱼角度 @State angle: number = 0 // 小鱼图片 @State src: Resource = $r('app.media.fish') // 是否开始游戏 @State isBegin: boolean = false build() { Row() { Stack() { // 返回按钮 Button('返回') .position({ x: 0, y: 0 }) .backgroundColor('#20101010') .onClick(() => { // 返回上一页 router.back() }) if (!this.isBegin) { // 开始游戏 Button('开始游戏') .onClick(() => { // 点击后显示小鱼 // this.isBegin = true // 转场动画需结合animateTo才能生效 animateTo({ duration: 1000 }, () => { // 点击后显示小鱼 this.isBegin = true }) }) } else { // 小鱼图片 Image(this.src) .position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标 .rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }) .width(40) .height(40) //.animation({duration: 500}) // 添加转场动画 .transition({ // 开始游戏,入场动画 type: TransitionType.Insert, opacity: 0, //一开始是透明的 translate: { x: -250 } }) } // 操作按钮 Row() { Button('⬅').backgroundColor('#20101010') .onClick(() => { // this.fishX -= 20 // this.src = $r('app.media.fish_rev') // 显示动画 animateTo({ duration: 500 }, () => { this.fishX -= 20 this.src = $r('app.media.fish_rev') }) }) Column({ space: 40 }) { Button('⬆').backgroundColor('#20101010') .onClick(() => { this.fishY -= 20 }) Button('⬇').backgroundColor('#20101010') .onClick(() => { this.fishY += 20 }) } Button('➡').backgroundColor('#20101010') .onClick(() => { this.fishX += 20 this.src = $r('app.media.fish') }) } .width(240) .height(240) .justifyContent(FlexAlign.Center) .position({x: 0, y: 120}) } .width('100%') .height('100%') } .height('100%') } }
三、ArkUI组件实现摇杆功能
此功能自行开发
此块涉及到的主要是算法 ,比如三角函数
角度正弦和余弦
import router from '@ohos.router' import { TouchEvent } from '@ohos.multimodalInput.touchEvent' import curves from '@ohos.curves' @Entry @Component struct AnimationPage { // 小鱼坐标 @State fishX: number = 200 @State fishY: number = 180 // 小鱼角度 @State angle: number = 0 // 小鱼图片 @State src: Resource = $r('app.media.fish') @State srcBg: Resource = $r('app.media.bg') // 是否开始游戏 @State isBegin: boolean = false // 摇杆中心区域坐标 private centerX: number = 120 private centerY: number = 120 // 大、小圆半径 private maxRadius: number = 100 private radius: number = 20 // 摇杆小圆球初始位置 @State positionX: number = this.centerX; @State positionY: number = this.centerY; // 角度正弦和余弦 sin: number = 0 cos: number = 0 // 小鱼移动速度 speed: number = 0 // 任务id taskId: number = -1 build() { Row() { Stack() { // 返回按钮 Button('返回') .position({ x: 0, y: 0 }) .backgroundColor('#20101010') .onClick(() => { // 返回上一页 router.back() }) if (!this.isBegin) { // 开始游戏 Button('开始游戏') .onClick(() => { // 点击后显示小鱼 // this.isBegin = true // 转场动画需结合animateTo才能生效 animateTo({ duration: 1000 }, () => { // 点击后显示小鱼 this.isBegin = true }) }) } else { // 小鱼图片 Image(this.src) .position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标 .rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }) .width(40) .height(40) //.animation({duration: 500}) // 添加转场动画 .transition({ // 开始游戏,入场动画 type: TransitionType.Insert, opacity: 0, //一开始是透明的 translate: { x: -250 } }) } // 操作按钮 Row() { Circle( {width: this.maxRadius * 2, height: this.maxRadius * 2}) .fill('#20101010') .position({x: this.centerX - this.maxRadius, y: this.centerY - this.maxRadius}) Circle( {width: this.radius * 2, height: this.radius * 2}) .fill('#403A3A3A') .position({x: this.positionX - this.radius, y: this.positionY - this.radius}) } .width(240) .height(240) .justifyContent(FlexAlign.Center) .position({x: 0, y: 120}) .onTouch(this.handleTouchEvent.bind(this)) } .width('100%') .height('100%') } .height('100%') .width('100%') .backgroundImage(this.srcBg) } // 处理手指移动的函数 handleTouchEvent(event: TouchEvent) { // 1、先获取手指位置坐标 // .x .y 我获取不到? 为啥 let x = event.touches[0].screenX // @ts-ignore let y = event.touches[0].screenY // 2、计算手指与中心点的坐标差值 let vx = x - this.centerX let vy = y - this.centerY // 3、计算手指与中心点连线和x轴正半轴的夹角,单位是弧度 let angle = Math.atan2(vy, vx); // 4、计算手指与中心点的距离(角度正弦和余弦) let distance = this.getDistance(vx, vy) // 5、计算摇杆小球的坐标(x轴和y轴) this.sin = Math.sin(angle) this.cos = Math.cos(angle) animateTo({curve: curves.responsiveSpringMotion()}, () => { this.positionX = this.centerX + (distance * this.sin) this.positionY = this.centerY + (distance * this.cos) }) } getDistance(x: number, y: number) { let d = Math.sqrt(x * x + y * y) return Math.min(d, this.maxRadius) } }
最终版:
import router from '@ohos.router' import curves from '@ohos.curves' @Entry @Component struct AnimationPage { // 小鱼坐标 @State fishX: number = 200 @State fishY: number = 180 // 小鱼角度 @State angle: number = 0 // 小鱼图片 @State src: Resource = $r('app.media.fish') @State srcBg: Resource = $r('app.media.bg') // 是否开始游戏 @State isBegin: boolean = false // 摇杆中心区域坐标 private centerX: number = 120 private centerY: number = 120 // 大、小圆半径 private maxRadius: number = 100 private radius: number = 20 // 摇杆小圆球初始位置 @State positionX: number = this.centerX; @State positionY: number = this.centerY; // 角度正弦和余弦 sin: number = 0 cos: number = 0 // 小鱼移动速度 speed: number = 0 // 任务id taskId: number = -1 build() { Row() { Stack() { // 返回按钮 Button('返回') .position({ x: 0, y: 0 }) .backgroundColor('#20101010') .onClick(() => { // 返回上一页 router.back() }) if (!this.isBegin) { // 开始游戏 Button('开始游戏') .onClick(() => { // 点击后显示小鱼 // this.isBegin = true // 转场动画需结合animateTo才能生效 animateTo({ duration: 1000 }, () => { // 点击后显示小鱼 this.isBegin = true }) }) } else { // 小鱼图片 Image(this.src) .position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标 .rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }) .width(40) .height(40) //.animation({duration: 500}) // 添加转场动画 .transition({ // 开始游戏,入场动画 type: TransitionType.Insert, opacity: 0, //一开始是透明的 translate: { x: -250 } }) } // 操作按钮 Row() { Circle( {width: this.maxRadius * 2, height: this.maxRadius * 2}) .fill('#20101010') .position({x: this.centerX - this.maxRadius, y: this.centerY - this.maxRadius}) Circle( {width: this.radius * 2, height: this.radius * 2}) .fill('#403A3A3A') .position({x: this.positionX - this.radius, y: this.positionY - this.radius}) } .width(240) .height(240) .justifyContent(FlexAlign.Center) .position({x: 0, y: 120}) .onTouch(this.handleTouchEvent.bind(this)) } .width('100%') .height('100%') } .height('100%') .width('100%') .backgroundImage(this.srcBg) } // 处理手指移动的函数 handleTouchEvent(event: TouchEvent) { switch (event.type) { case TouchType.Up: // 还原小鱼的速度 this.speed = 0 // 取消定时任务 clearInterval(this.taskId) // 还原摇杆小球的坐标 springMotion:还原动画 animateTo({curve: curves.springMotion()}, () => { this.positionX = this.centerX this.positionY = this.centerY this.angle = 0 }) break case TouchType.Down: // 开始定时任务 this.taskId = setInterval(() => { this.fishX += this.speed * this.cos this.fishY += this.speed * this.sin }, 40); break case TouchType.Move: // 1、先获取手指位置坐标 let x = event.touches[0].x let y = event.touches[0].y // 2、计算手指与中心点的坐标差值 let vx = x - this.centerX let vy = y - this.centerY // 3、计算手指与中心点连线和x轴正半轴的夹角,单位是弧度 let angle = Math.atan2(vy, vx); // 4、计算手指与中心点的距离(角度正弦和余弦) let distance = this.getDistance(vx, vy) this.sin = Math.sin(angle) this.cos = Math.cos(angle) // responsiveSpringMotion:跟手动画 animateTo({curve: curves.responsiveSpringMotion()}, () => { // 5、计算摇杆小球的坐标(x轴和y轴) 使用显示动画改变坐标 this.positionX = this.centerX + (distance * this.sin) this.positionY = this.centerY + (distance * this.cos) // 6、修改小鱼的角度 [弧度转角度] if (Math.abs(angle * 2) < Math.PI) { // 判断弧度是否小于90度 正负90度 朝右游 this.src = $r('app.media.fish') } else { this.src = $r('app.media.fish_rev') angle = angle < 0 ? angle + Math.PI : angle - Math.PI } this.angle = angle * 180 / Math.PI this.speed = 5 }) break } } getDistance(x: number, y: number) { let d = Math.sqrt(x * x + y * y) return Math.min(d, this.maxRadius) } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。