0
# Graphics and Visual Effects
1
2
Comprehensive 2D graphics system for custom drawing, visual effects, and image handling with hardware acceleration support for creating rich visual experiences across all platforms.
3
4
## Capabilities
5
6
### Color System
7
8
Core color representation and manipulation system supporting multiple color spaces and formats.
9
10
```kotlin { .api }
11
/**
12
* The Color class contains color information for drawing.
13
*/
14
@Immutable
15
class Color(val value: ULong) {
16
/**
17
* Construct a Color from ARGB float values in [0..1].
18
*/
19
constructor(
20
red: Float,
21
green: Float,
22
blue: Float,
23
alpha: Float = 1.0f,
24
colorSpace: ColorSpace = ColorSpaces.Srgb
25
)
26
27
/**
28
* Construct a Color from ARGB int values in [0..255].
29
*/
30
constructor(red: Int, green: Int, blue: Int, alpha: Int = 255)
31
32
/**
33
* Returns the red component of the color in the [0..1] range.
34
*/
35
val red: Float
36
37
/**
38
* Returns the green component of the color in the [0..1] range.
39
*/
40
val green: Float
41
42
/**
43
* Returns the blue component of the color in the [0..1] range.
44
*/
45
val blue: Float
46
47
/**
48
* Returns the alpha component of the color in the [0..1] range.
49
*/
50
val alpha: Float
51
52
/**
53
* The ColorSpace associated with this color.
54
*/
55
val colorSpace: ColorSpace
56
57
/**
58
* Copies this Color, optionally overriding some of the values.
59
*/
60
fun copy(
61
alpha: Float = this.alpha,
62
red: Float = this.red,
63
green: Float = this.green,
64
blue: Float = this.blue
65
): Color
66
67
companion object {
68
val Black: Color
69
val DarkGray: Color
70
val Gray: Color
71
val LightGray: Color
72
val White: Color
73
val Red: Color
74
val Green: Color
75
val Blue: Color
76
val Yellow: Color
77
val Cyan: Color
78
val Magenta: Color
79
val Transparent: Color
80
val Unspecified: Color
81
}
82
}
83
84
/**
85
* Create a Color from a color int (0xAARRGGBB format).
86
*/
87
fun Color(color: Long): Color
88
89
/**
90
* Create a Color from a color int (0xRRGGBB format with alpha = 255).
91
*/
92
fun Color(color: Int): Color
93
94
/**
95
* Parse a color from a hex string.
96
*/
97
fun Color.parseColor(colorString: String): Color
98
```
99
100
**Usage Examples:**
101
102
```kotlin
103
// Creating colors
104
val red = Color.Red
105
val customColor = Color(0.2f, 0.8f, 0.1f, 1.0f)
106
val fromHex = Color(0xFF2196F3)
107
val fromInt = Color(255, 100, 50)
108
109
// Color manipulation
110
val transparentRed = Color.Red.copy(alpha = 0.5f)
111
val components = Color.Blue.run { "R:$red G:$green B:$blue A:$alpha" }
112
```
113
114
### Canvas Drawing
115
116
Primary drawing interface for custom graphics with comprehensive drawing operations.
117
118
```kotlin { .api }
119
/**
120
* Drawing surface that provides methods to draw geometric shapes, text, and images.
121
*/
122
interface Canvas {
123
/**
124
* Draws a rectangle.
125
*/
126
fun drawRect(
127
color: Color,
128
topLeft: Offset = Offset.Zero,
129
size: Size = Size.Unspecified,
130
style: DrawStyle = Fill
131
)
132
133
/**
134
* Draws a rectangle with a Brush.
135
*/
136
fun drawRect(
137
brush: Brush,
138
topLeft: Offset = Offset.Zero,
139
size: Size = Size.Unspecified,
140
style: DrawStyle = Fill
141
)
142
143
/**
144
* Draws a rounded rectangle.
145
*/
146
fun drawRoundRect(
147
color: Color,
148
topLeft: Offset = Offset.Zero,
149
size: Size = Size.Unspecified,
150
cornerRadius: CornerRadius = CornerRadius.Zero,
151
style: DrawStyle = Fill
152
)
153
154
/**
155
* Draws a circle.
156
*/
157
fun drawCircle(
158
color: Color,
159
radius: Float,
160
center: Offset = Offset.Unspecified,
161
style: DrawStyle = Fill
162
)
163
164
/**
165
* Draws a circle with a Brush.
166
*/
167
fun drawCircle(
168
brush: Brush,
169
radius: Float,
170
center: Offset = Offset.Unspecified,
171
style: DrawStyle = Fill
172
)
173
174
/**
175
* Draws an oval.
176
*/
177
fun drawOval(
178
color: Color,
179
topLeft: Offset = Offset.Zero,
180
size: Size = Size.Unspecified,
181
style: DrawStyle = Fill
182
)
183
184
/**
185
* Draws a line between two points.
186
*/
187
fun drawLine(
188
color: Color,
189
start: Offset,
190
end: Offset,
191
strokeWidth: Float = Stroke.HairlineWidth
192
)
193
194
/**
195
* Draws a path.
196
*/
197
fun drawPath(
198
path: Path,
199
color: Color,
200
style: DrawStyle = Fill
201
)
202
203
/**
204
* Draws a path with a Brush.
205
*/
206
fun drawPath(
207
path: Path,
208
brush: Brush,
209
style: DrawStyle = Fill
210
)
211
212
/**
213
* Draws an image at the given offset.
214
*/
215
fun drawImage(
216
image: ImageBitmap,
217
topLeft: Offset = Offset.Zero,
218
paint: Paint = Paint()
219
)
220
221
/**
222
* Draws a subsection of an image.
223
*/
224
fun drawImageRect(
225
image: ImageBitmap,
226
srcOffset: IntOffset = IntOffset.Zero,
227
srcSize: IntSize = IntSize(image.width, image.height),
228
dstOffset: IntOffset = IntOffset.Zero,
229
dstSize: IntSize = srcSize,
230
paint: Paint = Paint()
231
)
232
233
/**
234
* Draws vertices as triangles.
235
*/
236
fun drawVertices(
237
vertices: Vertices,
238
blendMode: BlendMode,
239
paint: Paint
240
)
241
242
/**
243
* Saves the current drawing state.
244
*/
245
fun save()
246
247
/**
248
* Restores the previously saved drawing state.
249
*/
250
fun restore()
251
252
/**
253
* Translates the canvas.
254
*/
255
fun translate(dx: Float, dy: Float)
256
257
/**
258
* Scales the canvas.
259
*/
260
fun scale(sx: Float, sy: Float = sx)
261
262
/**
263
* Rotates the canvas.
264
*/
265
fun rotate(degrees: Float)
266
267
/**
268
* Skews the canvas.
269
*/
270
fun skew(sx: Float, sy: Float)
271
272
/**
273
* Clips the canvas to a rectangle.
274
*/
275
fun clipRect(rect: Rect, clipOp: ClipOp = ClipOp.Intersect)
276
277
/**
278
* Clips the canvas to a path.
279
*/
280
fun clipPath(path: Path, clipOp: ClipOp = ClipOp.Intersect)
281
}
282
283
/**
284
* Drawing style for strokes and fills.
285
*/
286
sealed class DrawStyle {
287
object Fill : DrawStyle()
288
class Stroke(
289
val width: Float = 0.0f,
290
val miter: Float = DefaultMiter,
291
val cap: StrokeCap = StrokeCap.Butt,
292
val join: StrokeJoin = StrokeJoin.Miter,
293
val pathEffect: PathEffect? = null
294
) : DrawStyle() {
295
companion object {
296
val HairlineWidth: Float
297
val DefaultMiter: Float
298
}
299
}
300
}
301
```
302
303
**Usage Examples:**
304
305
```kotlin
306
// Custom drawing in a Canvas composable
307
Canvas(modifier = Modifier.size(200.dp)) { canvas ->
308
// Draw filled rectangle
309
canvas.drawRect(
310
color = Color.Blue,
311
topLeft = Offset(50.0f, 50.0f),
312
size = Size(100.0f, 100.0f)
313
)
314
315
// Draw outlined circle
316
canvas.drawCircle(
317
color = Color.Red,
318
radius = 40.0f,
319
center = Offset(100.0f, 100.0f),
320
style = Stroke(width = 4.0f)
321
)
322
323
// Draw gradient rectangle
324
canvas.drawRect(
325
brush = Brush.linearGradient(
326
colors = listOf(Color.Yellow, Color.Green)
327
),
328
topLeft = Offset(0.0f, 150.0f),
329
size = Size(200.0f, 50.0f)
330
)
331
}
332
```
333
334
### Path System
335
336
Vector path operations for creating complex shapes and custom drawing paths.
337
338
```kotlin { .api }
339
/**
340
* A Path encapsulates compound geometric paths.
341
*/
342
class Path {
343
/**
344
* Set this path to the empty path.
345
*/
346
fun reset()
347
348
/**
349
* Move to the given coordinates without drawing a line.
350
*/
351
fun moveTo(x: Float, y: Float)
352
353
/**
354
* Relative version of moveTo.
355
*/
356
fun relativeMoveTo(dx: Float, dy: Float)
357
358
/**
359
* Add a line from the last point to the specified coordinates.
360
*/
361
fun lineTo(x: Float, y: Float)
362
363
/**
364
* Relative version of lineTo.
365
*/
366
fun relativeLineTo(dx: Float, dy: Float)
367
368
/**
369
* Add a quadratic bezier curve.
370
*/
371
fun quadraticBezierTo(x1: Float, y1: Float, x2: Float, y2: Float)
372
373
/**
374
* Relative version of quadraticBezierTo.
375
*/
376
fun relativeQuadraticBezierTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float)
377
378
/**
379
* Add a cubic bezier curve.
380
*/
381
fun cubicTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float)
382
383
/**
384
* Relative version of cubicTo.
385
*/
386
fun relativeCubicTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float, dx3: Float, dy3: Float)
387
388
/**
389
* Add an arc.
390
*/
391
fun arcTo(
392
rect: Rect,
393
startAngleDegrees: Float,
394
sweepAngleDegrees: Float,
395
forceMoveTo: Boolean
396
)
397
398
/**
399
* Add a rectangle to the path.
400
*/
401
fun addRect(rect: Rect)
402
403
/**
404
* Add an oval to the path.
405
*/
406
fun addOval(oval: Rect)
407
408
/**
409
* Add a rounded rectangle to the path.
410
*/
411
fun addRoundRect(
412
roundRect: RoundRect
413
)
414
415
/**
416
* Add a circle to the path.
417
*/
418
fun addPath(path: Path, offset: Offset = Offset.Zero)
419
420
/**
421
* Close the current sub-path.
422
*/
423
fun close()
424
425
/**
426
* Returns the bounds of this path.
427
*/
428
fun getBounds(): Rect
429
430
/**
431
* Returns true if the path is empty.
432
*/
433
fun isEmpty(): Boolean
434
435
/**
436
* Returns true if the path is convex.
437
*/
438
fun isConvex(): Boolean
439
440
/**
441
* Set this path to the result of applying the path operation to the two paths.
442
*/
443
fun op(path1: Path, path2: Path, operation: PathOperation): Boolean
444
445
/**
446
* Transform the path by the given matrix.
447
*/
448
fun transform(matrix: Matrix)
449
}
450
451
/**
452
* Path operations for combining paths.
453
*/
454
enum class PathOperation {
455
Difference, Intersect, Union, Xor, ReverseDifference
456
}
457
458
/**
459
* Path effects for modifying path drawing.
460
*/
461
abstract class PathEffect {
462
companion object {
463
/**
464
* Create a dash path effect.
465
*/
466
fun dashPathEffect(intervals: FloatArray, phase: Float = 0.0f): PathEffect
467
468
/**
469
* Create a corner path effect.
470
*/
471
fun cornerPathEffect(radius: Float): PathEffect
472
473
/**
474
* Chain two path effects.
475
*/
476
fun chainPathEffect(outer: PathEffect, inner: PathEffect): PathEffect
477
}
478
}
479
```
480
481
**Usage Examples:**
482
483
```kotlin
484
// Creating custom shapes with Path
485
val customPath = Path().apply {
486
moveTo(50.0f, 0.0f)
487
lineTo(100.0f, 50.0f)
488
lineTo(50.0f, 100.0f)
489
lineTo(0.0f, 50.0f)
490
close()
491
}
492
493
// Drawing the custom path
494
Canvas(modifier = Modifier.size(100.dp)) { canvas ->
495
canvas.drawPath(
496
path = customPath,
497
color = Color.Green,
498
style = Stroke(width = 3.0f)
499
)
500
}
501
502
// Bezier curve example
503
val curvePath = Path().apply {
504
moveTo(0.0f, 100.0f)
505
cubicTo(50.0f, 0.0f, 150.0f, 0.0f, 200.0f, 100.0f)
506
}
507
```
508
509
### Brush and Gradient System
510
511
Advanced painting system supporting gradients, patterns, and custom brushes.
512
513
```kotlin { .api }
514
/**
515
* Defines a brush to draw shapes with. Can be a solid color, gradient, or pattern.
516
*/
517
abstract class Brush {
518
companion object {
519
/**
520
* Creates a linear gradient brush.
521
*/
522
fun linearGradient(
523
colors: List<Color>,
524
start: Offset = Offset.Zero,
525
end: Offset = Offset.Infinite,
526
tileMode: TileMode = TileMode.Clamp
527
): Brush
528
529
/**
530
* Creates a linear gradient brush with color stops.
531
*/
532
fun linearGradient(
533
vararg colorStops: Pair<Float, Color>,
534
start: Offset = Offset.Zero,
535
end: Offset = Offset.Infinite,
536
tileMode: TileMode = TileMode.Clamp
537
): Brush
538
539
/**
540
* Creates a radial gradient brush.
541
*/
542
fun radialGradient(
543
colors: List<Color>,
544
center: Offset = Offset.Unspecified,
545
radius: Float = Float.POSITIVE_INFINITY,
546
tileMode: TileMode = TileMode.Clamp
547
): Brush
548
549
/**
550
* Creates a radial gradient brush with color stops.
551
*/
552
fun radialGradient(
553
vararg colorStops: Pair<Float, Color>,
554
center: Offset = Offset.Unspecified,
555
radius: Float = Float.POSITIVE_INFINITY,
556
tileMode: TileMode = TileMode.Clamp
557
): Brush
558
559
/**
560
* Creates a sweep gradient brush.
561
*/
562
fun sweepGradient(
563
colors: List<Color>,
564
center: Offset = Offset.Unspecified
565
): Brush
566
567
/**
568
* Creates a sweep gradient brush with color stops.
569
*/
570
fun sweepGradient(
571
vararg colorStops: Pair<Float, Color>,
572
center: Offset = Offset.Unspecified
573
): Brush
574
575
/**
576
* Creates a horizontal gradient brush.
577
*/
578
fun horizontalGradient(
579
colors: List<Color>,
580
startX: Float = 0.0f,
581
endX: Float = Float.POSITIVE_INFINITY,
582
tileMode: TileMode = TileMode.Clamp
583
): Brush
584
585
/**
586
* Creates a vertical gradient brush.
587
*/
588
fun verticalGradient(
589
colors: List<Color>,
590
startY: Float = 0.0f,
591
endY: Float = Float.POSITIVE_INFINITY,
592
tileMode: TileMode = TileMode.Clamp
593
): Brush
594
}
595
}
596
597
/**
598
* Solid color brush.
599
*/
600
class SolidColor(val value: Color) : Brush()
601
602
/**
603
* Tile modes for gradients and patterns.
604
*/
605
enum class TileMode {
606
Clamp, Repeat, Mirror, Decal
607
}
608
```
609
610
**Usage Examples:**
611
612
```kotlin
613
// Linear gradient
614
val linearBrush = Brush.linearGradient(
615
colors = listOf(Color.Red, Color.Yellow, Color.Green),
616
start = Offset.Zero,
617
end = Offset(100.0f, 0.0f)
618
)
619
620
// Radial gradient with color stops
621
val radialBrush = Brush.radialGradient(
622
0.0f to Color.White,
623
0.5f to Color.Blue,
624
1.0f to Color.Black,
625
center = Offset(50.0f, 50.0f),
626
radius = 50.0f
627
)
628
629
// Using brushes in drawing
630
Canvas(modifier = Modifier.size(100.dp)) { canvas ->
631
canvas.drawRect(brush = linearBrush)
632
canvas.drawCircle(
633
brush = radialBrush,
634
radius = 30.0f,
635
center = Offset(50.0f, 50.0f)
636
)
637
}
638
```
639
640
### Image Handling
641
642
Comprehensive image loading, manipulation, and rendering system.
643
644
```kotlin { .api }
645
/**
646
* Create an ImageBitmap from image file bytes.
647
*/
648
fun decodeImageFromByteArray(byteArray: ByteArray): ImageBitmap
649
650
/**
651
* Represents a bitmap image.
652
*/
653
interface ImageBitmap {
654
/**
655
* Width of the ImageBitmap in pixels.
656
*/
657
val width: Int
658
659
/**
660
* Height of the ImageBitmap in pixels.
661
*/
662
val height: Int
663
664
/**
665
* ColorSpace of the ImageBitmap.
666
*/
667
val colorSpace: ColorSpace
668
669
/**
670
* Indicates whether the ImageBitmap has an alpha channel.
671
*/
672
val hasAlpha: Boolean
673
674
/**
675
* Prepares the bitmap to be drawn.
676
*/
677
fun prepareToDraw()
678
679
/**
680
* Read the pixels from this bitmap.
681
*/
682
fun readPixels(
683
buffer: IntArray,
684
startX: Int = 0,
685
startY: Int = 0,
686
width: Int = this.width,
687
height: Int = this.height
688
)
689
}
690
691
/**
692
* Represents a Painter that can draw content.
693
*/
694
abstract class Painter {
695
/**
696
* The intrinsic size of the content.
697
*/
698
abstract val intrinsicSize: Size
699
700
/**
701
* Draw the content.
702
*/
703
protected abstract fun DrawScope.onDraw()
704
}
705
706
/**
707
* Create a BitmapPainter from an ImageBitmap.
708
*/
709
fun BitmapPainter(
710
image: ImageBitmap,
711
srcOffset: IntOffset = IntOffset.Zero,
712
srcSize: IntSize = IntSize(image.width, image.height),
713
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality
714
): Painter
715
716
/**
717
* Content scaling options for images.
718
*/
719
object ContentScale {
720
val Crop: ContentScale
721
val Fit: ContentScale
722
val FillHeight: ContentScale
723
val FillWidth: ContentScale
724
val FillBounds: ContentScale
725
val Inside: ContentScale
726
val None: ContentScale
727
}
728
```
729
730
**Usage Examples:**
731
732
```kotlin
733
// Loading and displaying an image
734
val imageBitmap = remember { decodeImageFromByteArray(imageBytes) }
735
val painter = remember { BitmapPainter(imageBitmap) }
736
737
// Using the painter in composables
738
Image(
739
painter = painter,
740
contentDescription = "Sample image",
741
modifier = Modifier.size(200.dp),
742
contentScale = ContentScale.Crop
743
)
744
745
// Custom drawing with ImageBitmap
746
Canvas(modifier = Modifier.size(200.dp)) { canvas ->
747
canvas.drawImage(
748
image = imageBitmap,
749
topLeft = Offset(10.0f, 10.0f)
750
)
751
752
// Draw subsection of image
753
canvas.drawImageRect(
754
image = imageBitmap,
755
srcOffset = IntOffset(0, 0),
756
srcSize = IntSize(100, 100),
757
dstOffset = IntOffset(50, 50),
758
dstSize = IntSize(100, 100)
759
)
760
}
761
```
762
763
### Blend Modes and Effects
764
765
Advanced compositing and blending operations for creating sophisticated visual effects.
766
767
```kotlin { .api }
768
/**
769
* Algorithms to use when painting on the canvas.
770
*/
771
enum class BlendMode {
772
Clear, Src, Dst, SrcOver, DstOver, SrcIn, DstIn, SrcOut, DstOut,
773
SrcAtop, DstAtop, Xor, Plus, Modulate, Screen, Overlay, Darken,
774
Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference,
775
Exclusion, Multiply, Hue, Saturation, Color, Luminosity
776
}
777
778
/**
779
* Defines how a new pixel is merged with the existing pixel.
780
*/
781
class Paint {
782
/**
783
* Color used when drawing shapes.
784
*/
785
var color: Color
786
787
/**
788
* Alpha value for transparency.
789
*/
790
var alpha: Float
791
792
/**
793
* Blend mode to use when drawing.
794
*/
795
var blendMode: BlendMode
796
797
/**
798
* Drawing style (fill or stroke).
799
*/
800
var style: PaintingStyle
801
802
/**
803
* Stroke width for stroke style.
804
*/
805
var strokeWidth: Float
806
807
/**
808
* Color filter to apply.
809
*/
810
var colorFilter: ColorFilter?
811
812
/**
813
* Shader for custom paint effects.
814
*/
815
var shader: Shader?
816
817
/**
818
* Path effect for stroke modification.
819
*/
820
var pathEffect: PathEffect?
821
822
/**
823
* Antialiasing setting.
824
*/
825
var isAntiAlias: Boolean
826
827
/**
828
* Filter quality for image drawing.
829
*/
830
var filterQuality: FilterQuality
831
}
832
833
/**
834
* Color filters for modifying paint colors.
835
*/
836
abstract class ColorFilter {
837
companion object {
838
/**
839
* Create a tint color filter.
840
*/
841
fun tint(color: Color, blendMode: BlendMode = BlendMode.SrcIn): ColorFilter
842
843
/**
844
* Create a color matrix filter.
845
*/
846
fun colorMatrix(colorMatrix: ColorMatrix): ColorFilter
847
848
/**
849
* Create a lighting color filter.
850
*/
851
fun lighting(multiply: Color, add: Color): ColorFilter
852
}
853
}
854
```
855
856
**Usage Examples:**
857
858
```kotlin
859
// Using blend modes for special effects
860
Canvas(modifier = Modifier.size(200.dp)) { canvas ->
861
// Draw base layer
862
canvas.drawRect(
863
color = Color.Red,
864
size = Size(100.0f, 100.0f)
865
)
866
867
// Draw overlapping layer with blend mode
868
val paint = Paint().apply {
869
color = Color.Blue
870
blendMode = BlendMode.Multiply
871
}
872
873
canvas.drawRect(
874
color = Color.Blue,
875
topLeft = Offset(50.0f, 50.0f),
876
size = Size(100.0f, 100.0f)
877
)
878
}
879
880
// Using color filters
881
val tintedPaint = Paint().apply {
882
colorFilter = ColorFilter.tint(Color.Red, BlendMode.Modulate)
883
}
884
```