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 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|  |  | 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 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 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 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|  |  | 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|  |  | 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|  |  | 354