A minimalist creative-coding toolkit for Python (homage to Processing/p5).
Project description
kanvas
A minimalist creative-coding toolkit for Python, inspired by Processing and p5.js.
Overview
kanvas provides a simple, educational framework for creative coding in Python. It captures the essence of Processing's setup() and draw() paradigm while maintaining a clean, readable codebase that's perfect for learning how creative coding frameworks work under the hood.
Key Features:
- Simple setup/draw loop similar to Processing
- Built on pygame for reliable cross-platform support
- Clean separation of concerns (model-view-controller architecture)
- Lightweight and hackable (~200 lines of core code)
- Beginner-friendly API with educational focus
Installation
Requirements
- Python 3.9 or higher
- pygame 2.0+
- numpy 1.23+
Install from source
git clone https://github.com/robinoscarsson/kanvas.git
cd kanvas
pip install -e .
Quick Start
from kanvas.core import run
def setup(model):
"""Called once at startup"""
model.clear(30) # Set background to gray
def draw(model, frame, dt):
"""Called every frame"""
x = (frame // 2) % model.w
for y in range(model.h):
model.pixel(x, y, 255, 255, 255)
# Run the sketch
run(setup, draw, size=(800, 600), title="My First Sketch")
Save this as sketch.py and run with:
python sketch.py
Press ESC to quit or close the window.
Examples
Check out the examples/ directory for more demonstrations:
Serpinski Triangle
Fractal generation using the chaos game method.
# Run with: python examples/serpinski_triangle.py
Ulam Spiral
Prime number visualization in spiral form - a beautiful mathematical pattern where prime numbers create distinctive diagonal structures.
# Run with: python examples/ulam_sprial.py
API Reference
Core Functions
run(setup_func, draw_func, **kwargs)
Main entry point to start a kanvas sketch.
Parameters:
setup_func: Function called once at startup, receivesmodelparameterdraw_func: Function called every frame, receivesmodel,frame, anddtparameterssize: Tuple of (width, height) for window size (default: (640, 360))title: Window title string (default: "kanvas")target_fps: Target frames per second (default: 60)
Model API
The model object provides the drawing surface:
model.pixel(x, y, r, g, b)
Set a pixel at coordinates (x, y) to RGB color (r, g, b).
model.clear(gray_value)
Clear the entire canvas to a grayscale value (0-255).
Properties
model.w: Canvas width in pixelsmodel.h: Canvas height in pixels
Controls
- ESC: Quit the application
- S: Save current frame as PNG image
Architecture
kanvas follows a clean MVC architecture:
src/kanvas/
├── core.py # Main application loop and coordination
├── controller.py # Input handling (keyboard, mouse, window events)
├── view.py # Rendering and window management (pygame)
├── model.py # Canvas state and pixel operations
└── utils.py # Utility functions
Philosophy
kanvas is designed for learning by doing. The entire codebase is intentionally simple and readable, making it easy to understand how creative coding frameworks work internally. There's no magic - you can trace every function call from user input to pixel output.
This makes kanvas ideal for:
- Learning creative coding concepts
- Understanding game loop architecture
- Teaching graphics programming
- Rapid prototyping of visual ideas
- Educational workshops and tutorials
Contributing
This is primarily an educational project, but contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with clear commit messages
- Submit a pull request
Roadmap
- Basic shape primitives (line, circle, rectangle)
- Color management system
- Mouse and keyboard input handling
- Transformation matrix support
- Image export utilities
- Animation recording
License
MIT License. See LICENSE for details.
Acknowledgments
- Inspired by Processing and p5.js
- Built with pygame
- Created for educational purposes and creative exploration
🎨 Overview
kanvas aims to capture the feel of Processing:
setup() runs once, draw() runs every frame, and the rest is up to you.
Under the hood it uses pygame for the window and rendering, and a small core loop written to be readable, hackable, and educational.
The goal isn’t performance or feature parity — it’s understanding.
If you’ve ever wondered “how would I build p5 myself?”, this is that journey.
⚙️ Installation
Clone the repository and install it locally in editable mode:
git clone https://github.com/yourname/kanvas.git
cd kanvas
pip install -e .
kanvas requires Python 3.9+ and pygame (automatically installed via pip).
🚀 Quick Start
Create a new Python file, for example example.py:
from kanvas import run
def setup(model):
model.clear(30) # background gray
def draw(model, frame, dt):
x = (frame // 2) % model.w
for y in range(model.h):
model.pixel(x, y, 255, 255, 255)
run(setup, draw, size=(320, 200), title="kanvas Example")
Then run it:
python example.py
A small window should appear with a white line sweeping across the screen.
Press ESC or click the X to quit.
🧩 Project Structure
src/kanvas/
├── core.py # Main loop orchestration
├── controller.py # Handles input (ESC / window close)
├── view.py # Pygame window and rendering
├── model.py # Framebuffer and pixel operations
└── __init__.py
examples/
└── pixelsmoke.py # Simple demonstration sketch
✨ Features (so far)
- Minimal setup/draw loop
- Clean separation of core / view / controller / model
- ESC and window close handling
- Simple pixel drawing via NumPy framebuffer
- Beginner-friendly codebase (~200 lines total)
🧠 Philosophy
kanvas exists to learn by building.
Every function is deliberately simple and explicit. There’s no magic, no global state, and no framework hiding the logic from you.
You can trace the entire rendering path from run() → controller.handle_input() → model.pixel() → view.present_framebuffer() in less than a minute.
If you’re curious about:
- How Processing or p5’s loop actually works
- How to handle events and rendering cleanly in Python
- Or just want a compact sandbox for creative-coding ideas
…this project might make you happy.
🧩 Roadmap (subject to whim)
- Basic shape primitives (
line,circle,rect) -
background(),fill(),stroke()API layer - Mouse position and keyboard input
- Higher-level color & transformation helpers
- Export to image / animation
This is a hobby project, not a product. Expect it to evolve (and break) as it grows.
❤️ Acknowledgements
- Inspired by Processing and p5.js
- Built with pygame
- Written out of pure curiosity and love for creative coding.
📄 License
MIT License — do whatever you want, but if you learn something, pass it on.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kanvas-0.1.2.tar.gz.
File metadata
- Download URL: kanvas-0.1.2.tar.gz
- Upload date:
- Size: 11.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7243fd419d58fa084a2ca0daa2018c8ae03a438fe44e41118e74885cc5a3799
|
|
| MD5 |
f354b315cdb38786f62fd85b6f47a50f
|
|
| BLAKE2b-256 |
6a43ee3549ff882d93e21659864dd4653923e90a97a3fe7f5a9142d942cc773a
|
File details
Details for the file kanvas-0.1.2-py3-none-any.whl.
File metadata
- Download URL: kanvas-0.1.2-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
decc8a0564f9a436a1a12c8c5e7d7493d9ae69689b519df6ec75adfaa9ac9f2e
|
|
| MD5 |
8b97a98c0ca7ed012231eeee007402a1
|
|
| BLAKE2b-256 |
0b3fdb0196f035c785fd4995ad10c4ff2afd0cc9c04de842b96d664605ff684d
|