Skip to content

Clipping and Masking

Clipping restricts drawing operations to specific regions of the canvas, creating masks that hide or reveal content. This powerful technique enables effects like cutouts, vignettes, and complex compositions by limiting where subsequent drawings appear.

Understanding Clipping

Clipping defines a region (the clipping path) outside of which nothing can be drawn. Any drawing operation will only affect pixels within the current clipping region. Clipping is part of the canvas state and can be saved and restored.

Creating Clipping Regions

The clip() method sets the current path as the clipping region:

javascript
// Create a circular clipping region
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 2);
canvas.clip();

// Subsequent drawings are clipped to the circle
canvas.setFillStyle(new Color(255, 0, 0)); // red
canvas.fillRect(0, 0, 200, 200); // Only circular area is filled

Clipping with Shapes

Rectangular Clipping

javascript
// Clip to rectangle
canvas.beginPath();
canvas.rect(50, 50, 100, 100);
canvas.clip();

canvas.setFillStyle(new Color(0, 0, 255)); // blue
canvas.fillRect(0, 0, 200, 200); // Only rectangle area visible

Elliptical Clipping

javascript
// Clip to ellipse
canvas.beginPath();
canvas.ellipse(100, 100, 60, 40, 0, 0, Math.PI * 2);
canvas.clip();

canvas.setFillStyle(new Color(0, 128, 0)); // green
canvas.fillRect(0, 0, 200, 200);

Complex Path Clipping

javascript
// Create star-shaped clipping region
canvas.beginPath();
const spikes = 5;
const outerRadius = 50;
const innerRadius = 25;

for (let i = 0; i < spikes * 2; i++) {
    const radius = i % 2 === 0 ? outerRadius : innerRadius;
    const angle = (i * Math.PI) / spikes;
    const x = 100 + Math.cos(angle) * radius;
    const y = 100 + Math.sin(angle) * radius;
    if (i === 0) canvas.moveTo(x, y);
    else canvas.lineTo(x, y);
}
canvas.closePath();
canvas.clip();

// Draw image or content within star shape
canvas.drawImage(myImage, 0, 0);

Clipping works with compositing for advanced effects; see Composite Operations.

Masking Techniques

Text as Mask

javascript
// Use text as clipping mask
canvas.setFont(new Font({size: 48, weight: 'bold', family: 'Arial', faces: []}));
canvas.beginPath();
canvas.fillText('MASK', 50, 100);
canvas.clip();

// Draw content through text mask
canvas.setFillStyle(new Color(255, 0, 0)); // red
canvas.fillRect(0, 0, 200, 200);

Image Masking

javascript
// Use image as mask (assuming maskImage is black and white)
canvas.drawImage(maskImage, 0, 0);
canvas.setGlobalCompositeOperation('source-in');
canvas.drawImage(contentImage, 0, 0);
canvas.setGlobalCompositeOperation('source-over');

Layered Clipping

javascript
canvas.save();

// First clip level
canvas.beginPath();
canvas.arc(100, 100, 80, 0, Math.PI * 2);
canvas.clip();

// Second clip level (intersection)
canvas.beginPath();
canvas.rect(50, 50, 100, 100);
canvas.clip();

// Content only appears in intersection
canvas.setFillStyle(new Color(128, 0, 128)); // purple
canvas.fillRect(0, 0, 200, 200);

canvas.restore();

Managing Clipping State

Clipping is part of the canvas state and can be saved and restored:

javascript
canvas.save();

// Set clipping
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 2);
canvas.clip();

// Draw clipped content
canvas.setFillStyle(new Color(0, 0, 255)); // blue
canvas.fillRect(0, 0, 200, 200);

canvas.restore();

// Clipping is removed - draw normally
canvas.setFillStyle(new Color(255, 0, 0)); // red
canvas.fillRect(150, 150, 50, 50);

Advanced Clipping Techniques

Inverse Clipping (Masking Outside)

javascript
// Create mask for area outside circle
canvas.save();

// Fill entire area
canvas.setFillStyle(new Color(0, 0, 0)); // black
canvas.fillRect(0, 0, 200, 200);

// Erase circle (creating hole)
canvas.setGlobalCompositeOperation('destination-out');
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 2);
canvas.fill();

canvas.restore();

Clipping with Transformations

javascript
canvas.save();

// Apply transformation
canvas.translate(100, 100);
canvas.rotate(Math.PI / 4);

// Create transformed clipping region
canvas.beginPath();
canvas.rect(-30, -30, 60, 60);
canvas.clip();

// Draw within transformed clip
canvas.setFillStyle(new Color(255, 165, 0)); // orange
canvas.fillRect(-50, -50, 100, 100);

canvas.restore();

Multiple Clipping Regions

javascript
// Create multiple separate clipping regions
function drawWithMultipleClips() {
    // First region
    canvas.save();
    canvas.beginPath();
    canvas.arc(50, 50, 30, 0, Math.PI * 2);
    canvas.clip();
    canvas.setFillStyle(new Color(255, 0, 0)); // red
    canvas.fillRect(0, 0, 100, 100);
    canvas.restore();

    // Second region
    canvas.save();
    canvas.beginPath();
    canvas.arc(150, 150, 30, 0, Math.PI * 2);
    canvas.clip();
    canvas.setFillStyle(new Color(0, 0, 255)); // blue
    canvas.fillRect(120, 120, 100, 100);
    canvas.restore();
}

Clipping and masking enable sophisticated visual effects, from simple cutouts to complex compositions, making your FxCanvas applications more visually compelling.