NLP2CMD supports automated drawing on HTML5 canvas applications like jspaint.app. This feature allows you to generate complex drawings through natural language commands.
# Draw a ladybug on jspaint
nlp2cmd -q "narysuj biedronkę na jspaint.app" --run --video output.webm
# Draw a simple circle
nlp2cmd -q "narysuj czerwone koło" --run
# Draw a cat with screenshot
nlp2cmd -q "narysuj kota" --run --screenshot
The following objects have built-in drawing blueprints:
| Object | Polish | English | Drawing Primitives |
|---|---|---|---|
| 🐞 Ladybug | biedronka | ladybug | circles, ellipses, dots |
| 🐱 Cat | kot, kicia | cat | bezier curves, ellipses |
| 🐕 Dog | pies | dog | circles, ellipses |
| 🐰 Rabbit | królik, zając | rabbit, bunny | ellipses, circles |
| 🏠 House | dom, domek | house | rectangles, triangles |
| 🚗 Car | auto, samochód | car | rectangles, circles (wheels) |
| 🌳 Tree | drzewo | tree | rectangles, circles |
| 🌻 Flower | kwiat, kwiatek | flower | circles, ellipses |
| ⭐ Star | gwiazda | star | polygon |
| ❤️ Heart | serce | heart | SVG path |
| 🌞 Sun | słońce | sun | circles, arcs |
| 🐟 Fish | ryba | fish | ellipses, curves |
| 🦋 Butterfly | motyl | butterfly | ellipses, lines |
| ⛄ Snowman | bałwan | snowman | circles |
Canvas workflows support the following actions:
# Set current color
- action: set_color
params:
color: "#FF0000" # Red
# Set line width
- action: set_line_width
params:
width: 3
# Draw filled ellipse
- action: draw_filled_ellipse
params:
rx: 50 # X radius
ry: 30 # Y radius
offset: [0, 0] # Offset from canvas center
# Draw filled circle
- action: draw_filled_circle
params:
radius: 40
offset: [20, -10]
# Draw circle (outline)
- action: draw_circle
params:
radius: 20
offset: [0, 0]
# Draw straight line
- action: draw_line
params:
from_offset: [0, 0]
to_offset: [50, 50]
# Draw bezier curve
- action: draw_bezier
params:
curves:
- type: M # Move to
x: 0
y: 0
- type: Q # Quadratic bezier
cpx: 25 # Control point X
cpy: -50 # Control point Y
x: 50 # End X
y: 0 # End Y
fill: false
close: false
# Draw arc
- action: draw_arc
params:
start_angle: 0
end_angle: 180
radius: 40
# Draw polygon (triangle, star, etc.)
- action: draw_polygon
params:
points:
- [0, -50] # Top
- [-40, 30] # Bottom left
- [40, 30] # Bottom right
fill: true
offset: [0, 0]
# Draw complex shapes using SVG path syntax
- action: draw_svg_path
params:
path: "M50,50 C20,20 80,20 50,50" # Heart shape
fill: true
# Wait for canvas to load
- action: wait_for_canvas
params: {}
# Get canvas center coordinates
- action: get_canvas_center
params: {}
# Click at position
- action: click_canvas
params:
offset: [10, 10]
# Fill area at position
- action: fill_at
params:
offset: [0, 0]
# Type text
- action: type_text
params:
text: "Hello"
# Take screenshot
- action: screenshot
params:
suffix: "final"
# Wait
- action: wait
params:
ms: 1000
The canvas automation uses JavaScript injected into the page for reliable drawing:
// Draw filled circle via Canvas 2D API
function drawFilledCircle(cx, cy, radius, color) {
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.save();
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
Available JS helpers:
_js_set_color(color_hex) - Select color in jspaint palette_js_select_tool(tool_name) - Select drawing tool_js_draw_filled_circle(cx, cy, radius, color) - Draw filled circle_js_draw_filled_ellipse(cx, cy, rx, ry, color) - Draw filled ellipse_js_draw_line(x1, y1, x2, y2, color, width) - Draw line_js_draw_polygon(points, color, width, fill) - Draw polygon_js_draw_bezier(commands, color, width, fill, close) - Draw bezier curvesnlp2cmd -q "narysuj biedronkę na jspaint.app" --run
Generated plan:
steps:
- action: navigate
params: {url: "https://jspaint.app"}
- action: wait_for_canvas
- action: get_canvas_center
- action: set_color
params: {color: "#FF0000"} # Red body
- action: draw_filled_ellipse
params: {rx: 60, ry: 80, offset: [0, 10]}
- action: set_color
params: {color: "#000000"} # Black head
- action: draw_filled_circle
params: {radius: 35, offset: [0, -60]}
- action: draw_filled_circle
params: {radius: 8, offset: [-20, 0]} # Dot
- action: draw_filled_circle
params: {radius: 8, offset: [20, 0]} # Dot
- action: draw_filled_circle
params: {radius: 8, offset: [0, 20]} # Dot
- action: screenshot
params: {suffix: "ladybug"}
nlp2cmd -q "narysuj kota na jspaint.app" --run --screenshot cat.png
# Record the drawing process
nlp2cmd -q "narysuj serce na jspaint.app" --run --video heart_drawing.webm
| Option | Description |
|---|---|
--run |
Execute the drawing in browser |
--screenshot [path] |
Save final screenshot |
--video [path] |
Record drawing process to video |
--duration [seconds] |
Video recording duration |
--log-dir [path] |
Save debug logs |
Run canvas-specific tests:
# Unit tests
pytest tests/unit/test_drawing_blueprints.py -v
# Canvas adapter tests
pytest tests/unit/test_automation.py::TestCanvasAdapter -v
# E2E tests (requires playwright)
pytest tests/e2e/test_canvas_e2e.py -v --tb=short
# Headless mode
HEADLESS=1 pytest tests/e2e/test_canvas_e2e.py -v
nlp2cmd -q "narysuj biedronkę"
↓
ActionPlanner.decompose_sync()
↓
Canvas blueprint lookup (drawing_blueprints.py)
↓
ActionPlan with canvas steps
↓
generate.py → Playwright execution
↓
JS helpers inject Canvas 2D API calls
↓
Screenshot/Video saved
--wait 5000_js_set_color() helperplaywright install chromiumBlueprints are defined in nlp2cmd/automation/drawing_blueprints.py:
OBJECT_BLUEPRINTS = [
{
"name": "ladybug",
"aliases": ["biedronka", "biedronkę", "ladybug"],
"steps_fn": lambda: [
ActionStep("set_color", {"color": "#FF0000"}),
ActionStep("draw_filled_ellipse", {"rx": 60, "ry": 80, "offset": [0, 10]}),
# ... more steps
],
},
]
drawing_blueprints.pytest_drawing_blueprints.py