Color Management
Relevant source files
The following files were used as context for generating this wiki page:
Color Management in Dotorixel provides a robust infrastructure for handling pixel data, UI themes, and user-facing color selection. It spans from low-level Rust implementations for performance-critical pixel manipulation to Svelte-based reactive state management and CSS design tokens for consistent visual presentation across platforms.
The system handles three primary layers of color: core data structures (RGBA), editor state (Foreground/Background slots), and design system tokens (UI surfaces and accents). Users interact with these through specialized components such as the HSV picker and color palettes.
Core Color Architecture
The foundation of color handling is split between a high-performance Rust core and a TypeScript-based application layer. The project transitioned from a legacy TypeScript implementation to a Rust-based Color struct to support future performance demands and cross-platform consistency.
Data Structures
In the Rust core, colors are represented as 8-bit RGBA values. The core logic includes constants for common states, such as transparency.
| Field | Type | Description |
|---|---|---|
r | u8 | Red channel (0-255) |
g | u8 | Green channel (0-255) |
b | u8 | Blue channel (0-255) |
a | u8 | Alpha channel (0-255) |
Sources: crates/core/src/color.rs:4-9, src/lib/canvas/color.ts:1-6
Component Relationship Diagram
The following diagram illustrates how color data flows from the low-level Rust core to the reactive UI layers.
Editor Color State
Dotorixel manages active colors using a dual-slot system comprising a Foreground Color and a Background Color. This is managed within the EditorState (or SharedState in multi-tab configurations) to ensure tools have access to the currently selected paint.
Key State Properties
- ForegroundColor: The primary color used by drawing tools (e.g., Pencil).
- BackgroundColor: Used for secondary operations; default is white (
#FFFFFF). - Recent Colors: A history of recently used colors shared across the workspace.
Color Swapping Logic
The editor provides a swapColors method that exchanges the values of the foreground and background slots. This is a common workflow for pixel artists switching between primary colors and highlights or erasers (when the eraser is configured to use the background color).
User Interface & Selection
Color selection is facilitated through a reactive HSV (Hue, Saturation, Value) picker and a palette system.
HSV Color Picker
The HsvPicker component allows users to select colors using a visual spectrum. It internally manages conversions between HSV and RGB color spaces to update the editor state.
- Hue: Controlled via a slider or 1D picker.
- Saturation/Value: Controlled via a 2D saturation-value square.
- Transparency: Swatches utilize a checkerboard pattern behind semi-transparent colors to ensure visibility.
Sources: src/lib/color-picker/HsvPicker.svelte, tasks/records/028-fg-bg-color-swap.md:104-108
Design System Tokens
The UI itself is colored using a set of CSS custom properties defined in the design system. These tokens support both light and dark modes through a data-theme attribute.
| Token Group | Purpose | Examples |
|---|---|---|
Surface | Backgrounds of panels and the app | --ds-bg-base, --ds-bg-surface |
Text | Content readability | --ds-text-primary, --ds-text-secondary |
Accent | Interactive elements and highlights | --ds-accent, --ds-accent-text |
Status | Feedback and alerts | --ds-danger, --ds-success |
Sources: src/styles/design-tokens.css:7-40, tasks/records/041-design-system-finalization.md
Implementation Examples
Color Struct (Rust)
The core Color implementation provides utilities for common operations and transparency.
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl Color {
pub const TRANSPARENT: Self = Self { r: 0, g: 0, b: 0, a: 0 };
}
Sources: crates/core/src/color.rs:4-14
State Management (TypeScript/Svelte)
Editor state utilizes Svelte runes ($state, $derived) for reactivity.
backgroundColor = $state<Color>({ r: 255, g: 255, b: 255, a: 255 });
selectedBackgroundColorHex = $derived(colorToHex(this.backgroundColor));
swapColors = (): void => {
const temp = this.foregroundColor;
this.foregroundColor = this.backgroundColor;
this.backgroundColor = temp;
};
Sources: src/lib/canvas/editor-state.svelte.ts, tasks/records/028-fg-bg-color-swap.md:22-34
Summary
Color Management in Dotorixel is a cross-tier system that ensures pixel-perfect accuracy in the Rust core while maintaining a highly responsive UI in Svelte. By utilizing a dual-color slot system (FG/BG) and a tokenized design system, the project achieves professional-grade editor functionality alongside a maintainable and themeable user interface.