本文正在参加星光计划3.0–夏日挑战赛
前言
在项目开发中遇到给设备充电时,电池图标显示一个充电动画效果,下面基于 HarmonyOS 的JSAPI实现一个电池充电的动画效果。
效果展示
实现原理
电池充电的动画就是一个宽度从0%加载到100%的过程,所以在充电状态只需要动态改变显示的宽度就可以实现一个充电的效果,而电池的轮廓和充电状态采用加载本地图片的方式实现。
实现步骤
1. 实现电池图标
首先加载空电量的电池轮廓的图片,在电池轮廓的上面覆盖一个显示电池电量的进度条,在电池电量进度条的上面覆盖一个闪电图标,显示充电状态。
battery.hml:
<div class="container">
    <image show="true" src="{{ batteryIcon }}"></image>
    <div class="progress" style="width : {{ getBatteryNum() }} px;"></div>
    <image show="{{ chargeState }}" class="charging" src="/common/img/ic_charging.png"></image>
</div>css样式:
.container {
    height: 48px;
    width: 48px;
    justify-content: center;
    align-items: center;
}
.progress {
    height: 16px;
    background-color: black;
    position: absolute;
    margin-left: 12%;
    top: 50%;
    transform: translate(0, -50%);
}
.charging {
    height: 48px;
    width: 48px;
    position: absolute;
    left:50%;
    top: 50%;
    transform: translate(-50%, -50%);
}2. 获取手机电池信息
通过系统接口提供的接口获取手机电池信息,导入batteryInfo模块,接口从API version 6开始支持。
import batteryInfo from '@ohos.batteryInfo';batteryInfo详细属性:
| 名称 | 类型 | 可读 | 可写 | 描述 | 
|---|---|---|---|---|
| batterySOC | number | 是 | 否 | 表示当前设备剩余电池电量百分比。 | 
| chargingStatus | [BatteryChargeState] | 是 | 否 | 表示当前设备电池的充电状态。 | 
| healthStatus | [BatteryHealthState] | 是 | 否 | 表示当前设备电池的健康状态。 | 
| pluggedType | [BatteryPluggedType] | 是 | 否 | 表示当前设备连接的充电器类型。 | 
| voltage | number | 是 | 否 | 表示当前设备电池的电压,单位微伏。 | 
| technology | string | 是 | 否 | 表示当前设备电池的技术型号。 | 
| batteryTemperature | number | 是 | 否 | 表示当前设备电池的温度,单位0.1摄氏度。 | 
| isBatteryPresent7+ | boolean | 是 | 否 | 表示当前设备是否支持电池或者电池是否在位。 | 
index.js 中获取电池电量和充电状态
//获取设备电池电量百分比
this.batterySoc = batteryInfo.batterySOC
//设备电池是否在充电状态
this.chargingStatus = batteryInfo.chargingStatus == batteryInfo.BatteryChargeState.ENABLE3. 实现动态改变进度条宽度
进度条必须显示在电池图标轮廓里,所以进度条的宽度不能超过电池图标,根据获取到的电量百分比,动态改变宽度但不能超过满电时的最大宽度,满电时的最大宽度可根据实现效果调整。
如下代码:
getBatteryNum() {
        let width = (this.percent / 100) * this.maxWidth
        if (this.percent >= 100) {
            return this.maxWidth
        }
        console.log(" getBatteryNum " + Math.round(width))
        return Math.round(width);
},4. 实现充电动画效果
使用系统提供的动画接口,导入animator模块,接口从API version 6开始支持。
import animator from '@ohos.animator';animator有以下方法:
| 名称 | 参数类型 | 说明 | 
|---|---|---|
| update | update(options: AnimatorOptions): void | 更新当前动画器 | 
| play | play(): void | 播放动画 | 
| finish | finish(): void | 结束动画 | 
| pause | pause(): void | 暂停动画 | 
| cancel | cancel(): void | 删除动画 | 
| reverse | reverse(): void | 以相反的顺序播放动画 | 
| onframe | onframe: (progress: number) => void | 回调时触发 | 
| onfinish | onfinish: () => void | 动画完成 | 
| oncancel | oncancel: () => void | 动画被取消 | 
| onrepeat | onrepeat: () => void | 动画重复播放 | 
AnimatorOptions属性:
| 名称 | 参数类型 | 必填 | 说明 | 
|---|---|---|---|
| duration | number | 是 | 动画播放的时长,单位毫秒,默认为0。 | 
| easing | string | 是 | 动画插值曲线,默认为ease'。 | 
| delay | number | 是 | 动画延时播放时长,单位毫秒,默认为0,即不延时。 | 
| fill | "none" | "forwards" | "backwards" | "both" | 是 | 动画执行后是否恢复到初始状态,默认值为"none"。动画执行后,动画结束时的状态(在最后一个关键帧中定义)将保留。 | 
| direction | "normal" | "reverse" | "alternate" | "alternate-reverse" | 是 | 动画播放模式,默认值"normal"。 | 
| iterations | number | 是 | 动画播放次数,默认值1。设置为0时不播放,设置为-1时无限次播放。 | 
| begin | number | 是 | 动画插值起点,不设置时默认为0。 | 
| end | number | 是 | 动画插值终点,不设置时默认为1。 | 
在触发充电状态时,重复播放Animator动画,在onframe()回调中动态改变电池电量百分比,从而改变进度条宽度,详细代码如下:
battery.js 完整代码
import animator from '@ohos.animator';
import batteryInfo from '@ohos.batteryInfo';
export default {
    props: ['quantity', 'charge'],
    data() {
        return {
            percent: this.quantity,
            chargeState: this.charge,
            batteryIcon: "/common/img/ic_battery.png",
            animator: null,
            maxWidth: 30
        };
    },
    onInit() {
        console.log("battery onInit")
        this.setBatteryIcon()
        this.$watch('quantity', 'onQuantityChange')
        this.$watch('charge', 'onChargeChange')
        var options = {
            duration: 2000,
            easing: 'friction',
            fill: 'forwards',
            direction: 'reverse',
            iterations: -1,
            begin: 0,
            end: this.maxWidth
        };
        this.animator = animator.createAnimator(options);
        var _this = this;
        this.animator.onframe = function (value) {
            _this.percent = (parseInt(value) / _this.maxWidth) * 100
        };
    },
    onPageShow() {
        console.log("battery onPageShow percent = " + this.percent + " chargeState = " + this.chargeState)
    },
    // 监听是否变化电量
    onQuantityChange(newV, oldV) {
        console.log('======proQuantity============ newV=' + newV + " oldV = " + oldV)
        this.percent = newV
    },
    // 监听是否充电
    onChargeChange(newV, oldV) {
        console.log('======proIsCharge============newV =' + newV + " oldV = " + oldV)
        this.chargeState = newV
        if (this.chargeState) {
            this.animator.play();
        } else {
            this.percent = batteryInfo.batterySOC
            this.animator.cancel();
        }
    },
    getBatteryNum() {
        let width = (this.percent / 100) * this.maxWidth
        if (this.percent >= 100) {
            return this.maxWidth
        }
        console.log(" getBatteryNum " + Math.round(width))
        return Math.round(width);
    },
    onDestroy(){
        this.animator.cancel();
    }
}总结
以上只是简单实现了一个平移动画的效果,结合系统的Animator可以实现各种各样炫酷的动画效果,可以提高应用的视觉和用户的体验,掌握HarmonyOS动画的使用,可以让我们更好的了解和参与HarmonyOS的开发。
更多原创内容请关注:中软国际 HarmonyOS 技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
想了解更多关于开源的内容,请访问:
51CTO 开源基础软件社区
https://ost.51cto.com/#bkwz










