• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 复杂绘制效果(ArkTS)
2
3
4除了基础填充颜色、描边颜色和一些样式设置的绘制效果外,还支持通过画刷和画笔实现更多复杂的绘制效果。比如:
5
6
7- 混合模式。
8
9- 路径效果,如虚线效果。
10
11- 着色器效果,如线性渐变、径向渐变等。
12
13- 滤波效果,如模糊效果等。
14
15
16## 混合模式
17
18混合模式可以用于画笔或画刷,它定义了如何将源像素(要绘制的内容)与目标像素(已存在于画布上的内容)进行组合。
19
20可以使用setBlendMode()接口将混合模式应用于画刷或画笔中,该接口需要接受一个参数BlendMode,即混合模式的类型,具体可参考[BlendMode](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blendmode)。
21
22此处以使用画刷设置叠加混合模式为例(为了防止混合模式的效果被背景色干扰,示例中的canvas并未设置背景色,使用的是默认的黑色背景),关键示例和效果示意图如下所示:
23
24```ts
25// 创建画刷
26let brush = new drawing.Brush();
27// 设置目标像素颜色,即矩形的颜色
28brush.setColor(0xFF, 0xFF,  0x00, 0x00);
29// 将目标像素的画刷效果设置到Canvas中
30canvas.attachBrush(brush);
31// 创建矩形对象
32let rect: common2D.Rect = { left: 100, top: 100, right: 600, bottom: 600 };
33// 绘制矩形(目标像素)
34canvas.drawRect(rect);
35// 设置源像素颜色,即圆形的颜色
36brush.setColor(0xFF, 0x00,  0x00, 0xFF);
37// 设置混合模式为叠加模式
38brush.setBlendMode(drawing.BlendMode.PLUS);
39// 将源像素的画刷效果设置到Canvas中
40canvas.attachBrush(brush);
41// 绘制圆(源像素)
42canvas.drawCircle(600, 600, 300);
43// 去除填充效果
44canvas.detachBrush();
45```
46
47![zh-cn_image_0000002194025221](figures/zh-cn_image_0000002194025221.png)
48
49
50## 路径效果
51
52路径效果如虚线效果,只用于画笔。
53
54可使用createDashPathEffect()接口设置路径效果。接口接受2个参数,分别为:
55
56- 浮点数数组intervals:表示虚线或者点线的间隔。
57
58- 浮点数phase:表示在intervals数组中的偏移量,即从数组的哪个位置开始应用虚线或点线效果。
59
60此处以绘制矩形虚线路径效果为例,关键示例和效果示意图如下所示:
61
62```ts
63// 创建画笔
64let pen = new drawing.Pen();
65// 设置线宽
66pen.setStrokeWidth(10.0);
67// 设置颜色
68pen.setColor(0xFF, 0xFF, 0x00, 0x00);
69// 表示10px的实线,5px的间隔,2px的实线,5px的间隔,以此循环
70let intervals = [10, 5, 2, 5];
71// 设置虚线路径效果
72let effect = drawing.PathEffect.createDashPathEffect(intervals, 0);
73pen.setPathEffect(effect);
74// 设置画笔描边效果
75canvas.attachPen(pen);
76// 创建矩形
77let rect: common2D.Rect = { left: 200, top: 200, right: 1000, bottom: 700 };
78// 绘制矩形
79canvas.drawRect(rect);
80// 去除描边效果
81canvas.detachPen();
82```
83
84| 原始图 | 设置虚线效果后的效果图 |
85| -------- | -------- |
86| ![Screenshot_20241130160231398](figures/Screenshot_20241130160231398.jpg) | ![Screenshot_20241130160433593](figures/Screenshot_20241130160433593.jpg) |
87
88
89## 着色器效果
90
91着色器效果基于画刷或画笔实现,可使用setShaderEffect()接口设置画刷或画笔的着色器效果。当前支持不同的着色器效果,如线性渐变着色器效果、径向渐变着色器效果、扇形渐变着色器效果。
92
93
94着色器相关接口和具体参数的说明请见[ShaderEffect](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#shadereffect12)。
95
96
97### 线性渐变着色器效果
98
99可使用createLinearGradient()接口创建想要设置的线性渐变着色器效果。接口接受6个参数,分别是开始点、结束点、颜色数组、平铺模式、相对位置数组以及矩阵对象。
100
101- 开始点和结束点用来确定渐变方向。
102
103- 颜色数组用于存储渐变使用到的颜色。
104
105- 相对位置数组则用于确定每种颜色在渐变中的相对位置,如果相对位置为空,颜色将会被均匀地分布在开始点和结束点之间。
106
107- 矩阵对象,用于对着色器做矩阵变换,默认为null,表示单位矩阵。
108
109- 平铺模式用于确定如何在渐变区域之外继续渐变效果,平铺模式分为以下4类:
110  - CLAMP:当图像超出其原始边界时,复制边缘颜色。
111  - REPEAT:在水平和垂直方向上重复图像。
112  - MIRROR:在水平和垂直方向上重复图像,并在相邻的图像之间交替使用镜像图像。
113  - DECAL:只在原始域内绘制,在其他地方返回透明黑色。
114
115此处以绘制矩形并使用画刷设置线性渐变着色器效果为例,关键示例和效果示意图如下所示:
116
117```ts
118let startPt: common2D.Point = { x: 100, y: 100 };
119let endPt: common2D.Point = { x: 900, y: 900 };
120let colors = [0xFFFFFF00, 0xFFFF0000, 0xFF0000FF];
121// 创建线性渐变着色器
122let shaderEffect = drawing.ShaderEffect.createLinearGradient(startPt, endPt, colors, drawing.TileMode.CLAMP);
123// 创建画刷
124let brush = new drawing.Brush();
125// 设置线性着色器
126brush.setShaderEffect(shaderEffect);
127// 设置画刷填充效果
128canvas.attachBrush(brush);
129let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
130// 绘制矩形
131canvas.drawRect(rect);
132// 去除填充效果
133canvas.detachBrush();
134```
135
136![zh-cn_image_0000002158744106](figures/zh-cn_image_0000002158744106.png)
137
138
139### 径向渐变着色器效果
140
141可使用createRadialGradient()接口创建想要设置的径向渐变着色器效果。接口接受6个参数,分别是圆心坐标(centerPt)、半径(radius)、颜色数组(colors)、平铺模式(TileMode)、相对位置数组(pos)以及矩阵对象(matrix)。
142
143其实现方式与线性渐变着色器类似,不同的是,径向渐变是由圆心开始向外径向渐变的。
144
145此处以绘制矩形并使用画刷设置径向渐变着色器效果为例,关键示例和效果示意图如下所示:
146
147```ts
148let centerPt: common2D.Point = { x: 500, y: 500 };
149let colors = [0xFFFF0000, 0xFF00FF00, 0xFF0000FF];
150// 创建径向渐变着色器
151let shaderEffect = drawing.ShaderEffect.createRadialGradient(centerPt, 600, colors, drawing.TileMode.CLAMP);
152// 创建画刷
153let brush = new drawing.Brush();
154// 设置径向渐变着色器
155brush.setShaderEffect(shaderEffect);
156// 设置画刷填充效果
157canvas.attachBrush(brush);
158let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
159// 绘制矩形
160canvas.drawRect(rect);
161// 去除填充效果
162canvas.detachBrush();
163```
164
165![Screenshot_20241130164939281](figures/Screenshot_20241130164939281.jpg)
166
167
168### 扇形渐变着色器效果
169
170可使用createSweepGradient接口创建想要设置的扇形渐变着色器效果。接口接受7个参数,分别是圆心坐标(centerPt)、颜色数组(colors)、平铺模式(TileMode)、扇形渐变的起始角度(startAngle)、扇形渐变的结束角度(endAngle)、相对位置数组(pos)以及矩阵对象(matrix)。
171
172其实现方式也与线性渐变着色器类似,不同的是,扇形渐变是在围绕中心点旋转的过程中渐变。
173
174此处以绘制矩形并使用画刷设置扇形渐变着色器效果为例,关键示例和效果示意图如下所示:
175
176```ts
177let centerPt: common2D.Point = { x: 500, y: 500 };
178let colors = [0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00];
179// 创建扇形渐变着色器
180let shaderEffect = drawing.ShaderEffect.createSweepGradient(centerPt, colors, drawing.TileMode.CLAMP, 0, 360);
181// 创建画刷
182let brush = new drawing.Brush();
183// 设置扇形渐变着色器
184brush.setShaderEffect(shaderEffect);
185// 设置画刷填充效果
186canvas.attachBrush(brush);
187let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
188// 绘制矩形
189canvas.drawRect(rect);
190// 去除填充效果
191canvas.detachBrush();
192```
193
194![Screenshot_20241130165741720](figures/Screenshot_20241130165741720.jpg)
195
196
197## 滤波器效果
198
199滤波器效果可基于画刷或画笔实现。当前支持不同的滤波器效果,比如图像滤波器、颜色滤波器、蒙版滤波器。
200
201滤波器相关接口和具体参数的说明请见[ImageFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#imagefilter12)。
202
203
204### 颜色滤波器效果
205
206颜色滤波器可基于画笔或画刷实现,颜色滤波器的相关接口和具体参数的说明请见[ColorFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#colorfilter)。
207
208目前可实现多种颜色滤波器,包括如下:
209
210- 具有混合模式的颜色滤波器。
211
212- 具有5x4颜色矩阵的颜色滤波器。
213
214- 将SRGB的伽玛曲线应用到RGB颜色通道的颜色滤波器。
215
216- 将RGB颜色通道应用于SRGB的伽玛曲线的颜色滤波器。
217
218- 将其输入的亮度值乘以透明度通道, 并将红色、绿色和蓝色通道设置为零的颜色滤波器。
219
220- 由两个颜色滤波器组合而成的颜色滤波器。
221
222此处以具有5x4颜色矩阵的颜色滤波器为例。
223
224可使用createMatrixColorFilter()接口创建具有5x4颜色矩阵的颜色滤波器。接口接受1个参数,表示为颜色矩阵,它是一个长度为20的浮点数数组。数组格式如下:
225
226[ a0, a1, a2, a3, a4 ]
227
228[ b0, b1, b2, b3, b4 ]
229
230[ c0, c1, c2, c3, c4 ]
231
232[ d0, d1, d2, d3, d4 ]
233
234对于每个原始的像素颜色色值(R, G, B, A),变换后的色值(R', G', B', A')计算公式为:
235
236R' = a0\*R + a1\*G + a2\*B + a3\*A + a4
237
238G' = b0\*R + b1\*G + b2\*B + b3\*A + b4
239
240B' = c0\*R + c1\*G + c2\*B + c3\*A + c4
241
242A' = d0\*R + d1\*G + d2\*B + d3\*A + d4
243
244此处以绘制矩形并使用画刷设置具有5x4颜色矩阵的颜色滤波器效果为例,关键示例和效果示意图如下所示:
245
246```ts
247// 创建画刷
248let brush = new drawing.Brush();
249// 设置颜色
250brush.setColor(0xFF, 0xFF, 0x00, 0x00);
251// 设置颜色矩阵
252let matrix: Array<number> = [
253  1, 0, 0, 0, 0,
254  0, 1, 0, 0, 0,
255  0, 0, 0.5, 0.5, 0,
256  0, 0, 0.5, 0.5, 0
257];
258// 创建5x4颜色矩阵的颜色滤波器
259let filter = drawing.ColorFilter.createMatrixColorFilter(matrix);
260// 设置颜色滤波器
261brush.setColorFilter(filter);
262// 设置画刷填充效果
263canvas.attachBrush(brush);
264let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
265// 绘制矩形
266canvas.drawRect(rect);
267// 去除填充效果
268canvas.detachBrush();
269```
270
271| 原始图 | 设置5x4颜色矩阵的颜色滤波器后的效果图 |
272| -------- | -------- |
273| ![Screenshot_20241130173415925](figures/Screenshot_20241130173415925.jpg) | ![Screenshot_20241130173354704](figures/Screenshot_20241130173354704.jpg) |
274
275
276### 图像滤波器效果
277
278图像滤波器可基于画笔或画刷来实现,图像滤波器的相关接口和具体参数的说明请见[ImageFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#imagefilter12)。
279
280目前只支持两种图像滤波器:
281
282- 基于颜色滤波器的图像滤波器。
283  可通过createFromColorFilter()接口实现,接口接受2个参数,颜色滤波器colorFilter和图像滤波器imageFilter,即把颜色滤波器的效果叠加到图像滤波器imageFilter上,imageFilter可为空,imageFilter为空则只添加颜色滤波器效果。
284
285- 具有模糊效果的图像滤波器。
286  可通过createBlurImageFilter()接口实现,接口接受4个参数,sigmaX,sigmaY,cTileMode和imageFilter。sigmaX和sigmaY是模糊的标准差,cTileMode是平铺模式,imageFilter是输入的图像滤波器。
287
288  最终效果即为在输入的图像滤波器imageFilter的基础上进行模糊化处理,即滤波器效果可叠加,imageFilter可为空,imageFilter为空则只添加模糊效果。
289
290此处以绘制矩形并使用画笔添加模糊效果的图像滤波器效果为例,关键示例和效果示意图如下所示:
291
292```ts
293// 设置画笔
294let pen = new drawing.Pen();
295// 设置线宽
296pen.setStrokeWidth(10.0);
297// 设置颜色
298pen.setColor(0xFF, 0xFF, 0x00, 0x00);
299// 创建模糊效果图像滤波器
300let filter = drawing.ImageFilter.createBlurImageFilter(20, 20, drawing.TileMode.CLAMP);
301// 设置图像滤波器
302pen.setImageFilter(filter);
303// 设置画笔描边效果
304canvas.attachPen(pen);
305let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
306// 绘制矩形
307canvas.drawRect(rect);
308// 去除描边效果
309canvas.detachPen();
310```
311
312| 原始图 | 设置模糊效果后的效果图 |
313| -------- | -------- |
314| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
315
316
317### 蒙版滤波器效果
318
319蒙版滤波器的模糊效果仅对透明度和形状边缘进行模糊处理,相对于图像滤波器的模糊效果来说计算成本更低。
320
321蒙版滤波器可基于画笔或画刷实现,蒙版滤波器的相关接口和具体参数的说明请见[MaskFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#maskfilter12)。
322
323可使用createBlurMaskFilter()接口创建想要设置具有模糊效果的蒙版滤波器。接口接受2个参数,分别为:
324
325- blurType:用于指定要应用的模糊类型,详细分类请参考[BlurType](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blurtype12)。
326
327- sigma:用于指定要应用的高斯模糊的标准差,标准差必须大于0。
328
329此处以绘制矩形并使用画笔设置蒙版滤波器效果为例,关键示例和效果示意图如下所示:
330
331```ts
332// 创建画笔
333let pen = new drawing.Pen();
334// 设置线宽
335pen.setStrokeWidth(10.0);
336// 设置颜色
337pen.setColor(0xFF, 0xFF, 0x00, 0x00);
338// 创建模糊效果的蒙版滤波器
339let filter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, 20);
340// 设置模糊效果
341pen.setMaskFilter(filter);
342// 设置画笔描边效果
343canvas.attachPen(pen);
344let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
345// 绘制矩形
346canvas.drawRect(rect);
347// 去除描边效果
348canvas.detachPen();
349```
350
351| 原始图 | 设置模糊效果后的效果图 |
352| -------- | -------- |
353| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
354
355<!--RP1-->
356## 相关实例
357
358针对Drawing(ArkTS)的开发,有以下相关实例可供参考:
359
360- [ArkTSGraphicsDraw (API14)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/ArkTSGraphicsDraw)
361<!--RP1End-->