往期知识点整理
- 【HarmonyOS 鸿蒙实战开发】NavDestination弹窗
- 【HarmonyOS 鸿蒙实战开发】全局自定义组件复用实现案例
- 【HarmonyOS 鸿蒙实战开发】在TaskPool线程中操作关系型数据库实现案例
- 【HarmonyOS 鸿蒙实战开发】 发短信案例
- 【HarmonyOS 鸿蒙实战开发】 骨架屏实现案例
- 【HarmonyOS 鸿蒙实战开发】 画笔调色板
- 持续更新中……
介绍
本示例实现了一个网格渐变的画笔调色板,能够根据给定的 HSL 类型颜色和色阶数,按亮度生成渐变色,用户可以通过调色板选择颜色并在画布上绘制路径。
效果图预览

使用说明
- 页面底部展示当前画笔颜色和预设的常用颜色,点击预设的常用颜色可以修改画笔颜色。
- 点击画笔颜色,显示网格渐变的调色板,选择调色板上的颜色可以修改画笔颜色。
- 在图片上触摸并拖动手指,可以绘制路径,路径颜色为当前选中的画笔颜色。
实现思路
-
调色板(HslPalette)渐变方案和布局。
- 根据给定的
hslHues(HSL颜色列表)和levels(色阶数量)生成按亮度渐变的颜色,并根据给定的的渐变亮度起止点(gradientStartPoint和gradientEndPoint),使不同颜色的同一色阶亮度相同。
- 根据给定的
private hslHues: HslType[] = []; // HSL 类型颜色的源数组
private levels: number = 0; // 渐变色阶数
private gradientStartPoint: number = 0; // 渐变开始点的亮度值
private gradientEndPoint: number = 0; // 渐变结束点的亮度值
// TODO:知识点:根据 HSL 色相数组和色阶数生成按亮度渐变的 HEX 格式颜色
computeHSLGradient(hues: HslType[], levels: number): string[] {
if (levels <= 0) {
return [];
}
const colors: string[] = [];
for (let i = 0; i < levels; i++) {
hues.forEach(hsl => {
// 根据给定的渐变亮度起止点和所处色阶计算渐变亮度
const fadedL =
this.gradientStartPoint + Math.round(i * (this.gradientEndPoint - this.gradientStartPoint) / levels); // 逐渐变淡
// 将 HSL 转换为 HEX 格式
const hex = hslToHex(hsl.hue, hsl.saturation, fadedL);
// 添加到颜色数组
colors.push(hex);
});
}
return colors;
}
- 由于ArkUI组件不能直接使用HSL类型的颜色,所以获取到渐变亮度后需要通过
hslToHex函数将 HSL 颜色转换为 HEX 颜色再存储在colors数组中。
/**
* 将 HSL 颜色模型转换为 HEX 颜色模型
*
* @param {number} hue - 色相 (Hue),范围为 0 到 360
* @param {number} saturation - 饱和度 (Saturation),范围为 0 到 100
* @param {number} lightness - 亮度 (Lightness),范围为 0 到 100
* @returns {string} - 返回 HEX 颜色值,格式为 '#RRGGBB'
*/
export function hslToHex(hue: number, saturation: number, lightness: number): string {
// 将 HSL 转换为 RGB
const rgb: RgbType = hslToRgb(hue, saturation, lightness);
// 返回 HEX 颜色值
return rgbToHex(rgb.red, rgb.green, rgb.blue);
}
/**
* 将 HSL 颜色值转换为 RGB 颜色格式。
*
* @param {number} hue - 色相,范围为 0-360。
* @param {number} saturation - 饱和度,范围为 0-100,表示颜色的强度。
* @param {number} lightness - 亮度,范围为 0-100,表示颜色的明暗程度。
* @returns {rgbType} - 返回一个包含 RGB 值的对象,格式为 { red, green, blue },每个值的范围为 0-255。
*/
function hslToRgb(hue: number, saturation: number, lightness: number): RgbType {
let red: number, green: number, blue: number;
// 将饱和度和亮度从百分比转换为小数
saturation /= 100;
lightness /= 100;
if (saturation === 0) {
// 无饱和度,返回灰色
red = Math.round(lightness * 255); // 灰色的 Red 值
green = Math.round(lightness * 255); // 灰色的 Green 值
blue = Math.round(lightness * 255); // 灰色的 Blue 值
} else {
// 辅助函数:根据 HSL 值计算 RGB 值,处理不同的色相区间
const convertHueToRgb = (baseValue: number, brightnessMultiplier: number, hueFraction: number): number => {
// 确保 hueFraction 在 0 到 1 之间
if (hueFraction < 0) {
hueFraction += 1;
}
if (hueFraction > 1) {
hueFraction -= 1;
}
// 第一个区间
if (hueFraction < 1 / 6) {
return baseValue + (brightnessMultiplier - baseValue) * 6 * hueFraction;
}
// 第二个区间
if (hueFraction < 1 / 2) {
return brightnessMultiplier;
}
// 第三个区间
if (hueFraction < 2 / 3) {
return baseValue +


1100

被折叠的 条评论
为什么被折叠?



