High-Level Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The Rocreate project is a professional-grade painting application built with TypeScript that supports both standalone and embedded deployments. It utilizes a hybrid rendering approach, leveraging standard Canvas 2D for general UI and legacy operations, while integrating CanvasKit (Skia WASM) for high-performance, GPU-accelerated graphics rendering and compositing.
The architecture is centered around a controller-based pattern where KlApp orchestrates the interaction between the drawing canvas, history management, and the user interface. It employs a tile-based undo/redo system and persistent storage via IndexedDB to ensure robust performance and data reliability.
Sources: CLAUDE.md:5-10, src/app/script/app/kl-app.ts:47-55, prompt.md:10-15
System Overview
The application follows a modular structure where core logic is decoupled from low-level rendering kernels. The system is designed to handle complex creative workflows, including multi-layer management, advanced brush engines with pressure sensitivity, and WebGL-powered filters.
Core Architecture Components
| Component | Description | Primary File |
|---|---|---|
| KlApp | The central controller connecting UI, canvas, and history. | src/app/script/app/kl-app.ts |
| KlCanvas | Manages pixel data, layer stacks, and compositing operations. | src/app/script/klecks/canvas/kl-canvas.ts |
| Easel | Manages the viewport, zoom/pan, and tool interactions (brushes, shapes). | src/app/script/klecks/ui/easel/easel.ts |
| KlHistory | A tile-based undo/redo system storing efficient deltas. | src/app/script/klecks/history/ |
| CanvasKit | The GPU-accelerated rendering and compositing layer. | src/app/script/canvaskit/ |
Sources: CLAUDE.md:15-22, src/app/script/app/kl-app.ts:150-165
Component Interactions
The following diagram illustrates the high-level relationship between the main application controller and its primary subsystems during initialization and runtime.
The diagram shows the central role of KlApp in managing the flow between rendering, history, and the user interface.
Sources: CLAUDE.md:15-30, src/app/script/app/kl-app.ts:250-300
Data Flow and Input Processing
Input processing in Rocreate utilizes a chained event handler system to manage complex interactions like pointer and touch input. This system ensures that input is sanitized, smoothed, and correctly transformed before affecting the canvas state.
Input Event Chain
The application uses an EventChain to process drawing events through several stages:
- LineSanitizer: Cleans raw input data.
- AssistModeSanitizer: Applies perspective or symmetry constraints.
- LineSmoothing: Applies presets (Basic, StreamLine, Pulled String) to stabilize strokes.
This sequence demonstrates how user input is transformed into visual strokes through a series of sanitization and smoothing filters.
Sources: src/app/script/app/kl-app.ts:468-475, CLAUDE.md:33-35, src/app/script/klecks/ui/easel/easel.ts:430-450
Rendering and Compositing
Rocreate implements a two-pass rendering approach. The main project canvas handles the complex blending of multiple layers, while a separate layer is used for UI overlays, selections, and temporary drawing previews.
GPU Acceleration
The application attempts to initialize CanvasKit for GPU-accelerated compositing. If the WASM binary fails to load or the environment is unsupported, it falls back to a standard Canvas 2D compositor.
// Background loading of CanvasKit for GPU compositing
loadCanvasKit()
.then(() => {
console.log('[KlApp] CanvasKit GPU compositor ready');
})
.catch((e) => {
console.log('[KlApp] GPU compositing unavailable, using Canvas 2D fallback');
});
Sources: src/app/script/app/kl-app.ts:133-140, CLAUDE.md:16-22
Storage and Persistence
Persistence is handled primarily via IndexedDB through a ProjectStore and KlRecoveryManager. This allows for automatic recovery of work after crashes or accidental tab closures.
- Tile-based Storage: Project data is stored in fragments to minimize I/O overhead during saves.
- Recovery System:
KlRecoveryManagertracks the current state and provides recovery options upon application restart. - Serialization: Projects are converted to a storage-friendly format (Blobs) before being persisted in IndexedDB.
Sources: src/app/script/main-standalone.ts:35-50, src/app/script/klecks/storage/project-store.ts:100-115, CLAUDE.md:36-38
Conclusion
The Rocreate architecture provides a robust foundation for high-performance creative tools. By separating the concern of viewport management (Easel), pixel manipulation (KlCanvas), and state synchronization (KlApp), the system maintains extensibility. The integration of CanvasKit ensures that even complex multi-layer compositions remain performant across different hardware configurations.