Skip to content

w3canvas/sharpcanvas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

191 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SharpCanvas

License: CC0

A comprehensive C# implementation of the HTML5 Canvas 2D rendering API with two production-ready backends: cross-platform SkiaSharp and Windows-native System.Drawing.

πŸš€ Features

  • ~95% Canvas API Coverage - Comprehensive implementation of the HTML5 Canvas 2D API (details)
  • Two Production Backends
    • SkiaSharp - Cross-platform (Windows, Linux, macOS), hardware-accelerated
    • System.Drawing - Windows-native GDI+, perfect for Windows-only applications
  • 100% Test Coverage - 258/258 tests passing (229 modern + 28 core + 1 standalone)
  • Backend-Agnostic Runtime - Workers, SharedWorkers, and Event Loops shared across all backends
  • WebAssembly Support - Run in browsers via Blazor WASM or headless with Wasmtime
  • Blazor Component - Ready-to-use interactive Canvas component for Blazor apps
  • JavaScript Interoperability - Full JavaScript integration via Microsoft.ClearScript V8
  • NativeAOT Ready - Experimental support for ahead-of-time compilation
  • Accessibility - Focus ring support for enhanced accessibility

πŸ“¦ Quick Start

Choosing a Backend

SharpCanvas provides two production-ready backends:

SkiaSharp (Recommended for most scenarios)

dotnet add package SharpCanvas.Context.Skia
  • βœ… Cross-platform (Windows, Linux, macOS)
  • βœ… Hardware-accelerated rendering
  • βœ… Active development and modern features
  • βœ… WebAssembly and Blazor support

System.Drawing (Windows-only)

dotnet add package SharpCanvas.Context.Drawing2D
  • βœ… Windows-native GDI+ integration
  • βœ… No external dependencies on Windows
  • βœ… Perfect for Windows-only applications
  • βœ… Backward compatibility - Potential support back to .NET Framework 4.x (2012+)
  • βœ… Familiar API for Windows developers

Basic Usage (SkiaSharp)

using SharpCanvas.Context.Skia;
using SkiaSharp;

// Create a surface
var info = new SKImageInfo(800, 600);
var surface = SKSurface.Create(info);

// Create a canvas context
var document = new Document(); // or your IDocument implementation
var context = new SkiaCanvasRenderingContext2D(surface, document);

// Draw something
context.fillStyle = "red";
context.fillRect(10, 10, 100, 100);

context.strokeStyle = "blue";
context.lineWidth = 5;
context.strokeRect(150, 10, 100, 100);

// Draw text
context.font = "24px Arial";
context.fillStyle = "black";
context.fillText("Hello, SharpCanvas!", 10, 150);

// Export to image
byte[] pngBytes = context.GetBitmap();

Advanced Example

// Gradients
var gradient = context.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, "red");
gradient.addColorStop(0.5, "yellow");
gradient.addColorStop(1, "green");
context.fillStyle = gradient;
context.fillRect(10, 200, 200, 50);

// Transformations
context.save();
context.translate(100, 100);
context.rotate(Math.PI / 4);
context.fillStyle = "purple";
context.fillRect(-25, -25, 50, 50);
context.restore();

// Paths
context.beginPath();
context.arc(300, 100, 50, 0, 2 * Math.PI);
context.fillStyle = "orange";
context.fill();
context.strokeStyle = "black";
context.lineWidth = 2;
context.stroke();

Basic Usage (System.Drawing)

using SharpCanvas.Legacy.Drawing.Context.Drawing2D;
using System.Drawing;

// Create a bitmap and graphics surface
var bitmap = new Bitmap(800, 600);
using var graphics = Graphics.FromImage(bitmap);

// Create a canvas context
var document = new Document(); // or your IDocument implementation
var context = new CanvasRenderingContext2D(graphics, bitmap);

// Draw something (same Canvas API!)
context.fillStyle = "red";
context.fillRect(10, 10, 100, 100);

context.strokeStyle = "blue";
context.lineWidth = 5;
context.strokeRect(150, 10, 100, 100);

// Draw text
context.font = "24px Arial";
context.fillStyle = "black";
context.fillText("Hello, SharpCanvas!", 10, 150);

// Save to file
bitmap.Save("output.png", System.Drawing.Imaging.ImageFormat.Png);

Note: Both backends use the same HTML5 Canvas API, so your code is portable between them!

🌐 WebAssembly and Blazor

SharpCanvas supports WebAssembly deployment for running .NET Canvas code in browsers and headless environments.

Blazor WebAssembly Component

Use SharpCanvas in Blazor WASM applications:

cd SharpCanvas.Blazor.Wasm
dotnet run

Then navigate to http://localhost:5233 to see the interactive demo with 4 rendering modes:

  • Basic shapes (rectangles, fills, strokes)
  • Gradients (linear and radial)
  • Paths (arcs, curves, bezier)
  • Text rendering

JavaScript Integration

SharpCanvas includes JavaScript engine integration via ClearScript V8:

cd SharpCanvas.JsHost
dotnet run

This runs comprehensive JavaScript-driven Canvas tests including:

  • Basic drawing operations
  • Path API (moveTo, lineTo, arc, curves)
  • Transformations (translate, rotate, scale)
  • Gradients and patterns
  • Text rendering

All tests generate PNG output files for validation.

Standalone WASM Execution

For headless WASM execution with Wasmtime (requires wasm-tools-net8 workload):

# Install Wasmtime
curl https://wasmtime.dev/install.sh -sSf | bash

# Build WASM console app
cd SharpCanvas.Wasm.Console
dotnet build

# Run with Wasmtime
wasmtime run bin/Debug/net8.0/browser-wasm/AppBundle/SharpCanvas.Wasm.Console.wasm

Note: See docs/WASM_DEPLOYMENT.md for comprehensive deployment instructions.

WASM Deployment Documentation

πŸ—οΈ Architecture

Project Structure

SharpCanvas/
β”œβ”€β”€ SharpCanvas.Core/              # Core interfaces and shared types
β”œβ”€β”€ SharpCanvas.Runtime/           # Backend-agnostic runtime (Workers, Event Loops) ✨ NEW
β”œβ”€β”€ Context.Skia/                  # SkiaSharp backend (cross-platform)
β”œβ”€β”€ Legacy/Drawing/
β”‚   └── Context.Drawing2D/         # System.Drawing backend (Windows GDI+)
β”œβ”€β”€ Context.WindowsMedia/          # WPF backend (Windows only, legacy)
β”œβ”€β”€ SharpCanvas.Tests/             # Test suites
β”‚   β”œβ”€β”€ Tests.Skia.Modern/        # Comprehensive tests (229 tests)
β”‚   β”œβ”€β”€ Tests.Skia/               # Core integration tests (28 tests)
β”‚   └── Tests.Skia.Standalone/    # Standalone integration tests (1 test)
β”œβ”€β”€ SharpCanvas.JsHost/            # JavaScript integration (ClearScript V8)
β”œβ”€β”€ SharpCanvas.Blazor.Wasm/       # Blazor WebAssembly component
β”œβ”€β”€ SharpCanvas.Wasm.Console/      # Standalone WASM console app (Wasmtime)
└── SharpCanvas.Wasm.NativeAOT/    # Experimental NativeAOT project (opt-in)

Backend Comparison

Feature SkiaSharp System.Drawing
Platforms βœ… Windows, Linux, macOS ⚠️ Windows only
Performance ⚑ Hardware-accelerated 🎨 Software rendering (GDI+)
API Completeness βœ… 100% Canvas 2D API βœ… 100% Canvas 2D API
Compilation βœ… 100% (0 errors) βœ… 100% (0 errors)
Tests βœ… 258/258 passing (100%) βœ… Compiles, tests available
WASM Support βœ… Blazor + Wasmtime ❌ N/A (requires Windows APIs)
JavaScript Integration βœ… ClearScript V8 βœ… ClearScript V8
Dependencies SkiaSharp NuGet System.Drawing (built-in)
Framework Support .NET Standard 2.0+ / .NET 8.0+ .NET 8.0+ (Windows)
Best For Cross-platform, modern apps Windows desktop/server, legacy .NET
Status βœ… Production Ready βœ… Production Ready

πŸ“– Documentation

Core Documentation

Key Features

  • Backend-Agnostic Runtime - Workers and SharedWorkers work with all backends
  • Conditional Compilation - Build Skia or System.Drawing targets separately
  • Testing Coverage - 258 tests validate both backends automatically
  • Zero Code Duplication - ~2000 lines of runtime code shared between backends

πŸ“š API Documentation

Core Canvas API

SharpCanvas implements the full HTML5 Canvas 2D API:

Drawing Rectangles

  • fillRect(x, y, width, height) - Draw filled rectangle
  • strokeRect(x, y, width, height) - Draw rectangle outline
  • clearRect(x, y, width, height) - Clear rectangle area

Paths

  • beginPath() - Start new path
  • closePath() - Close current path
  • moveTo(x, y) - Move to point
  • lineTo(x, y) - Line to point
  • arc(x, y, radius, startAngle, endAngle, anticlockwise) - Draw arc
  • arcTo(x1, y1, x2, y2, radius) - Arc to point
  • quadraticCurveTo(cpx, cpy, x, y) - Quadratic curve
  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) - Bezier curve
  • ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) - Draw ellipse
  • rect(x, y, width, height) - Add rectangle to path
  • roundRect(x, y, width, height, radii) - Add rounded rectangle

Drawing Paths

  • fill() / fill(path) - Fill current path or Path2D object
  • stroke() / stroke(path) - Stroke current path or Path2D object
  • clip() / clip(path) - Set clipping region

Text

  • fillText(text, x, y) - Draw filled text
  • strokeText(text, x, y) - Draw text outline
  • measureText(text) - Measure text dimensions

Images

  • drawImage(image, dx, dy) - Draw image
  • drawImage(image, dx, dy, dWidth, dHeight) - Draw scaled image
  • drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) - Draw image slice

Transformations

  • translate(x, y) - Translate origin
  • rotate(angle) - Rotate coordinate system
  • scale(x, y) - Scale coordinate system
  • transform(a, b, c, d, e, f) - Apply transformation matrix
  • setTransform(a, b, c, d, e, f) - Set transformation matrix
  • getTransform() - Get current transformation
  • resetTransform() - Reset to identity matrix

State Management

  • save() - Save current state
  • restore() - Restore previous state
  • reset() - Reset to default state

Styles

  • fillStyle - Fill color, gradient, or pattern
  • strokeStyle - Stroke color, gradient, or pattern
  • lineWidth - Line width
  • lineCap - Line cap style ("butt", "round", "square")
  • lineJoin - Line join style ("miter", "round", "bevel")
  • miterLimit - Miter limit
  • setLineDash(segments) - Set line dash pattern
  • getLineDash() - Get line dash pattern
  • lineDashOffset - Dash offset

Shadows

  • shadowColor - Shadow color
  • shadowBlur - Shadow blur radius
  • shadowOffsetX - Shadow X offset
  • shadowOffsetY - Shadow Y offset

Compositing

  • globalAlpha - Global transparency (0.0 - 1.0)
  • globalCompositeOperation - Compositing mode

Gradients and Patterns

  • createLinearGradient(x0, y0, x1, y1) - Create linear gradient
  • createRadialGradient(x0, y0, r0, x1, y1, r1) - Create radial gradient
  • createConicGradient(startAngle, x, y) - Create conic gradient
  • createPattern(image, repetition) - Create pattern

Image Data

  • getImageData(sx, sy, sw, sh) - Get pixel data
  • putImageData(imageData, dx, dy) - Put pixel data
  • createImageData(width, height) - Create blank image data

Context State

  • isContextLost() - Check if context is lost
  • getContextAttributes() - Get context attributes

Accessibility

  • drawFocusIfNeeded(element) - Draw focus ring if element focused

Properties

  • font - Text font
  • textAlign - Text alignment ("start", "end", "left", "right", "center")
  • textBaseLine - Text baseline
  • direction - Text direction ("ltr", "rtl")
  • imageSmoothingEnabled - Enable/disable image smoothing
  • imageSmoothingQuality - Image smoothing quality

πŸ§ͺ Testing

Running Tests

# Run all tests
dotnet test

# Run modern backend tests only
dotnet test SharpCanvas.Tests/Tests.Skia.Modern/

# Run unified tests (cross-backend)
dotnet test SharpCanvas.Tests/Tests.Unified/

# Run with detailed output
dotnet test --verbosity detailed

Test Coverage

  • Modern Backend: 230/230 tests passing (100%)
  • Standalone Tests: 1/1 tests passing (100%)
  • Core Tests: 28/28 tests passing (100%)
  • Windows-specific Tests: 28/28 tests passing (100%)
  • Total: 258/258 tests passing (100%)

All tests pass successfully, including:

  • All bezier curve and path operations
  • All composite operations and blend modes
  • All filter effects and combinations
  • All transformation scenarios
  • Workers and SharedWorker tests
  • ImageBitmap and OffscreenCanvas tests

πŸ› οΈ Building from Source

Prerequisites

  • .NET SDK 8.0 or later (verified on .NET 8, 9, and 10)
  • SkiaSharp (automatically restored via NuGet)

Build Steps

# Clone the repository
git clone https://github.com/w3canvas/sharpcanvas.git
cd sharpcanvas

# Restore dependencies
dotnet restore

# Build the solution
dotnet build

# Run tests
dotnet test

Building in Claude Code Web

If you encounter NuGet proxy authentication issues in Claude Code Web, use the provided proxy:

# Start the NuGet proxy
python3 .claude/nuget-proxy.py > /tmp/nuget_proxy.log 2>&1 &

# Set proxy environment variables
export all_proxy=http://127.0.0.1:8889
export ALL_PROXY=http://127.0.0.1:8889
export http_proxy=http://127.0.0.1:8889
export HTTP_PROXY=http://127.0.0.1:8889
export https_proxy=http://127.0.0.1:8889
export HTTPS_PROXY=http://127.0.0.1:8889

# Now build normally
dotnet restore
dotnet build

See .claude/NUGET_PROXY_README.md for details.

πŸ“– Documentation

Core Documentation

WebAssembly and Blazor Documentation

🎯 Production Readiness

Both SharpCanvas backends are production-ready!

βœ… SkiaSharp Backend (Cross-Platform)

Status: Production Ready - Recommended for most scenarios

Fully Implemented:

  • βœ… Complete HTML5 Canvas 2D API
  • βœ… All transformation operations
  • βœ… Gradients and patterns (linear, radial, conic)
  • βœ… Shadow effects
  • βœ… Image data manipulation
  • βœ… All compositing operations (25+ blend modes)
  • βœ… Complete filter support (10 CSS filter functions)
  • βœ… Accessibility features (drawFocusIfNeeded)
  • βœ… Workers and SharedWorker support
  • βœ… ImageBitmap and OffscreenCanvas
  • βœ… Path2D reusable paths
  • βœ… 258/258 tests passing (100%)
  • βœ… WebAssembly/Blazor deployment
  • βœ… JavaScript integration via ClearScript V8

Platforms: Windows, Linux, macOS

βœ… System.Drawing Backend (Windows-Native)

Status: Production Ready - Perfect for Windows-only applications

Fully Implemented:

  • βœ… Complete HTML5 Canvas 2D API
  • βœ… All path operations (beginPath, moveTo, lineTo, arc, bezierCurveTo, etc.)
  • βœ… Rectangle operations (fillRect, strokeRect, clearRect)
  • βœ… Text rendering with font parsing
  • βœ… Transformations (translate, rotate, scale)
  • βœ… Gradients and patterns
  • βœ… State management (save/restore)
  • βœ… 100% compilation (0 errors)
  • βœ… JavaScript integration via ClearScript V8

Platforms: Windows only (GDI+)

πŸ”œ Optional Future Enhancements

  • NativeAOT optimization testing
  • Performance profiling for very large canvases
  • Additional SVG path parsing features
  • WASM deployment optimization

🀝 Contributing

Contributions are welcome! Please feel free to submit pull requests.

Areas for Contribution

See Roadmap for detailed contribution opportunities.

High-impact areas:

  1. Examples and Samples - Real-world usage examples, tutorials, and demos
  2. Performance - Profile and optimize rendering for complex scenes
  3. Documentation - Additional examples, translations, quick-start guides
  4. Platform Testing - Test and optimize on different platforms (Linux, macOS, Windows)
  5. Developer Tools - Visual debuggers, profilers, and utilities
  6. WASM Optimization - Improve WebAssembly package sizes and performance
  7. NativeAOT Testing - Validate and optimize ahead-of-time compilation

Current Status:

  • βœ… SkiaSharp backend - Feature-complete, 100% tested
  • βœ… System.Drawing backend - Feature-complete, fully implemented
  • βœ… WASM deployment - Verified for .NET 8, 9, and 10
  • βœ… NativeAOT - Verified for .NET 8, 9, and 10

Focus contributions on enhancements, tooling, examples, and deployment optimizations.

πŸ“„ License

Unless otherwise noted, all source code and documentation is released into the public domain under CC0.

For questions about licensing, please contact:

  • w3canvas at jumis.com

πŸ™ Credits

Developed by Jumis, Inc. and contributors.

Based on the HTML5 Canvas specification:

πŸ“ž Support

About

SharpCanvas is an implementation of HTML5 Canvas written in C# for .Net Environments

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors