鸿蒙开发:简单了解属性动画

简介: 无论是是使用animateTo还是animation,其实最终要改变的都是组件的可执行属性,最终的效果是一致的,animateTo是闭包内改变属性引起的界面变化,一般作用于出现消失转场,而animation则是组件通过属性接口绑定的属性变化引起的界面变化,一般使用场景为,animateTo适用对多个可动画属性配置相同动画参数的动画,需要嵌套使用动画的场景;animation适用于对多个可动画属性配置不同参数动画的场景。

前言

运行环境:基于HarmonyOs NEXT

DevEco Studio:Build Version: 5.0.3.900

API:12

modelVersion5.0.0


什么是属性动画呢?字面之义就是让属性产生动画,产生某些可执行的动作,使其和原有的UI形态发生了根本的变化,当然了,其本身也类似这层意思;属性动画中,我们需要知道,并不是所有的属性都可以执行动画操作,比如一个组件,设置焦点控制,禁用控制,改变的只是动作状态,而本身的UI形态并没有发生变化,所以并不能执行动画,也就不属于动画属性。

是否定义为一个可执行动画属性,有两个标准,第一个是改变它能够使其UI发生变化,比如宽高,内边距,外边距属性,第二就是,改变它,可以添加动画作为过渡,不做动画,又何谈属性动画呢,是吧。


常见的可执行动画属性,如下:


分类

说明

布局属性

位置、大小、内边距、外边距、对齐方式、权重等。

仿射变换

平移、旋转、缩放、锚点等。

背景

背景颜色、背景模糊等。

内容

文字大小、文字颜色,图片对齐方式、模糊等。

前景

前景颜色等。

Overlay

Overlay属性等。

外观

透明度、圆角、边框、阴影等。


实现属性动画


属性动画最注重的就是两点,一是必须使其UI发生改变,二是能够有动画产生连续效果,目前在鸿蒙开发中,系统提供了两个可以实现属性动画的方式,使用animateTo和animation来实现。


简单举例:


使用animateTo让组件平移100,动画持续时间为1秒。


@Entry
@Component
struct Index {
  @State translateX: number = 0
  build() {
    Column() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .translate({ x: this.translateX })
      Button("点击")
        .margin({ top: 10 })
        .onClick(() => {
          this.getUIContext()?.animateTo({ duration: 1000 }, () => {
            this.translateX = 100 //x轴移动100
          })
        })
    }
    .height('100%')
    .width('100%')
  }
}


使用animation让组件平移100,动画持续时间为1秒。


@Entry
@Component
struct Index {
  @State translateX: number = 0
  build() {
    Column() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .translate({ x: this.translateX })
        .animation({duration:1000})
      Button("点击")
        .margin({ top: 10 })
        .onClick(() => {
          this.translateX = 100 //x轴移动100
        })
    }
    .height('100%')
    .width('100%')
  }
}


可以看到实际效果是一样的。



当然了,除了平移属性能够实现这种效果,其实你使用margin也能实现平移的效果。


.margin({ left: this.translateX })
.animation({ duration: 1000 })


说明


需要说明的是,实现一个动画,无论是使用animation还是animateTo都是触发的动作,真正展示视觉效果,还得是可执行的属性,无论平移,缩放还是旋转。


平移动画


让一个组件产生一个平移动画,设置translate属性即可,当然,你设置offset或者margin也是可以实现的,只不过一个是组件偏移,一个是位置的坐标偏移,我理解是大差不差的,但是还是建议使用官方的translate。


其类型参数是TranslateOptions,接收三个参数,x,y,z,分别表示在对应轴移动的距离,值为正时表示向对应轴的正向移动,值为负时表示向对应轴的反向移动。




如果你仅仅是平移,只需要XY两个值即可,因为Z值有接近观察点放大和远离观察点缩小效果,一般未有缩放效果,Z值我们可以不传递。




例如,向X轴方向平移100,向Y轴方向平移100。


@Entry
@Component
struct Index {
  @State translateX: number = 0
  @State translateY: number = 0
  build() {
    RelativeContainer() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .translate({ x: this.translateX, y: this.translateY })
        .animation({ duration: 1000 })
      Button("点击")
        .onClick(() => {
          this.translateX = 100
          this.translateY = 100
        })
        .alignRules({
          center: { anchor: "__container__", align: VerticalAlign.Center },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}


效果:




如果你要加上Z值,比如也设置100,我们就会看到明显的缩放动画。



缩放动画


缩放动画,可以使用scale属性进行实现,类型参数为ScaleOptions,有五个参数,分别为X,Y,Z,centerX和centerY,X轴、Y轴、Z轴为缩放比例,默认值为1,centerX和centerY为设置缩放的中心点。


简单举例,原有基础之上放大2倍。


@Entry
@Component
struct Index {
  @State translateX: number = 1
  @State translateY: number = 1
  @State translateZ: number = 1
  build() {
    RelativeContainer() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .scale({ x: this.translateX, y: this.translateY, z: this.translateZ })
        .animation({ duration: 1000 })
        .margin({ top: 100 })
        .alignRules({
          top: { anchor: "__container__", align: VerticalAlign.Top },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
      Button("点击")
        .margin({ top: 10 })
        .onClick(() => {
          this.translateX = 2
          this.translateY = 2
          this.translateZ = 2
        })
        .alignRules({
          center: { anchor: "__container__", align: VerticalAlign.Center },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}


效果查看:



默认系数为1,放大就比1大,缩小就比1小,centerX和centerY就是中心点,默认是组件的中点,如下图,放大两倍后,也是以中点放大两倍。



如果你更改了centerX和centerY的值,再放大时就是以更改的值作为中心点进行放大,可以看到是有明显的区别的。



旋转动画


旋转动画,可以使用rotate属性进行实现,类型参数为RotateOptions,总共有8个参数,详细介绍如下:


名称

类型

必填

说明

x

number

旋转轴向量x坐标。

y

number

旋转轴向量y坐标。

z

number

旋转轴向量z坐标。

angle

number | string

旋转角度。取值为正时相对于旋转轴方向顺时针转动,取值为负时相对于旋转轴方向逆时针转动。取值可为string类型,如'90deg'。

centerX

number | string

变换中心点x轴坐标。表示组件变换中心点(即锚点)的x方向坐标。

单位:vp

centerY

number | string

变换中心点y轴坐标。表示组件变换中心点(即锚点)的y方向坐标。

单位:vp

centerZ10+

number

z轴锚点,即3D旋转中心点的z轴分量。

perspective10+

number

视距,即视点到z=0平面的距离。

旋转轴和旋转中心点都基于坐标系设定,组件发生位移时,坐标系不会随之移动。




正常的旋转,我们只改变角度即可,也就是按照中心点旋转,比如旋转180度。


@Entry
@Component
struct Index {
  @State angle: number = 0
  build() {
    RelativeContainer() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .rotate({ angle: this.angle})
        .animation({ duration: 1000 })
        .margin({ top: 100 })
        .alignRules({
          top: { anchor: "__container__", align: VerticalAlign.Top },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
      Button("点击")
        .margin({ top: 10 })
        .onClick(() => {
          this.angle = 180
        })
        .alignRules({
          center: { anchor: "__container__", align: VerticalAlign.Center },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}


效果查看:



当然了,你也可以通过改变中心点,或者坐标点,实现想要的旋转效果。


组合动画


单一动画,我们设置单个可执行属性即可,如果是多个动画,显而易见,就是设置多个属性,比如实现一个,X轴移动100,并且旋转180度,放大1.5倍。


@Entry
@Component
struct Index {
  @State angle: number = 0
  @State translateX: number = 0
  @State scaleX: number = 1
  @State scaleY: number = 1
  @State scaleZ: number = 1
  build() {
    RelativeContainer() {
      Text("1")
        .width(50)
        .height(50)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
        .rotate({ angle: this.angle })
        .translate({ x: this.translateX })
        .scale({ x: this.scaleX, y: this.scaleY, z: this.scaleZ })
        .animation({ duration: 1000 })
        .margin({ top: 100 })
        .alignRules({
          top: { anchor: "__container__", align: VerticalAlign.Top },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
      Button("点击")
        .margin({ top: 10 })
        .onClick(() => {
          this.translateX = 100
          this.angle = 180
          this.scaleX = 1.5
          this.scaleY = 1.5
          this.scaleY = 1.5
        })
        .alignRules({
          center: { anchor: "__container__", align: VerticalAlign.Center },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}


效果查看



两种属性动画介绍


无论是是使用animateTo还是animation,其实最终要改变的都是组件的可执行属性,最终的效果是一致的,animateTo是闭包内改变属性引起的界面变化,一般作用于出现消失转场,而animation则是组件通过属性接口绑定的属性变化引起的界面变化,一般使用场景为,animateTo适用对多个可动画属性配置相同动画参数的动画,需要嵌套使用动画的场景;animation适用于对多个可动画属性配置不同参数动画的场景。


相关总结


如果你要执行动画的组件,是始终存在的,那么这种情况下,是推荐使用的,如果是那种将要出现或者将要消失的组件,这里是不推荐的。


还有就是,要合理的使用属性动画,避免一些轮询机制中使用,否则会影响其它页面的组件展示效果。

相关文章
|
7月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
|
3月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
401 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
395 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
6月前
|
安全 JavaScript API
鸿蒙开发核心要素
鸿蒙开发核心要素
|
3月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
857 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
7月前
|
存储 IDE 定位技术
【HarmonyOS 5】鸿蒙组件&模板服务详解 - 助力高效开发的利器
在移动应用开发领域,效率与质量始终是开发者追求的核心目标。鸿蒙系统作为新兴的操作系统,为开发者提供了丰富且强大的开发资源,其中鸿蒙组件&模板服务更是成为开发者快速构建高质量应用的得力助手。
279 0
HarmonyOS NEXT仓颉开发语言实战案例:电影App
周末好!本文分享使用仓颉语言重构ArkTS实现的电影App案例,对比两者在UI布局、组件写法及语法差异。内容包括页面结构、列表分组、分类切换与电影展示等。通过代码演示仓颉在HarmonyOS开发中的应用。##仓颉##ArkTS##HarmonyOS开发
|
7月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:健身App
本期分享一个健身App首页的布局实现,顶部采用Stack容器实现重叠背景与偏移效果,列表部分使用List结合Scroll实现可滚动内容。代码结构清晰,适合学习HarmonyOS布局技巧。
HarmonyOS NEXT仓颉开发语言实战案例:小而美的旅行App
本文分享了一个旅行App首页的设计与实现,使用List容器搭配Row、Column布局完成个人信息、功能列表及推荐模块的排版,详细展示了HarmonyOS下的界面构建技巧。
|
3月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
223 0