• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Complex Drawing Effects (ArkTS)
2
3
4In addition to the basic fill color, stroke color, and some style settings, you can also use pens and brushes to implement more complex drawing effects. For example,
5
6
7- Blend mode.
8
9- Path effect, such as the dotted line effect.
10
11- Shader effect, such as linear gradient and radial gradient.
12
13- Filter effect, such as the blur effect.
14
15
16## Blend Mode
17
18The blend mode can be used for pens or brushes. It defines how to combine the source pixel (content to be drawn) with the target pixel (content that already exists on the canvas).
19
20You can use the setBlendMode() API to apply the blend mode to a pen or brush. This API needs to accept the BlendMode parameter, that is, the blend mode type. For details, see [BlendMode](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blendmode).
21
22The following uses the brush as an example to describe how to set the blending mode. (To prevent the blending mode from being interfered by the background color, the background color is not set for the canvas in the example, and the default black background is used.) The following figure shows the key example and effect.
23
24```ts
25// Create a brush.
26let brush = new drawing.Brush();
27// Set the color of the target pixel, that is, the color of the rectangle.
28brush.setColor(0xFF, 0xFF,  0x00, 0x00);
29// Set the brush effect of the target pixel in Canvas.
30canvas.attachBrush(brush);
31// Create a rectangle object.
32let rect: common2D.Rect = { left: 100, top: 100, right: 600, bottom: 600 };
33// Draw a rectangle (target pixel).
34canvas.drawRect(rect);
35// Set the color of the source pixel, that is, the color of the circle.
36brush.setColor(0xFF, 0x00,  0x00, 0xFF);
37// Set the blending mode to overlay.
38brush.setBlendMode(drawing.BlendMode.PLUS);
39// Set the brush effect of the source pixel to Canvas.
40canvas.attachBrush(brush);
41// Draw a circle (source pixel).
42canvas.drawCircle(600, 600, 300);
43// Remove the padding effect.
44canvas.detachBrush();
45```
46
47![image_0000002194025221](figures/image_0000002194025221.png)
48
49
50## Path Effects
51
52The path effect is similar to the dotted line effect, which is used only for pens.
53
54You can use the createDashPathEffect() interface to set the path effect. The interface accepts the following two parameters:
55
56- Floating-point array intervals: indicates the interval between dotted lines or dots.
57
58- Floating-point number phase: indicates the offset in the intervals array, that is, the position from which the dotted line or dot line effect is applied.
59
60The following uses the drawing of a rectangular dotted line as an example. The following figure shows the key example and effect.
61
62```ts
63// Create a pen.
64let pen = new drawing.Pen();
65// Set the line width.
66pen.setStrokeWidth(10.0);
67// Set the color.
68pen.setColor(0xFF, 0xFF, 0x00, 0x00);
69// 10px solid line, 5px interval, 2px solid line, 5px interval, and so on
70let intervals = [10, 5, 2, 5];
71// Set the dotted line path effect.
72let effect = drawing.PathEffect.createDashPathEffect(intervals, 0);
73pen.setPathEffect(effect);
74// Set the stroke effect.
75canvas.attachPen(pen);
76// Create a rectangle.
77let rect: common2D.Rect = { left: 200, top: 200, right: 1000, bottom: 700 };
78// Draw a rectangle.
79canvas.drawRect(rect);
80// Remove the stroke effect.
81canvas.detachPen();
82```
83
84| Original image| Effect after the dotted line effect is set|
85| -------- | -------- |
86| ![Screenshot_20241130160231398](figures/Screenshot_20241130160231398.jpg) | ![Screenshot_20241130160433593](figures/Screenshot_20241130160433593.jpg) |
87
88
89## Shader Effects
90
91The shader effect is implemented based on the pen or brush. You can call the setShaderEffect() API to set the shader effect of the pen or brush. Currently, different shader effects are supported, such as linear gradient shader, radial gradient shader, and sector gradient shader.
92
93
94For details about shader APIs and parameters, see [ShaderEffect](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#shadereffect12).
95
96
97### Linear Gradient Shader Effects
98
99You can use the createLinearGradient() interface to create the linear gradient shader effect to be set. The interface accepts six parameters: start point, end point, color array, tile mode, relative position array, and matrix object.
100
101- The start point and the end point are used to determine a gradient direction.
102
103- The color array is used to store colors used for gradient.
104
105- The relative position array is used to determine a relative position of each color in the gradient. If the relative position is empty, the colors are evenly distributed between the start point and the end point.
106
107- Matrix object, which is used to perform matrix transformation on the shader. The default value is null, indicating the identity matrix.
108
109- The tile mode is used to determine how to continue the gradient effect outside the gradient area. The tile mode is classified into the following four types:
110  - CLAMP: When the image exceeds its original boundary, the edge color is copied.
111  - REPEAT: repeats the image in the horizontal and vertical directions.
112  - MIRROR: Images are repeated in the horizontal and vertical directions, and mirror images are used alternately between adjacent images.
113  - DECAL: Draws only in the original domain and returns the transparent black color in other places.
114
115The following describes how to draw a rectangle and use the brush to set the linear gradient shader effect. The following figure shows the key example and effect.
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// Create a linear gradient shader.
122let shaderEffect = drawing.ShaderEffect.createLinearGradient(startPt, endPt, colors, drawing.TileMode.CLAMP);
123// Create a brush.
124let brush = new drawing.Brush();
125// Set the linear shader.
126brush.setShaderEffect(shaderEffect);
127// Set the brush filling effect.
128canvas.attachBrush(brush);
129let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
130// Draw a rectangle.
131canvas.drawRect(rect);
132// Remove the padding effect.
133canvas.detachBrush();
134```
135
136![image_0000002158744106](figures/image_0000002158744106.png)
137
138
139### Radial Gradient Shader Effects
140
141You can use the createRadialGradient() interface to create a radial gradient shader effect. The interface accepts six parameters: centerPt, radius, colors, tileMode, pos, and matrix.
142
143An implementation of the radial gradient shader is similar to that of the linear gradient shader, and a difference is that the radial gradient is radially changed outward from the center of the circle.
144
145The following describes how to draw a rectangle and use the brush to set the radial gradient shader effect. The following figure shows the key example and effect.
146
147```ts
148let centerPt: common2D.Point = { x: 500, y: 500 };
149let colors = [0xFFFF0000, 0xFF00FF00, 0xFF0000FF];
150// Create a radial gradient shader.
151let shaderEffect = drawing.ShaderEffect.createRadialGradient(centerPt, 600, colors, drawing.TileMode.CLAMP);
152// Create a brush.
153let brush = new drawing.Brush();
154// Set the radial gradient shader.
155brush.setShaderEffect(shaderEffect);
156// Set the brush filling effect.
157canvas.attachBrush(brush);
158let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
159// Draw a rectangle.
160canvas.drawRect(rect);
161// Remove the padding effect.
162canvas.detachBrush();
163```
164
165![Screenshot_20241130164939281](figures/Screenshot_20241130164939281.jpg)
166
167
168### Sector Gradient Shader Effects
169
170You can use the createSweepGradient API to create the desired sector gradient shader effect. The interface accepts seven parameters: centerPt, colors, TileMode, startAngle, and endAngle, a relative position array (pos), and a matrix object (matrix).
171
172The implementation is similar to that of the linear gradient shader. The difference is that the sector gradient changes in the process of rotating around the center point.
173
174The following describes how to draw a rectangle and use the brush to set the sector gradient shader effect. The following figure shows the key example and effect.
175
176```ts
177let centerPt: common2D.Point = { x: 500, y: 500 };
178let colors = [0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00];
179// Create a sector gradient shader.
180let shaderEffect = drawing.ShaderEffect.createSweepGradient(centerPt, colors, drawing.TileMode.CLAMP, 0, 360);
181// Create a brush.
182let brush = new drawing.Brush();
183// Set the sector gradient shader.
184brush.setShaderEffect(shaderEffect);
185// Set the brush filling effect.
186canvas.attachBrush(brush);
187let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
188// Draw a rectangle.
189canvas.drawRect(rect);
190// Remove the padding effect.
191canvas.detachBrush();
192```
193
194![Screenshot_20241130165741720](figures/Screenshot_20241130165741720.jpg)
195
196
197## Filter Effects
198
199The filter effect may be implemented based on a pen or brush. Currently, different filter effects are supported, such as the image filter, color filter, and mask filter.
200
201For details about the filter APIs and parameters, see [ImageFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#imagefilter12).
202
203
204### Color Filter Effects
205
206The color filter can be implemented based on the pen or brush. For details about the color filter APIs and parameters, see [ColorFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#colorfilter).
207
208Currently, multiple color filters can be implemented, including:
209
210- Creates an **OH_Drawing_ColorFilter** object with a given blend mode.
211
212- Creates an **OH_Drawing_ColorFilter** object with a given 5x4 color matrix.
213
214- Apply the gamma curve of SRGB to the color filter of the RGB color channel.
215
216- A color filter that applies the RGB color channel to the gamma curve of SRGB.
217
218- A color filter that multiplies its input luminance value by the alpha channel and sets the red, green, and blue channels to zero.
219
220- A color filter that consists of two color filters.
221
222Here, a color filter with a 5x4 color matrix is used as an example.
223
224You can use the createMatrixColorFilter() interface to create a color filter with a 5x4 color matrix. The interface takes one parameter, which is represented as a color matrix. It is an array of floating point numbers with a length of 20. The array format is as follows:
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
234For each original pixel color value (R, G, B, A), a transformed color value (R', G', B', A') is calculated as follows:
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
244The following describes how to draw a rectangle and use the brush to set the color filter effect with a 5 x 4 color matrix. The following figure shows the key example and effect.
245
246```ts
247// Create a brush.
248let brush = new drawing.Brush();
249// Set the color.
250brush.setColor(0xFF, 0xFF, 0x00, 0x00);
251// Set the color matrix.
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// Create a color filter for the 5x4 color matrix.
259let filter = drawing.ColorFilter.createMatrixColorFilter(matrix);
260// Set the color filter.
261brush.setColorFilter(filter);
262// Set the brush filling effect.
263canvas.attachBrush(brush);
264let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
265// Draw a rectangle.
266canvas.drawRect(rect);
267// Remove the padding effect.
268canvas.detachBrush();
269```
270
271| Original image| Effect after the color filter of the 5x4 color matrix is set|
272| -------- | -------- |
273| ![Screenshot_20241130173415925](figures/Screenshot_20241130173415925.jpg) | ![Screenshot_20241130173354704](figures/Screenshot_20241130173354704.jpg) |
274
275
276### Image Filter Effects
277
278The image filter can be implemented based on the pen or brush. For details about the image filter APIs and parameters, see [ImageFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#imagefilter12).
279
280Currently, only two types of image filters are supported:
281
282- Image filter based on the color filter.
283  You can implement this function by calling createFromColorFilter(). The interface accepts two parameters: colorFilter and imageFilter. That is, the effect of the color filter is superimposed on the imageFilter. The imageFilter can be null. If the imageFilter is null, only the effect of the color filter is added.
284
285- Creates an image filter with a given blur effect.
286  You can use the createBlurImageFilter() interface to implement this function. The interface accepts four parameters: sigmaX, sigmaY, cTileMode, and imageFilter. sigmaX and sigmaY are the standard deviation of blur, cTileMode is the tile mode, and imageFilter is the input image filter.
287
288  The final effect is to perform blurring processing based on the input image filter imageFilter. That is, the filter effect can be overlaid. imageFilter can be empty. If imageFilter is empty, only the blur effect is added.
289
290The following uses drawing a rectangle and using a pen to add the blur effect to the image filter as an example. The following figure shows the key example and effect.
291
292```ts
293// Set the pen.
294let pen = new drawing.Pen();
295// Set the line width.
296pen.setStrokeWidth(10.0);
297// Set the color.
298pen.setColor(0xFF, 0xFF, 0x00, 0x00);
299// Create a blurry image filter.
300let filter = drawing.ImageFilter.createBlurImageFilter(20, 20, drawing.TileMode.CLAMP);
301// Set the image filter.
302pen.setImageFilter(filter);
303// Set the stroke effect.
304canvas.attachPen(pen);
305let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
306// Draw a rectangle.
307canvas.drawRect(rect);
308// Remove the stroke effect.
309canvas.detachPen();
310```
311
312| Original image| Effect after the blur effect is set|
313| -------- | -------- |
314| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
315
316
317### Mask Filter Effects
318
319The blur effect of the mask filter blurs only the transparency and shape edges. Compared with the blur effect of the image filter, the calculation cost of the mask filter is lower.
320
321The mask filter can be implemented based on the pen or brush. For details about the mask filter APIs and parameters, see [MaskFilter](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#maskfilter12).
322
323You can use the createBlurMaskFilter() interface to create a mask filter with the blur effect. The interface accepts the following two parameters:
324
325- blurType: fuzzy type to be applied. For details, see [BlurType](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blurtype12).
326
327- sigma: specifies the standard deviation of the Gaussian blur to be applied. The standard deviation must be greater than 0.
328
329The following describes how to draw a rectangle and use a pen to set the mask filter effect. The following figure shows the key example and effect.
330
331```ts
332// Create a pen.
333let pen = new drawing.Pen();
334// Set the line width.
335pen.setStrokeWidth(10.0);
336// Set the color.
337pen.setColor(0xFF, 0xFF, 0x00, 0x00);
338// Create a mask filter for the blur effect.
339let filter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, 20);
340// Set the blur effect.
341pen.setMaskFilter(filter);
342// Set the stroke effect.
343canvas.attachPen(pen);
344let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
345// Draw a rectangle.
346canvas.drawRect(rect);
347// Remove the stroke effect.
348canvas.detachPen();
349```
350
351| Original image| Effect after the blur effect is set|
352| -------- | -------- |
353| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
354