Pro Canvas Design Tool Suite
Professional-grade skill designed for create visual art in PNG and PDF formats. Built for Claude Code with best practices and real-world patterns.
Canvas Design Tool Suite
Full-featured HTML5 Canvas design toolkit for building interactive graphics editors, image manipulation tools, drawing applications, and visual design systems using Canvas API and WebGL.
When to Use This Skill
Choose Canvas Design Tool when:
- Building interactive image editors or drawing tools
- Creating custom canvas-based UI components
- Implementing image filters, transformations, and effects
- Building annotation or markup tools for web applications
- Creating games or interactive visual experiences
Consider alternatives when:
- Need vector graphics — use SVG or a library like Paper.js
- Need 3D rendering — use Three.js or WebGL directly
- Need print-quality output — use PDF generation libraries
Quick Start
# Activate canvas design tool claude skill activate pro-canvas-design-tool-suite # Build a drawing tool claude "Build a canvas-based drawing tool with brush, eraser, and shape tools" # Create an image editor claude "Create a canvas image editor with crop, rotate, and filter capabilities"
Example: Interactive Drawing Canvas
class DrawingCanvas { private canvas: HTMLCanvasElement; private ctx: CanvasRenderingContext2D; private isDrawing = false; private lastPoint: { x: number; y: number } | null = null; private tool: 'brush' | 'eraser' | 'line' | 'rect' = 'brush'; private color = '#000000'; private lineWidth = 3; private history: ImageData[] = []; private historyIndex = -1; constructor(container: HTMLElement, width: number, height: number) { this.canvas = document.createElement('canvas'); this.canvas.width = width; this.canvas.height = height; this.ctx = this.canvas.getContext('2d')!; container.appendChild(this.canvas); this.setupEvents(); this.saveState(); } private setupEvents() { this.canvas.addEventListener('pointerdown', (e) => { this.isDrawing = true; this.lastPoint = this.getPoint(e); this.ctx.beginPath(); this.ctx.moveTo(this.lastPoint.x, this.lastPoint.y); }); this.canvas.addEventListener('pointermove', (e) => { if (!this.isDrawing || !this.lastPoint) return; const point = this.getPoint(e); this.ctx.strokeStyle = this.tool === 'eraser' ? '#ffffff' : this.color; this.ctx.lineWidth = this.lineWidth; this.ctx.lineCap = 'round'; this.ctx.lineJoin = 'round'; this.ctx.lineTo(point.x, point.y); this.ctx.stroke(); this.lastPoint = point; }); this.canvas.addEventListener('pointerup', () => { this.isDrawing = false; this.lastPoint = null; this.saveState(); }); } private getPoint(e: PointerEvent) { const rect = this.canvas.getBoundingClientRect(); return { x: (e.clientX - rect.left) * (this.canvas.width / rect.width), y: (e.clientY - rect.top) * (this.canvas.height / rect.height), }; } saveState() { this.historyIndex++; this.history = this.history.slice(0, this.historyIndex); this.history.push(this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height)); } undo() { if (this.historyIndex > 0) { this.historyIndex--; this.ctx.putImageData(this.history[this.historyIndex], 0, 0); } } redo() { if (this.historyIndex < this.history.length - 1) { this.historyIndex++; this.ctx.putImageData(this.history[this.historyIndex], 0, 0); } } }
Core Concepts
Canvas API Categories
| Category | Methods | Use Case |
|---|---|---|
| Drawing | fillRect, strokeRect, arc, bezierCurveTo | Shapes and paths |
| Text | fillText, strokeText, measureText | Text rendering |
| Images | drawImage, getImageData, putImageData | Image manipulation |
| Transforms | translate, rotate, scale, transform | Positioning and rotation |
| Compositing | globalCompositeOperation, globalAlpha | Blending and layering |
| Clipping | clip, save, restore | Masked rendering |
| Gradients | createLinearGradient, createRadialGradient | Color gradients |
| Patterns | createPattern | Repeating textures |
Image Filters
| Filter | Description | Implementation |
|---|---|---|
| Grayscale | Convert to grayscale | (r + g + b) / 3 per pixel |
| Brightness | Adjust brightness | Add/subtract constant per channel |
| Contrast | Adjust contrast | ((value - 128) * factor) + 128 |
| Blur | Gaussian blur | Convolution kernel averaging |
| Sharpen | Enhance edges | Convolution with center-weighted kernel |
| Sepia | Vintage warm tone | Matrix transformation on RGB |
| Invert | Color inversion | 255 - value per channel |
// Image filter implementation function applyFilter(ctx: CanvasRenderingContext2D, filter: string) { const { width, height } = ctx.canvas; const imageData = ctx.getImageData(0, 0, width, height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { const r = data[i], g = data[i+1], b = data[i+2]; switch (filter) { case 'grayscale': const gray = 0.299 * r + 0.587 * g + 0.114 * b; data[i] = data[i+1] = data[i+2] = gray; break; case 'sepia': data[i] = Math.min(255, r * 0.393 + g * 0.769 + b * 0.189); data[i+1] = Math.min(255, r * 0.349 + g * 0.686 + b * 0.168); data[i+2] = Math.min(255, r * 0.272 + g * 0.534 + b * 0.131); break; case 'invert': data[i] = 255 - r; data[i+1] = 255 - g; data[i+2] = 255 - b; break; } } ctx.putImageData(imageData, 0, 0); }
Configuration
| Parameter | Description | Default |
|---|---|---|
canvas_width | Canvas width in pixels | 800 |
canvas_height | Canvas height in pixels | 600 |
background | Background color | #ffffff |
default_tool | Initial active tool | brush |
max_history | Maximum undo history states | 50 |
export_quality | JPEG export quality (0-1) | 0.92 |
pixel_ratio | Device pixel ratio for HiDPI | window.devicePixelRatio |
smoothing | Image smoothing enabled | true |
Best Practices
-
Handle device pixel ratio for sharp rendering on HiDPI displays — Scale the canvas backing store by
devicePixelRatiowhile keeping CSS size unchanged. Without this, canvas content appears blurry on retina displays:canvas.width = cssWidth * dpr; canvas.style.width = cssWidth + 'px'. -
Use offscreen canvases for complex compositing — Render layers, filters, and temporary drawings on offscreen canvases, then composite them onto the main canvas. This enables non-destructive editing and layer-based workflows.
-
Implement efficient undo/redo with state snapshots — Store
ImageDatasnapshots for simple editors, but for complex editors with many objects, store command objects (command pattern) that can be applied or reversed without storing full pixel data. -
Throttle rendering to requestAnimationFrame — Never render on every mouse event. Batch drawing operations into
requestAnimationFramecallbacks to maintain 60fps smoothness and prevent janky, dropped-frame behavior. -
Use pointer events instead of mouse events — Pointer events handle mouse, touch, and stylus input uniformly. They also provide pressure sensitivity data for stylus-aware drawing applications and handle multi-touch gestures naturally.
Common Issues
Canvas appears blurry on high-DPI (retina) displays. The canvas element's internal resolution defaults to CSS pixels, not device pixels. Set canvas.width = displayWidth * devicePixelRatio and ctx.scale(devicePixelRatio, devicePixelRatio) while keeping CSS dimensions at the display size.
Memory usage grows unbounded with undo history. Each ImageData snapshot for a 1920x1080 canvas is ~8MB. Limit history depth to 30-50 states, or compress older states to PNG blobs (via canvas.toBlob()) which are 10-50x smaller. For production editors, use delta encoding that stores only changed regions.
Touch drawing is laggy compared to mouse drawing. Touch events fire at lower frequency than mouse events on many devices. Use PointerEvent.getCoalescedEvents() to access all intermediate points between event firings, then draw smooth curves through all points for responsive, gap-free strokes.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.