【鸿蒙实战开发】HarmonyOS NEXT 画笔调色板

介绍

本示例实现了一个网格渐变的画笔调色板,能够根据给定的 HSL 类型颜色和色阶数,按亮度生成渐变色,用户可以通过调色板选择颜色并在画布上绘制路径。

效果图预览

0030086000753188655.20240827214745.93646216170351586980758569564625.gif

使用说明

  1. 页面底部展示当前画笔颜色和预设的常用颜色,点击预设的常用颜色可以修改画笔颜色。
  2. 点击画笔颜色,显示网格渐变的调色板,选择调色板上的颜色可以修改画笔颜色。
  3. 在图片上触摸并拖动手指,可以绘制路径,路径颜色为当前选中的画笔颜色。

实现思路

  1. 调色板(HslPalette)渐变方案和布局。

    • 根据给定的hslHues(HSL颜色列表)和levels(色阶数量)生成按亮度渐变的颜色,并根据给定的的渐变亮度起止点(gradientStartPointgradientEndPoint),使不同颜色的同一色阶亮度相同。源码参考PaletteMainPage.ets
      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 数组中。源码参考ColorTypeConverter.ets
    /**
     * 将 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 * hueFr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值