1 Star 0 Fork 0

Stevenllv/MyAnimation

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

MyAnimation

一、工具

DevEco Studio 二、项目介绍

先来看看简单的特效

知识点:

属性动画概述 实现属性动画 自定义属性动画 1、动画示例1:

点击放大缩小

很简单在onClick()设置如下代码即可:

.onClick(() => { if (this.flag) { animateTo({ duration: 2000, curve: Curve.EaseOut, iterations: 1, playMode: PlayMode.Normal, onFinish: () => { console.info('play end') } }, () => { this.widthSize = 60 this.heightSize = 60 }) } else { animateTo({}, () => { this.widthSize = 100 this.heightSize = 100 }) } this.flag = !this.flag })

2、动画示例2:

单击旋转

代码:

.animation({//自身转动特效 duration: this.speed, curve: Curve.Linear, delay: 0, iterations: -1, // 设置-1表示动画无限循环 playMode: PlayMode.Normal }) 需要注意,rotateAngle = 360 speed -=1000发生变化才会触发动画。

所以改进后是这样的可以动态控制

.onClick(()=>{ if (this.isCenter) { animateTo({//自身转动特效 duration: 0, curve: Curve.Linear, delay: 0, iterations: 0, // 设置-1表示动画无限循环 playMode: PlayMode.Normal }, () => { this.rotateAngle = 0 }) promptAction.showToast({ message: '暂停', duration: 500 }) } else { animateTo({//自身转动特效 duration: 5000, curve: Curve.Linear, delay: 0, iterations: -1, // 设置-1表示动画无限循环 playMode: PlayMode.Normal }, () => { this.rotateAngle = 0 }) promptAction.showToast({ message: '开始', duration: 500 }) } this.isCenter = !this.isCenter

      //clearInterval(this.intervalID);
    })

进一步优化(动画衔接问题,看起来更顺畅):

setInterval(()=> {//每0.1秒执行0.5°的转动,动画更平滑

for (let index = 0; index < 12; index++) {
  let doubleAngle = (this.averageAngle - 30 * index + 0) * Math.PI / 180
  let sin = Math.sin(doubleAngle);
  let cos = Math.cos(doubleAngle);
  this.widAr[index] =this.radius1+this.radius1*cos
  this.heiAr[index] =this.radius2+this.radius2*sin * Math.cos(Math.PI * 5 / 18)
}

if (this.isRotate) {
  if (this.averageAngle<360) {//0~360°循环
    this.averageAngle+=0.5
  }else {
    this.averageAngle = 0;
  }
  this.rotateAngle = 360
}

}, 100)

3、动画示例3:

蚂蚁行走路径动画

代码设置:

Column() { Image($r('app.media.ant')) .width(100) .height(100) .margin(50) // 执行动画:从起点移动到(300,200),再到(300,500),再到终点 .motionPath({ path: 'Mstart.x start.y L300 200 L300 500 Lend.x end.y', from: 0.0, to: 2.0, rotatable: true }) .onClick(() => { animateTo({ duration: 4000, curve: Curve.Linear }, () => { this.toggle = !this.toggle // 通过this.toggle变化组件的位置 }) }) }.width('100%').height('28%').alignItems(this.toggle ? HorizontalAlign.Start : HorizontalAlign.Center) 点击执行

animateTo({ duration: 4000, curve: Curve.Linear }, () => { this.toggle = !this.toggle // 通过this.toggle变化组件的位置 })

触发路径动画motionPath({ path: 'Mstart.x start.y L300 200 L300 500 Lend.x end.y', from: 0.0, to: 2.0, rotatable: true })

监听蚂蚁位置后改变布局大小alignItems(this.toggle ? HorizontalAlign.Start : HorizontalAlign.Center)实现蚂蚁行走的过程。

4、动画示例4:

兔子跳舞动画

首秀用Row()+ForEach创建四只兔子。

Row() { ForEach(this.springs, (item: Spring) => { Motion({ iCurve: item.iCurve, dRotate: this.dRotate }) }) } 然后定义每只兔子的Spring动画效果:

private springs: Spring[] = [ new Spring( curves.springMotion(1, 0)), new Spring( curves.responsiveSpringMotion(0.8, 0)), new Spring( curves.interpolatingSpring(10, 1, 228, 30)), new Spring(curves.springCurve(10, 1, 228, 30)) ]; .onClick(() => { this.dRotate = -50; }) 只有点击执行动画,兔子就跳起来了,是不是很简单。

接下来我们来点干活,比较炫酷的动画场景。

十二星座之星空环绕 效果图:

首先准备十二张星座图片,Demo里面有(感兴趣可以去下载体验)

然后开始布局,使用RelativeContainer()相对布局

RelativeContainer() {

    Column(){
      Image($r('app.media.constellation1'))
        .width(this.img)
        .height(this.img)

      Text('天蝎座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[0],y:this.heiAr[0]})//星座旋转位置
    .id('star1')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击天蝎座',
        duration: 500
      })
    })


    Column(){
      Image($r('app.media.constellation2'))
        .width(this.img)
        .height(this.img)

      Text('处女座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[1],y:this.heiAr[1]})
    .id('star2')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击处女座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation3'))
        .width(this.img)
        .height(this.img)

      Text('双子座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[2],y:this.heiAr[2]})
    .id('star3')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击双子座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation4'))
        .width(this.img)
        .height(this.img)

      Text('双鱼座')
        .fontColor($r('app.color.white'))

    } .position({x:this.widAr[3],y:this.heiAr[3]})
    .id('star4')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击双鱼座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation5'))
        .width(this.img)
        .height(this.img)

      Text('金牛座')
        .fontColor($r('app.color.white'))

    } .position({x:this.widAr[4],y:this.heiAr[4]})
    .id('star5')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击金牛座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation6'))
        .width(this.img)
        .height(this.img)

      Text('射手座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[5],y:this.heiAr[5]})
    .id('star6')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击射手座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation7'))
        .width(this.img)
        .height(this.img)

      Text('狮子座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[6],y:this.heiAr[6]})
    .id('star7')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击狮子座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation8'))
        .width(this.img)
        .height(this.img)

      Text('摩羯座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[7],y:this.heiAr[7]})
    .id('star8')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击摩羯座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation9'))
        .width(this.img)
        .height(this.img)

      Text('巨蟹座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[8],y:this.heiAr[8]})
    .id('star9')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击巨蟹座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation10'))
        .width(this.img)
        .height(this.img)

      Text('水瓶座')
        .fontColor($r('app.color.white'))

    }.position({x:this.widAr[9],y:this.heiAr[9]})
    .id('star10')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击水瓶座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation11'))
        .width(this.img)
        .height(this.img)

      Text('天秤座')
        .fontColor($r('app.color.white'))

    } .position({x:this.widAr[10],y:this.heiAr[10]})
    .id('star11')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击天秤座',
        duration: 500
      })
    })

    Column(){
      Image($r('app.media.constellation12'))
        .width(this.img)
        .height(this.img)

      Text('白羊座')
        .fontColor($r('app.color.white'))

    } .position({x:this.widAr[11],y:this.heiAr[11]})
    .id('star12')
    .onClick(()=>{
      promptAction.showToast({
        message: '点击白羊座',
        duration: 500
      })
    })


  }.width('100%')
  .height('100%')
  .onAreaChange((oldValue: Area, newValue: Area) => {
    this.radius1 = new Number(newValue.width).valueOf()/2-25
    this.radius2 = new Number(newValue.height).valueOf()/2-25
  })

先把图片贴上去,然后计算旋转位置。

需用到一些计算公式

椭圆的标准方程是(x/a)^2 + (y/b)^2 =1

偏心率e=√(1 - (b/a)^2)

然后根据公式代码实现旋转后的坐标:

setInterval(()=> {//每0.1秒执行0.5°的转动,动画更平滑

for (let index = 0; index < 12; index++) {
  let doubleAngle = (this.averageAngle - 30 * index + 0) * Math.PI / 180
  let sin = Math.sin(doubleAngle);
  let cos = Math.cos(doubleAngle);
  this.widAr[index] =this.radius1+this.radius1*cos
  this.heiAr[index] =this.radius2+this.radius2*sin * Math.cos(Math.PI * 5 / 18)
}

if (this.isRotate) {
  if (this.averageAngle<360) {//0~360°循环
    this.averageAngle+=0.5
  }else {
    this.averageAngle = 0;
  }
  this.rotateAngle = 360
}

}, 100)

定义两个状态变量去更新UI:

@State widAr:Array = [this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1,this.radius1] @State heiAr:Array = [this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2,this.radius2] 最后我们来监听点击事件:

.onTouch((event?: TouchEvent) => {//页面监听滑动控 if(event){ if (event.type === TouchType.Down) { this.eventType = 'Down' this.x1 =event.touches[0].x this.isRotate = false } if (event.type === TouchType.Up) { this.eventType = 'Up' this.isRotate = true } if (event.type === TouchType.Move) { this.eventType = 'Move'

      this.x2 =event.touches[0].x -this.x1


      //左右滑动控制转动
      if (event.touches[0].y<this.radius2){
        if (this.x2>0) {
          this.averageAngle +=5
        }else {
          this.averageAngle -=5
        }
      }else {
        if (this.x2>0) {
          this.averageAngle -=5
        }else {
          this.averageAngle +=5
        }
      }
    }
  }
})

实现左右滑动加速效果,背景给一个星空背景,这样一来就实现了旋转的十二星辰。

源码Demo:MyAnimation: 鸿蒙动画特效旋转的十二星辰

特技

  1. 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
  2. Gitee 官方博客 blog.gitee.com
  3. 你可以 https://gitee.com/explore 这个地址来了解 Gitee 上的优秀开源项目
  4. GVP 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
  5. Gitee 官方提供的使用手册 https://gitee.com/help
  6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 https://gitee.com/gitee-stars/

空文件

简介

鸿蒙动画特效旋转的十二星辰 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/stevenllv/MyAnimation.git
git@gitee.com:stevenllv/MyAnimation.git
stevenllv
MyAnimation
MyAnimation
master

搜索帮助