# ColorPickerDemo **Repository Path**: dot_happydz_admin/ColorPickerDemo ## Basic Information - **Project Name**: ColorPickerDemo - **Description**: OpenHarmony TS 颜色选择器,常见的颜色选择器,使用颜色条滑动选择主色调,更改颜色面板的颜色,并触摸选择颜色。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2024-02-25 - **Last Updated**: 2025-01-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ArkUI(TS)声明式开发:颜色选择器 ### 项目介绍 本项目基于[OpenHarmony](https://docs.openharmony.cn/pages/v3.1/zh-cn/OpenHarmony-Overview_zh.md/)的ArkUI框架:TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:[基于TS扩展的声明式开发范式](https://docs.openharmony.cn/pages/v3.1/zh-cn/application-dev/ui/ui-ts-overview.md/),因为OpenHarmony的API相对于HarmonyOS的API,功能上比较完善和成熟的,有些新的技术也早早接触到,所以本项目直接使用OpenHarmony SDK开发。 **工具版本:** DevEco Studio 3.0 Beta4 **SDK版本:** 3.1.6.6(API Version 8 Release) **项目功能:** 常见的颜色选择器,使用颜色条滑动选择主色调,更改颜色面板的颜色,并触摸选择颜色。 ### 效果演示 ![](image/demo.gif) ### 主要API [画布组件canvas](https://gitee.com/link?target=https%3A%2F%2Fdocs.openharmony.cn%2Fpages%2Fv3.1%2Fzh-cn%2Fapplication-dev%2Freference%2Farkui-ts%2Fts-components-canvas-canvas.md%2F):画布组件,用于自定义绘制图形。 | 方法/属性 | 解释 | | :--------------------- | :--------------------- | | createLinearGradient() | 创建一个线性渐变色 | | addColorStop() | 设置渐变颜色和比例 | | getImageData() | 获取坐标点像素的颜色值 | | fillRect() | 填充一个矩形 | | clearRect() | 清空画布 | | fillStyle | 属性:指定绘制的填充色 | ### 实现思路 #### 1、绘制颜色条 使用createLinearGradient()方法创建一个从上至下的线性渐变色。**(代码片段)** ```javascript /** * 颜色条 */ @Builder ColorBar() { Canvas(this.crcBar) .onAreaChange((oldValue: Area, newValue: Area) => { // 获取组件的宽高 this.barWidth = parseInt(newValue.width.toString()) this.barHeight = parseInt(newValue.height.toString()) this.barIndicatorSize = this.barWidth / 3 // 创建渐变色的范围 const grad = this.crcBar.createLinearGradient(0, 0, 0, this.barHeight) // 设置渐变颜色和比例。 grad.addColorStop(0, 'rgb(255, 0, 0)') grad.addColorStop(1 * 1 / 6, 'rgb(255, 255, 0)') grad.addColorStop(2 * 1 / 6, 'rgb(0, 255, 0)') grad.addColorStop(3 * 1 / 6, 'rgb(0, 255, 255)') grad.addColorStop(4 * 1 / 6, 'rgb(0, 0, 255)') grad.addColorStop(5 * 1 / 6, 'rgb(255, 0, 255)') grad.addColorStop(1, 'rgb(255, 0, 0)') // 设置渐变色 this.crcBar.fillStyle = grad // 绘制矩形 this.crcBar.fillRect(0, 0, this.barWidth, this.barHeight) }).width('100%') .borderWidth(0.5) } ``` #### 2、绘制颜色条指示器 使用 [Path绘制组件](https://docs.openharmony.cn/pages/v3.1/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-path.md/) :绘制两个相对的三角形,作为颜色条指示器。**(代码片段)** ![](image/demo2.png) ```javascript /** * 颜色条指示器 */ @Builder ColorBarIndicator() { Row() { if (this.barIndicatorSize != 0) { Path() .width(this.barIndicatorSize) .height(this.barIndicatorSize) .commands(`M0 0 L${vp2px(this.barIndicatorSize)} ${vp2px(this.barIndicatorSize / 2)} L0 ${vp2px(this.barIndicatorSize)} Z`) .fill('#00000000') .stroke(Color.Black) .strokeWidth(0.8) Blank() Path() .width(this.barIndicatorSize) .height(this.barIndicatorSize) .commands(`M0 ${vp2px(this.barIndicatorSize / 2)} L${vp2px(this.barIndicatorSize)} 0 L${vp2px(this.barIndicatorSize)} ${vp2px(this.barIndicatorSize)} Z`) .fill('#00000000') .stroke(Color.Black) .strokeWidth(0.8) } }.width('100%') .padding(1) .offset({ y: this.barIndicatorOffsetY }) .markAnchor({ y: '50%' }) } ``` #### 3、颜色条滑动选择颜色 设置颜色条的触摸事件,根据坐标点,调用getImageData()方法获取触摸坐标点像素的颜色值。并更新颜色条指示器的Y轴位置。**(代码片段)** ```javascript /** * 颜色条触摸事件 */ onTouchEventBar(event: TouchEvent) { // x坐标 let x = event.touches[0].x // y坐标 let y = event.touches[0].y // 触摸区域限制 if (x < 0)x = 0 if (x > this.barWidth - 1.2) x = this.barWidth - 1.2 if (y < 1)y = 1 if (y > this.barHeight - 1.2) y = this.barHeight - 1.2 console.log(`颜色条-当前坐标:x = ${x}, y = ${y}`) // 触摸y坐标赋值给指示器偏移量 this.barIndicatorOffsetY = y // 获取颜色条坐标点一个像素的颜色值 let imageData = this.crcBar.getImageData(x, y, px2vp(1), px2vp(1)) console.log(`颜色条-当前颜色:` + JSON.stringify(imageData)) // 绘制颜色面板 this.drawColorBoard(`rgb(${imageData.data[0]},${imageData.data[1]},${imageData.data[2]})`) // 获取颜色面板选中的颜色 this.getBoardSelectColor() } ``` #### 4、绘制颜色面板 使用fillRect()绘制背景矩形,在其之上绘制:从左至右,白色-->透明渐变色,最后绘制:从下至上,黑色-->透明渐变色。 ```javascript /** * 绘制颜色面板 * @param bgColor 背景颜色 默认颜色:红色 */ drawColorBoard(bgColor = 'rgb(255, 0, 0)') { // 清空画布 this.crcBoard.clearRect(0, 0, this.boardWidth, this.boardHeight) // 绘制背景色 this.crcBoard.fillStyle = bgColor this.crcBoard.fillRect(0, 0, this.boardWidth, this.boardHeight) // 绘制渐变色:白色->透明色 const gradWhite = this.crcBoard.createLinearGradient(0, 0, this.boardWidth, 0) gradWhite.addColorStop(0, 'rgb(255,255,255)') gradWhite.addColorStop(1, 'rgba(255,255,255,0)') this.crcBoard.fillStyle = gradWhite this.crcBoard.fillRect(0, 0, this.boardWidth, this.boardHeight) // 绘制渐变色:黑色->透明色 const gradBlack = this.crcBoard.createLinearGradient(0, this.boardHeight, 0, 0) gradBlack.addColorStop(0, 'rgb(0,0,0)') gradBlack.addColorStop(1, 'rgba(0,0,0,0)') this.crcBoard.fillStyle = gradBlack this.crcBoard.fillRect(0, 0, this.boardWidth, this.boardHeight) } ``` #### 5、绘制颜色面板指示器 这个很简单,就是组件设置边框和圆角,圆角半径为宽高一半为圆形,大圆套小圆 ```javascript /** * 颜色面板指示器 */ @Builder ColorBoardIndicator() { if (this.boardIndicatorSize != 0) { Stack() { Stack() { } .width(this.boardIndicatorSize - 1) .height(this.boardIndicatorSize - 1) .border({ color: Color.White, width: 1, radius: this.boardIndicatorSize / 2 }) Stack() { } .width(this.boardIndicatorSize) .height(this.boardIndicatorSize) .border({ color: Color.Black, width: 1, radius: this.boardIndicatorSize / 2 }) }.offset({ x: this.boardIndicatorOffsetX, y: this.boardIndicatorOffsetY }) .markAnchor({ x: '50%', y: '50%' }) } } ``` #### 6、颜色面板触摸选择颜色 设置颜色条的触摸事件,根据坐标点,调用getImageData()方法获取触摸坐标点像素的颜色值。并更新颜色面板指示器的的XY位置。**(代码片段)** ```javascript /** * 颜色面板触摸事件 */ onTouchEventBoard(event: TouchEvent) { // x坐标 let x = event.touches[0].x // y坐标 let y = event.touches[0].y // 触摸区域限制 if (x < 0)x = 0 if (x > this.boardWidth - 1) x = this.boardWidth - 1 if (y < 0)y = 0 if (y > this.boardHeight - 1) y = this.boardHeight - 1 // 触摸xy坐标赋值给指示器偏移量 this.boardIndicatorOffsetX = x this.boardIndicatorOffsetY = y // 获取颜色面板选中的颜色 this.getBoardSelectColor() } /** * 获取颜色面板选中的颜色 */ getBoardSelectColor() { console.log(`颜色面板-当前坐标:x = ${this.boardIndicatorOffsetX}, y = ${this.boardIndicatorOffsetY}`) // 获取坐标点一个像素的颜色值 let imageData = this.crcBoard.getImageData(this.boardIndicatorOffsetX, this.boardIndicatorOffsetY, px2vp(1), px2vp(1)) console.log(`颜色面板-当前颜色:` + JSON.stringify(imageData)) this.colorChange(`rgb(${imageData.data[0]},${imageData.data[1]},${imageData.data[2]})`) } ``` #### 7、外部调用 界面加载成功后,ColorPickerView组件提供一个方法回调。直接在回调中获取颜色变化。来更新数据。 ```javascript import { ColorPickerView } from '../component/ColorPicker' @Entry @Component struct Index { @State color: string = 'rgb(255, 0, 0)' build() { Column() { Text('Hello World') .fontSize(40) .fontWeight(FontWeight.Bold) .fontColor(this.color) Stack() { ColorPickerView({ colorChange: (color) => { this.color = color } }) }.width(300) .height(300) .margin({ top: 30 }) }.width('100%') .height('100%') .justifyContent(FlexAlign.Center) } } ``` ### 结尾 本项目没有什么特别难的点,主要还是熟悉API,多看官方文档,多看一些优秀的项目,只有把原理掌握到自己手上才是王道。 每天进步一点点、需要付出努力亿点点。 项目地址:[https://gitee.com/liangdidi/ColorPickerDemo.git](https://gitee.com/liangdidi/ColorPickerDemo.git)