1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
# Patterns and Gradients
_New in [:octicons-tag-24: 2.8.3](https://github.com/py-pdf/fpdf2/blob/master/CHANGELOG.md)_
## Overview
In PDF (Portable Document Format), a **pattern** is a graphical object that can be used to fill (or stroke) shapes. Patterns can include simple color fills, images, or more advanced textures and gradients.
The **patterns** on PDF documents are grouped on 2 types:
- **Tiling patterns** for any repeating patters.
- **Shading patterns** for gradients.
*fpdf2* provides a context manager `pdf.use_pattern(...)`. Within this context, all drawn shapes or text will use the specified pattern. Once the context ends, drawing reverts to the previously defined color.
**At this moment, tiling patterns are not yet supported by `fpdf2`**.
## 2. Gradients
### 2.1 What is a Gradient?
A **gradient** is a progressive blend between two or more colors. In PDF terms, gradients are implemented as *shading patterns*—they allow a smooth color transition based on geometry.
### 2.2 Linear Gradients (axial shading)
A **linear gradient** blends colors along a straight line between two points. For instance, you can define a gradient that goes:
- Left to right
- Top to bottom
- Diagonally
or in any arbitrary orientation by specifying coordinates.
**Example: Creating a Linear Gradient**
```python
from fpdf import FPDF
from fpdf.pattern import LinearGradient
pdf = FPDF()
pdf.add_page()
# Define a linear gradient
linear_grad = LinearGradient(
pdf,
from_x=10, # Starting x-coordinate
from_y=0, # Starting y-coordinate
to_x=100, # Ending x-coordinate
to_y=0, # Ending y-coordinate
colors=["#C33764", "#1D2671"] # Start -> End color
)
with pdf.use_pattern(linear_grad):
# Draw a rectangle that will be filled with the gradient
pdf.rect(x=10, y=10, w=100, h=20, style="FD")
pdf.output("pattern_linear_demo.pdf")
```
Result: [pattern_linear_demo.pdf](./pattern_linear_demo.pdf)
**Key Parameters**:
- **from_x, from_y, to_x, to_y**: The coordinates defining the line along which colors will blend.
- **colors**: A list of colors (hex strings or (R,G,B) tuples). The pattern will interpolate between these colors.
### 2.3 Radial Gradients
A **radial gradient** blends colors in a circular or elliptical manner from an inner circle to an outer circle. This is perfect for spotlight-like effects or circular color transitions.
**Example: Creating a Radial Gradient**
```python
from fpdf import FPDF
from fpdf.pattern import RadialGradient
pdf = FPDF()
pdf.add_page()
# Define a radial gradient
radial_grad = RadialGradient(
pdf,
start_circle_x=30, # Center X of inner circle
start_circle_y=30, # Center Y of inner circle
start_circle_radius=0, # Radius of inner circle
end_circle_x=50, # Center X of outer circle
end_circle_y=50, # Center Y of outer circle
end_circle_radius=25, # Radius of outer circle
colors=["#FFFF00", "#FF0000"], # Inner -> Outer color
)
with pdf.use_pattern(radial_grad):
# Draw a circle filled with the radial gradient
pdf.circle(x=50, y=50, radius=25, style="FD")
pdf.output("pattern_radial_demo.pdf")
```
Result: [pattern_radial_demo.pdf](./pattern_radial_demo.pdf)
**Key Parameters**:
- **start_circle_x, start_circle_y, start_circle_radius**: Center and radius of the inner circle.
- **end_circle_x, end_circle_y, end_circle_radius**: Center and radius of the outer circle.
- **colors**: A list of colors to be interpolated from inner circle to outer circle.
## 4. Advanced Usage
### 4.1 Multiple Colors
Both linear and radial gradients support **multiple colors**. If you pass, for example, `colors=["#C33764", "#1D2671", "#FFA500"]`, the resulting pattern will interpolate color transitions through each color in that order.
### 4.2 Extending & Background for Linear Gradients
- **extend_before**: Extends the first color before the starting point (i.e., `x1,y1`).
- **extend_after**: Extends the last color beyond the end point (i.e., `x2,y2`).
- **background**: Ensures that if any area is uncovered by the gradient (e.g., a rectangle that is bigger than the gradient line), it’ll show the given background color.
### 4.3 Custom Bounds
For **linear gradients** or **radial gradients**, passing `bounds=[0.2, 0.4, 0.7, ...]` (values between 0 and 1) fine-tunes where each color transition occurs. For instance, if you have 5 colors, you can specify 3 boundary values that partition the color progression among them.
For example, taking a gradient with 5 colors and `bounds=[0.1, 0.8, 0.9]`:
- The transition from color 1 to color 2 starts at the beginning (0%) and ends at 10%
- The transition from color 2 to color 3 starts at 10% and ends at 80%
- The transition from color 3 to color 4 starts at 80% and ends at 90%
- The transition from color 4 to color 5 starts at 90% and goes to the end (100%)
In other words, each boundary value dictates where the color transitions will occur along the total gradient length.
|