Managing Canvas State
FxCanvas maintains a state that includes transformations, styles, and clipping regions. Proper state management is crucial for complex drawings, allowing you to temporarily modify settings and return to previous states without manual tracking.
Understanding Canvas State
The canvas state encompasses:
- Current transformation matrix
- Current clipping region
- Fill and stroke styles (colors, gradients, patterns)
- Line properties (width, caps, joins, dashes)
- Shadow properties
- Global alpha and compositing mode
- Text properties (font, alignment, baseline)
Saving and Restoring State
The save() and restore() methods manage state stacks:
// Save current state
canvas.save();
// Modify state
canvas.setFillStyle(new Color(255, 0, 0)); // red
canvas.translate(100, 100);
canvas.rotate(Math.PI / 4);
// Draw with modified state
canvas.fillRect(0, 0, 50, 50);
// Restore previous state
canvas.restore();
// Subsequent drawings use original state
canvas.fillRect(0, 0, 50, 50);State Stack Management
States are managed as a stack - each save() pushes a copy of the current state, restore() pops the top state:
canvas.save(); // Level 1
canvas.setFillStyle(new Color(0, 0, 255)); // blue
canvas.save(); // Level 2 - saves blue style
canvas.setFillStyle(new Color(0, 128, 0)); // green
// Current style is green
canvas.restore(); // Back to level 1 - style is blue
canvas.restore(); // Back to original - style is defaultWhat Gets Saved and Restored
When you save state, the following are preserved:
- Transformation matrix
- Clipping region
- fillStyle and strokeStyle
- lineWidth, lineCap, lineJoin, miterLimit
- lineDash and lineDashOffset
- shadow properties (color, offset, blur)
- globalAlpha
- globalCompositeOperation
- font, textAlign, textBaseline
Not saved: the actual pixel content of the canvas.
Resetting Transformations
The resetTransform() method resets the transformation matrix to the identity matrix (no transformations):
// Apply transformations
canvas.translate(100, 100);
canvas.scale(2, 2);
canvas.rotate(Math.PI / 4);
// Draw transformed
canvas.fillRect(0, 0, 25, 25);
// Reset transformations
canvas.resetTransform();
// Draw at original coordinates
canvas.fillRect(0, 0, 25, 25);This is equivalent to canvas.setTransform(1, 0, 0, 1, 0, 0).
Clearing Canvas Areas
The clearRect(x, y, width, height) method clears a rectangular area, making it transparent:
// Clear entire canvas
canvas.clearRect(0, 0, canvas.width, canvas.height);
// Clear specific area
canvas.clearRect(50, 50, 100, 100);Clearing removes all content in the specified area, regardless of transformations or clipping.
Advanced State Management
Nested State Saving
function drawComplexShape(x, y, scale, rotation) {
canvas.save();
// Apply transformations
canvas.translate(x, y);
canvas.scale(scale, scale);
canvas.rotate(rotation);
// Draw shape
canvas.setFillStyle(new Color(0, 0, 255)); // blue
canvas.fillRect(-25, -25, 50, 50);
canvas.restore();
}
// Use the function
drawComplexShape(100, 100, 1.5, Math.PI / 6);
drawComplexShape(200, 200, 0.8, -Math.PI / 4);State for Temporary Effects
// Draw base content
canvas.setFillStyle(new Color(211, 211, 211)); // lightgray
canvas.fillRect(0, 0, 200, 200);
// Temporary shadow effect
canvas.save();
canvas.setShadowColor(new Color(0, 0, 0, 0.5));
canvas.setShadowOffsetX(5);
canvas.setShadowOffsetY(5);
canvas.setShadowBlur(10);
canvas.setFillStyle(new Color(255, 0, 0)); // red
canvas.fillRect(50, 50, 100, 100);
canvas.restore();
// Shadow effect is gone
canvas.setFillStyle(new Color(0, 0, 255)); // blue
canvas.fillRect(100, 100, 50, 50);Clipping and State
canvas.save();
// Create clipping region
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 2);
canvas.clip();
// Draw within clip
canvas.setFillStyle(new Color(0, 128, 0)); // green
canvas.fillRect(0, 0, 200, 200); // Only circular area filled
canvas.restore();
// Clipping is removed
canvas.setFillStyle(new Color(255, 255, 0)); // yellow
canvas.fillRect(150, 150, 50, 50); // Draws normallyProper state management keeps your drawing code clean, maintainable, and prevents unexpected interactions between different parts of your graphics code.