鸿蒙的动态渐变背景实现

前言

最近想搞个酷炫一点的页面,觉得渐变挺不错,决定背景采用渐变了。

但是单纯的静态的渐变还是感觉差点意思,思来想去觉得得搞个动态渐变。

下面是我的实现思路 关于基础的静态渐变,这里不愿意赘述,贴一张官方的链接在这吧,链接是 官方文档-渐变样式。简单而且详细。

说明:以下均以线性渐变举例,变量命名因为是演示所以比较随意。

最开始我的方案是用那个 属性动画,如果说你想实现的效果比较简单。比方说如下,那么是很合适的。

但如果你要实现的比较复杂,例如下面这样

虽然用属性动画仍旧可以大致还原,但是我觉得 关键帧动画这时候可能就更有优势了。

这里也不赘述了,点一下链接可以看到文档。

属性动画实现

先定义两个控制颜色的变量

css 复制代码
@State gradientOptions : LinearGradientOptions = {
    angle:45,
    colors:[
      ["#f09819", 0],
      ["#edde5d", 1],
    ]
  }
  @State flag: number = 1

然后我们在onDidBuild回调里启动动画,具体就是改一下我们定义的gradientOptions的值,就能触发动画了

css 复制代码
onDidBuild():{
     this.gradientOptions =  {
      angle:45,
      colors:[
        ["#ffee113e", 0],
        ["#ff1a3864", 1]
 
      ]
    }
}

下面是组件信息,我们可以通过变量flag来实现更多更丰富的渐变效果,这里不作演示

kotlin 复制代码
 Column()
          .width(200)
          .height(200)
          .linearGradient(this.gradientOptions)
          .animation({duration:2000,onFinish:()=>{
            if(this.flag){
              this.flag = 0
              this.gradientOptions =
            {
                angle:45,
                colors:[
                  ["#edde5d", 0],
                  ["#f09819", 1],
 
                ]
              }
            }else {
              this.flag = 1
              this.gradientOptions = {
                angle:45,
                colors:[
                  ["#ffee113e", 0],
                  ["#ff1a3864", 1],
                ]
              }
            }
 
          }})

这样基本就可以完成我们第一个渐变的效果了。

但是很重要的一个缺点就是,换方向的话是不会有动画的

我们前面主要是两种颜色变化,并且角度都是45度,如果我们把第二个颜色的角度改成90度,也就是

ini 复制代码
              this.flag = 1
              this.gradientOptions = {
                angle:90,
                colors:[
                  ["#ffee113e", 0],
                  ["#ff1a3864", 1],
                ]
              }
            

那么就会很不连贯了, 像下面这样,感觉就是属性动画处理不了这样的转变,也不清楚算不算bug。

总之就是,用属性动画的话,就几乎改变不了渐变的方向了,不能提供更为多元的视觉效果。

当然,硬要用属性动画,通过很复杂的调试应该也能做到看起来连贯吧。

关键帧动画实现

实际上这个似乎才是主流的动态渐变背景的实现方案。

大致就是一个框(组件)固定,但是背景图来回移动,从而达到渐变的效果。

例如我前面那个举例的很复杂的例子,实际上是怎样运行的呢?

这里是为了演示所以把周围的显露出来了,并且加了个border,之后加上clip属性并把border删了就可以达到之前的效果了。

具体的代码实现如下

我们定义位置变量pos

css 复制代码
@State pos : Position = {x: "0%",y:"0%"}

组件信息

sql 复制代码
   Column(){
        Column()
          .position(this.pos)
          .width("500%")
          .height("500%")
          .linearGradient({
            angle:60,
            colors:[
              ["#ffed5d8b", 0],
              ["#ffb7f019", 0.2],
              ["#ffae8215", 0.4],
              ["#ff354bb8", 0.6],
              ["#ffd3ed5d", 0.8],
              ["#ff590f86", 1],
            ]
          })
      }
      .width(200)
      .height(200)
      .clip(true)

然后最重要的是我们的关键帧动画函数ani

kotlin 复制代码
ani(){
    this.uiContext?.keyframeAnimateTo({iterations:-1},
      [
        {duration:1,event:()=>{
          this.pos.x = "0%"
          this.pos.y = "-400%"
 
        }
        },
        {duration:3000,event:()=>{
          this.pos.x = "0%"
          this.pos.y = "0%"
 
    }
    },
        {
      duration:3000,event:()=>{
          this.pos.x = "-400%"
          this.pos.y = "0%"
        },
      }, {
        duration:3000,event:()=>{
          this.pos.x = "-400%"
          this.pos.y = "-400%"
        },
      },
        {
          duration:3000,event:()=>{
          this.pos.x = "0%"
          this.pos.y = "-400%"
        },
        }, {
        duration:4242,event:()=>{
          this.pos.x = "-400%"
          this.pos.y = "0%"
        }
      }, {
        duration:3000,event:()=>{
          this.pos.x = "0%"
          this.pos.y = "0%"
        }
      }, {
        duration:4242,event:()=>{
          this.pos.x = "-400%"
          this.pos.y = "-400%"
        },
      }, {
        duration:3000,event:()=>{
          this.pos.x = "0%"
          this.pos.y = "-400%"
        },
      },
 
      ])
  }

这里解释一下这个函数啊,这个_iteration: -1_ 指的是无限次播放重复播放这个动画。

然后这里的一次循环的具体的路径参考下图。

关于duration和pos的具体设置,不展开讲了,否则偏离主题了。这部分也完全是个性化的,这里仅供参考。

最后在onDidBuild回调里执行我们的关键帧动画函数就好了。

scss 复制代码
onDidBuild():{
     this.ani()
}

后话

最初的目的是想要完全随机的背景动态变化,但是实际上用关键帧之后,看不出来是不是固定的背景的吧,而且一般估计没人盯着你的背景看是不是重复播放。效果上估计也都是差不多的,完全随机还不可控,说不定会随机出一个很难看的渐变色。虽然可以限定颜色范围。

实现的话也不是没有思路,大概就是在关键帧动画里最后的一步里加个animateTo函数,然后把组件的linearGradient属性的值改成变量,在animateTo函数里修改,应该就行了。

相关推荐
前端世界3 小时前
鸿蒙UI开发全解:JS与Java双引擎实战指南
javascript·ui·harmonyos
阿巴~阿巴~6 小时前
操作系统核心技术剖析:从Android驱动模型到鸿蒙微内核的国产化实践
android·华为·harmonyos
Keya10 小时前
在HarmonyOS(鸿蒙)中H5页面中的视频不会自动播放
app·harmonyos·arkts
HMS Core13 小时前
用AI重塑游戏体验:《诛仙2》携手HarmonyOS SDK实现性能与功耗双赢
人工智能·游戏·harmonyos
儿歌八万首13 小时前
HarmonyOS中各种动画的使用介绍
华为·harmonyos·arkts·arkui
dilvx13 小时前
配置鸿蒙 fastboot
华为·harmonyos
儿歌八万首13 小时前
HarmonyOS 中状态管理 V2和 V1 的区别
harmonyos·component·arkui
鸿蒙小林13 小时前
HarmonyOS应用开发者高级试题2025年7月部分单选题
harmonyos·开发者认证
zkmall13 小时前
鸿蒙商城开发:ZKmall开源商城系统特性适配与性能优化
性能优化·开源·harmonyos