@@ -7,20 +7,22 @@ This section defines the core interfaces and type signatures that must be implem
77### Color Format Support
88
99Colors can be specified in multiple formats:
10+
1011- Hex string: ` "#FF5733" ` or ` "#FF5733AA" ` (with alpha)
1112- RGB tuple: ` (255, 87, 51) `
1213- RGBA tuple: ` (255, 87, 51, 255) `
1314
1415### Position Format Support
1516
1617Positions can be specified as:
18+
1719- Pixels: ` 100 `
1820- Percentage: ` "50%" `
1921
20-
2122## Design Overview
2223
2324### Core Principles
25+
2426- ** Required params upfront** : ` Canvas(width, height) ` or ` Canvas.from_aspect_ratio(ratio) ` or ` Canvas.from_json() `
2527- ** Typed methods without prefixes** : ` .text() ` , ` .background() ` , ` .outline() ` - call multiple times for layers
2628- ** Method chaining** : All layer methods return ` self ` for fluent API (e.g., ` canvas.background().text() ` )
@@ -53,6 +55,29 @@ canvas.text(
5355 italic = False ,
5456 max_width = None , # For word wrapping
5557 effects = None , # list of effect objects (Stroke, Shadow, Glow, etc.)
58+ background_color = None , # Hex string for text background
59+ padding = None , # int or (horizontal, vertical) tuple
60+ border_radius = None , # int for rounded background corners
61+ )
62+
63+ # Text with background (Badge style)
64+ canvas.text(
65+ content = " 20:19" ,
66+ size = 30 ,
67+ color = " #FFFFFF" ,
68+ background_color = " #000000" ,
69+ padding = (15 , 8 ),
70+ border_radius = 10 ,
71+ )
72+
73+ # Image layers (Overlay images/logos)
74+ canvas.image(
75+ path = " assets/logo.png" , # Local path or URL
76+ position = (50 , 50 ),
77+ width = 200 , # width or height (preserves aspect ratio if one is None)
78+ opacity = 1.0 ,
79+ rotation = 0 , # Degrees
80+ align = (" top" , " left" )
5681)
5782
5883# Text with effects using effect classes
@@ -77,6 +102,7 @@ canvas.text(
77102)
78103
79104# Decoration layers
105+ canvas.image(path = " logo.png" , position = (20 , 20 ), width = 100 )
80106canvas.outline(width = 5 , color = " #000000" , offset = 10 )
81107
82108# Render
@@ -105,7 +131,10 @@ json_str = canvas.to_json() # Export canvas to JSON string
105131 "gradient" : {
106132 "type" : " linear" ,
107133 "angle" : 45 ,
108- "stops" : [[" #FF5733" , 0.0 ], [" #3333FF" , 1.0 ]]
134+ "stops" : [
135+ [" #FF5733" , 0.0 ],
136+ [" #3333FF" , 1.0 ]
137+ ]
109138 },
110139 "opacity" : 0.7 ,
111140 "blend_mode" : " multiply"
@@ -118,23 +147,36 @@ json_str = canvas.to_json() # Export canvas to JSON string
118147 "color" : " #FFFFFF" ,
119148 "align" : [" center" , " middle" ],
120149 "bold" : true ,
121- "effects" : [
122- {"type" : " stroke" , "width" : 3 , "color" : " #000000" }
123- ]
150+ "effects" : [{ "type" : " stroke" , "width" : 3 , "color" : " #000000" }],
151+ "background_color" : " #000000" ,
152+ "padding" : [10 , 5 ],
153+ "border_radius" : 5
154+ },
155+ {
156+ "type" : " image" ,
157+ "path" : " assets/logo.png" ,
158+ "position" : [50 , 50 ],
159+ "width" : 200 ,
160+ "opacity" : 1.0 ,
161+ "rotation" : 0
124162 },
125163 {
126164 "type" : " text" ,
127165 "content" : [
128- {"text" : " Hello " , "color" : " #FFFFFF" },
129- {"text" : " World" , "color" : " #FF0000" , "effects" : [{"type" : " stroke" , "width" : 2 , "color" : " #000000" }]}
166+ { "text" : " Hello " , "color" : " #FFFFFF" },
167+ {
168+ "text" : " World" ,
169+ "color" : " #FF0000" ,
170+ "effects" : [{ "type" : " stroke" , "width" : 2 , "color" : " #000000" }]
171+ }
130172 ],
131173 "size" : 72 ,
132- "effects" : [{"type" : " stroke" , "width" : 1 , "color" : " #000000" }]
174+ "effects" : [{ "type" : " stroke" , "width" : 1 , "color" : " #000000" }]
133175 },
134176 {
135177 "type" : " outline" ,
136178 "width" : 10 ,
137- "color" : " #FFFFFF" ,
179+ "color" : " #FFFFFF"
138180 }
139181 ]
140182}
@@ -188,7 +230,7 @@ assert recreated.to_json() == exported # Perfect round-trip
188230
189231### Helper Classes
190232
191- ``` python
233+ ```` python
192234from quickthumb import LinearGradient, RadialGradient, BlendMode, TextPart, Stroke
193235
194236# Gradients
@@ -207,14 +249,16 @@ BlendMode.LIGHTEN
207249Stroke(width = 3 , color = " #000000" )
208250
209251# Rich text parts (for partial text styling)
210- TextPart(
211- text = " Hello" ,
212- color = " #FF0000" , # optional, inherits from parent text layer
213- effects = None , # optional list of effect objects
214- )
215- ```
252+ TextPart(
253+ text = " Hello" ,
254+ color = " #FF0000" , # optional, inherits from parent text layer
255+ effects = None , # optional list of effect objects
256+ background_color = " #FFFF00" , # Highlight specific words
257+ padding = 5 ,
258+ )
259+ ```
216260
217- ### Text Effects
261+ # ## Text Effects
218262
219263Text layers support effects for enhanced visual styling using effect classes:
220264
@@ -236,9 +280,10 @@ canvas.text("Epic Title", size=96, color="#FFFFFF", effects=[
236280stroke_style = [Stroke(width = 3 , color = " #000000" )]
237281canvas.text(" Title 1" , size = 72 , effects = stroke_style)
238282canvas.text(" Title 2" , size = 60 , effects = stroke_style)
239- ```
283+ ````
240284
241285** Available Effects:**
286+
242287- `Stroke(width, color)` : Adds an outline around text
243288
244289# ## Rich Text (Partial Styling)
@@ -316,6 +361,7 @@ canvas.text(
316361# # Implementation Priority
317362
318363# ## Phase 1: Core (Minimum Viable)
364+
319365- Canvas creation (size + aspect ratio)
320366- Solid background
321367- Basic text (no stroke, center alignment)
@@ -324,25 +370,31 @@ canvas.text(
324370- Method chaining (all layer methods return `self ` )
325371
326372# ## Phase 2: Enhanced Backgrounds
373+
327374- Linear gradients
328375- Radial gradients
329376- Image backgrounds with fit modes
330377- Blend modes and opacity
331378
332379# ## Phase 3: Text Features
380+
333381- Text stroke/ outline
334382- Custom positioning
335383- Font loading and caching
336384- Bold/ italic variants
337385
338386# ## Phase 4: Decorations & Polish
387+
388+ - Image overlays (positioned images)
389+ - Text backgrounds (labels/ badges)
339390- Outline decoration
340391- JPEG / WebP output
341392- JSON operations (`from_json()` , `to_json()` )
342393- Comprehensive error messages
343394
344395# ## Phase 5: Text Effects
396+
345397- Effect classes (currently: `Stroke` )
346398- Effects list (`effects` parameter)
347399- Rich text with `TextPart` (partial text styling with effects support)
348- - Future: Additional effects like ` Shadow ` , ` Glow ` , etc.
400+ - Future: Additional effects like `Shadow` , `Glow` , etc.
0 commit comments