发布于2026-07-15 阅读(0)
扫一扫,手机访问
上次我们实现了触摸手绘功能,核心产出了 PenManager 模块和 PaintComponent 页面。PenManager 通过 touchEvent 回调收集触摸点,构建 Path 对象,再利用 CanvasRenderingContext2D.drawPath() 将其绘制到画布上。跟着步骤走,手指已经可以在屏幕上自由涂鸦了。
但手绘功能还有个关键短板:绘制出的线条颜色固定为黑色、粗细固定为3px、透明度固定为100%。这样的笔触过于单调,实际绘画中根本不够用。本篇将聚焦于画笔属性调节,通过颜色选择器、粗细滑块和透明度滑块三个UI组件,让用户能够实时调整画笔效果。我们会把这些属性绑定到 Pen 对象上,确保每次绘制都使用最新的参数。

实现画笔属性调节,其实就三步:首先,创建一个画笔属性配置管理器 PenSettings,用于存储和更新颜色、粗细、透明度;其次,设计颜色选择器 ColorPicker 组件,让用户可以从预设色板中选色;最后,实现粗细和透明度的滑块组件 Slider。所有修改都会立即反应在下一笔绘制中。
在画图APP中,我们需要导入 @ohos.graphics.drawing 模块中的 Pen 类,以及状态管理接口用于跨组件通信。
// utils/PenSettings.ets
// 画笔属性管理器,采用单例模式,全局共享同一份配置
import { Pen } from '@ohos.graphics.drawing';
class PenSettings {
private static instance: PenSettings = new PenSettings();
// 当前选中的颜色,十六进制格式,默认黑色
public currentColor: string = '#FF000000';
// 当前画笔粗细,单位px,默认3
public currentWidth: number = 3;
// 当前透明度,范围0-255,默认255(完全不透明)
public currentAlpha: number = 255;
private constructor() { }
static getInstance(): PenSettings {
return PenSettings.instance;
}
// 应用当前设置到传入的Pen对象
applyToPen(pen: Pen): void {
// 解析颜色字符串为整数,例如'#FF0000' -> 0xFF0000
const colorInt = parseInt(this.currentColor.substring(1), 16);
// 透明度与颜色合并,完成ARGB组合
const argbColor = (this.currentAlpha << 24) | (colorInt & 0x00FFFFFF);
pen.setColor(argbColor);
pen.setStrokeWidth(this.currentWidth);
pen.setAlpha(this.currentAlpha);
}
// 更新颜色,并触发画布重绘(通过回调)
setColor(color: string): void {
this.currentColor = color;
this.onSettingsChanged?.();
}
setWidth(width: number): void {
this.currentWidth = width;
this.onSettingsChanged?.();
}
setAlpha(alpha: number): void {
this.currentAlpha = alpha;
this.onSettingsChanged?.();
}
// 设置变更回调,用于通知画布重新绘制
onSettingsChanged: (() => void) | null = null;
}
export default PenSettings;
关键点说明:
applyToPen 方法接收一个 Pen 实例,将当前颜色、粗细、透明度一次性应用到该笔上。颜色处理时需要注意透明度要与颜色值合并为ARGB格式。setColor 等方法通过回调机制通知外部(如画布组件)重新绘制,这样才能在调整滑块后立即看到预览效果。@ohos.graphics.drawing.Pen,其中 setColor / setStrokeWidth / setAlpha 是官方提供的标准方法。ColorPicker 组件提供一个预设颜色网格,用户点击某个色块后,更新 PenSettings 中的颜色值。
// components/ColorPicker.ets
// 颜色选择器组件,展示预设色板供用户点击选择
import PenSettings from '../utils/PenSettings';
@Component
export struct ColorPicker {
@State private selectedColor: string = '#FF000000';
// 预设颜色数组,涵盖常见绘画色彩
private colors: string[] = [
'#FF000000', '#FFFFFFFF', '#FFFF0000', '#FF00FF00',
'#FF0000FF', '#FFFFFF00', '#FFFF00FF', '#FF00FFFF',
'#FF808080', '#FFC0C0C0', '#FF800000', '#FF008000',
'#FF000080', '#FF808000', '#FF800080', '#FF008080',
'#FFE0B0FF', '#FFFFC0CB', '#FFA52A2A', '#FF000000'
];
build() {
Column() {
// 标题
Text('颜色选择')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
.textAlign(TextAlign.Start)
.margin({ bottom: 6 });
// 颜色网格,每行5个
Grid() {
ForEach(this.colors, (color: string) => {
GridItem() {
Stack() {
// 色块方块
Rect()
.width(36)
.height(36)
.borderRadius(6)
.fill(color)
.border({
width: this.selectedColor === color ? 3 : 1,
color: this.selectedColor === color ? '#FF007AFF' : '#FFCCCCCC'
})
.onClick(() => {
this.selectedColor = color;
PenSettings.getInstance().setColor(color);
});
// 如果是当前选中颜色,显示选中标记
if (this.selectedColor === color) {
Text('✓')
.fontSize(18)
.fontColor('#FF007AFF')
.fontWeight(FontWeight.Bold);
}
}
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
.width(40)
.height(40)
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.width('100%')
.maxHeight(200)
.columnsGap(8)
.rowsGap(8)
}
.padding(12)
.backgroundColor('#FFF8F8F8')
.borderRadius(12)
}
}
关键点说明:
'#AARRGGBB' 格式,其中 AA 部分在预设颜色中固定为 FF(不透明),实际透明度由 PenSettings 中的 currentAlpha 控制。PenSettings.getInstance().setColor(color),该操作会触发回调,通知画布应用新颜色。使用原生 Slider 组件,分别控制画笔粗细(1-20px)和透明度(0-255)。
// components/BrushSlider.ets
// 画笔粗细和透明度滑块组件,支持滑动调节
import PenSettings from '../utils/PenSettings';
@Component
export struct BrushSlider {
// 当前画笔粗细
@State private brushWidth: number = 3;
// 当前透明度
@State private brushAlpha: number = 255;
build() {
Column({ space: 16 }) {
// 粗细调节
Column() {
Row() {
Text('粗细')
.fontSize(14)
.fontWeight(FontWeight.Medium);
Text(`${this.brushWidth}px`)
.fontSize(12)
.fontColor('#FF666666')
.margin({ left: 8 });
}
.width('100%')
.justifyContent(FlexAlign.Start);
Slider({
value: this.brushWidth,
min: 1,
max: 20,
step: 1,
style: SliderStyle.OutSet
})
.width('100%')
.showTips(true)
.showSteps(false)
.onChange((value: number) => {
this.brushWidth = value;
PenSettings.getInstance().setWidth(value);
});
}
// 透明度调节
Column() {
Row() {
Text('透明度')
.fontSize(14)
.fontWeight(FontWeight.Medium);
Text(`${Math.round(this.brushAlpha / 255 * 100)}%`)
.fontSize(12)
.fontColor('#FF666666')
.margin({ left: 8 });
}
.width('100%')
.justifyContent(FlexAlign.Start);
Slider({
value: this.brushAlpha,
min: 0,
max: 255,
step: 1,
style: SliderStyle.OutSet
})
.width('100%')
.showTips(true)
.showSteps(false)
.onChange((value: number) => {
this.brushAlpha = value;
PenSettings.getInstance().setAlpha(value);
});
}
}
.padding(12)
.backgroundColor('#FFF8F8F8')
.borderRadius(12)
}
}
关键点说明:
Slider 的 showTips 属性设为 true,滑动时会显示当前数值的工具提示。setWidth / setAlpha 方法,同时传递给其绑定的回调。最后,将上述组件组合到画图APP的主页面中,并确保每次绘制时使用 PenSettings 中的最新配置。
// pages/PaintPage.ets
// 画图APP主页面,集成颜色选择器、滑块和画布区域
import PenSettings from '../utils/PenSettings';
import { ColorPicker } from '../components/ColorPicker';
import { BrushSlider } from '../components/BrushSlider';
import drawing from '@ohos.graphics.drawing';
@Entry
@Component
struct PaintPage {
private canvasContext: CanvasRenderingContext2D;
private settings: PenSettings = PenSettings.getInstance();
@State private currentTool: string = 'pen'; // 'pen' | 'rect' | 'circle'
// 当前正在使用的Pen对象
private drawingPen: drawing.Pen = new drawing.Pen();
aboutToAppear(): void {
// 注册设置变更回调:每次颜色/粗细/透明度变化时,更新当前Pen
this.settings.onSettingsChanged = () => {
this.settings.applyToPen(this.drawingPen);
};
// 初始化时应用默认设置
this.settings.applyToPen(this.drawingPen);
}
build() {
Column() {
// 顶部工具栏
Row() {
Button('画笔')
.onClick(() => { this.currentTool = 'pen'; })
Button('矩形')
.onClick(() => { this.currentTool = 'rect'; })
Button('圆形')
.onClick(() => { this.currentTool = 'circle'; })
}
.padding(8)
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
// 中间画布区域
Canvas(this.canvasContext)
.width('100%')
.layoutWeight(1)
.backgroundColor('#FFFFFFFF')
// 底部设置区:颜色选择 + 粗细/透明度
Column({ space: 12 }) {
ColorPicker()
BrushSlider()
}
.padding(8)
.width('100%')
.backgroundColor('#FFF0F0F0')
}
.width('100%')
.height('100%')
}
}
关键点说明:
aboutToAppear 中注册了 PenSettings 的回调 onSettingsChanged,当颜色、粗细或透明度改变时,自动调用 applyToPen 更新 this.drawingPen。this.drawingPen,而不是临时创建的 Pen 对象,这样才能应用最新的设置。
完成上述代码后,运行APP,应观察到以下效果:
立即调出画笔的隐藏功能!本篇教你用颜色选择器、粗细滑块和透明度滑块,实时调节画笔效果,告别单调黑线,从预设色板轻松选色,滑动控制笔触粗细与透明度,跟着步骤集成PenSettings属性管理器,让每笔绘画都自定义,实现灵活涂鸦体验
本篇产出了三个核心模块:PenSettings 画笔属性管理器、ColorPicker 颜色选择器、BrushSlider 粗细与透明度滑块。这些组件被集成到主画布页面中,实现了画笔参数的实时调节,让用户能画出不同颜色、粗细和透明度的线条。这个功能是画图APP用户体验的关键提升点,也是后续实现形状绘制、文字添加等功能的基础。
下一篇「切换绘制模式与交互反馈」将实现矩形、圆形和自由画笔三种绘制模式的切换,优化UI反馈,让用户清晰知道当前处于哪种绘制状态,为后续的图形绘制做铺垫。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8