往期知识点整理
介绍
本示例介绍使用绘制组件中的Circle组件以及Path组件实现实时进度效果。该场景多用于手机电池电量、汽车油量、水位变化等动态变化中。
效果预览图
使用说明
- 加载完成后初始显示进度为0%,颜色为红色,且有充电、耗电两个按钮。
- 点击充电按钮,进度会持续增长,直到100%时绿色填充满整个圆形,当到达20%以上和80%以上时,颜色动态变化。
- 点击耗电按钮,进度会持续下降,直到0%恢复1中的初始效果,当到达20%以下和80%以下时,颜色动态变化。
实现思路
- 使用Circle组件绘制外层的圆环。
// 外框圆环
Circle({
width: Constants.BIG_DIAMETER,
height: Constants.BIG_DIAMETER
})
.fill(Constants.COLOR_TRANSPARENT)
.stroke(this.colorBackgroundFill)
.strokeWidth($r("app.integer.paint_component_outer_circle_stroke_width"))
- 绘制中间的进度的填充。中间的填充有两个状态:1、在进度100%时是填充颜色的圆形;2、在进度不足100%时,使用Path组件绘制闭合曲线实现。
// 进度展示
Circle({
width: Constants.DIAMETER,
height: Constants.DIAMETER
})
.fill(this.bgColor)
// TODO:知识点:使用Path组件绘制封闭曲线,实现水位线效果
Path()
.width(Constants.DIAMETER)
.height(Constants.DIAMETER)
.commands(this.pathCommands)
.fill(this.colorBackgroundFill)
.antiAlias(true)
.stroke(this.colorBackgroundFill)
.strokeWidth($r("app.integer.paint_component_path_stroke_width"))
- 计算封闭曲线。水位线的端点的纵坐标y与进度k的关系为:y=(1-k)*2r,而圆心坐标为(r,r),以此确定水位线的坐标,然后拼接成绘制封闭曲线的commands。
/**
* 根据进度拿到水位线的端点的纵坐标
*
* @param progressPercent 进度百分比
* @returns 水位线的端点的纵坐标
*/
getOrdinate(progressPercent: number): number {
return (Constants.UNIT_ONE - progressPercent) * (Constants.RADIUS_IN_PX + Constants.RADIUS_IN_PX);
}
/**
* 根据圆心,以及纵坐标拿到水位线两个端点的距离的平方
*
* @param ordinate 纵坐标
* @returns 端点间距离的平方
*/
getDistanceSquare(ordinate: number): number {
return Constants.RADIUS_IN_PX * Constants.RADIUS_IN_PX - (ordinate - Constants.RADIUS_IN_PX) * (ordinate - Constants.RADIUS_IN_PX);
}
/**
* 计算闭合曲线
*
* @param progressNum 进度
* @returns 绘制闭合曲线的commands
*/
getPathCommands(progressNum: number): string {
// 拿到水位线的端点的纵坐标
const ordinate: number = this.getOrdinate(progressNum / Constants.PERCENT_RATE);
// 拿到端点之间的距离的平方
const distanceSquare: number = this.getDistanceSquare(ordinate);
if (distanceSquare >= Constants.ZERO) {
// 开平方得到端点间的距离
const distance: number = Math.sqrt(distanceSquare);
// 计算得出第一个端点的横坐标
const firstAbscissa: number = Constants.RADIUS_IN_PX - distance;
// 计算得到第二个端点的横坐标
const secondAbscissa: number = Constants.RADIUS_IN_PX + distance;
return this.formatPathCommands(firstAbscissa, secondAbscissa, ordinate, Constants.RADIUS_IN_PX);
}
return "";
}
/**
* 拼接绘制闭合曲线的commands
*
* @param firstAbscissa
* @param secondAbscissa
* @param ordinate
* @param radius
* @returns
*/
formatPathCommands(firstAbscissa: number, secondAbscissa: number, ordinate: number, radius: number): string {
return `M${firstAbscissa} ${ordinate} A${radius} ${radius} 0 ${ordinate > Constants.RADIUS_IN_PX ? 0 : 1} 0 ${secondAbscissa} ${ordinate}`
+ `Q${(firstAbscissa + 3 * secondAbscissa) / 4} ${ordinate + 12.5 * (secondAbscissa - firstAbscissa) / radius}, ${(firstAbscissa + secondAbscissa) / 2} ${ordinate} T${firstAbscissa} ${ordinate}`;
}
- 绘制最上层的百分比显示。
// 进度百分比
Row() {
Text($r("app.string.paint_component_progress_percentage_symbol_name"))
.fontColor(Constants.COLOR_NORMAL)
.fontSize($r("app.integer.paint_component_progress_percentage_symbol_font_size"))
Text(this.progressNum.toFixed(Constants.ZERO) + Constants.PERCENTAGE_STR)
.fontSize($r("app.integer.paint_component_progress_percentage_font_size"))
高性能知识点
不涉及
工程结构&模块类型
paintcomponent // har类型
|---constants
| |---Constants.ets // 常量类
|---view
| |---PaintComponent.ets // 视图层-绘制组件页面
最后
总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。
《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
鸿蒙开发面试真题(含参考答案):
《OpenHarmony源码解析》:
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……