Customizing Fabric.js Selection Controls and Visual States

When working with Fabric.js canvas applications, customizing how selected objects appear is essential for creating polished user experiences. This guide covers the properties and methods available for modifying selection handles, borders, and object states.

Canvas Setup

<canvas id="c" style="border: 1px solid #ccc;"></canvas>

<script>
  const canvas = new fabric.Canvas('c', {
    width: 500,
    height: 500
  })

  const rect = new fabric.Rect({
    top: 100,
    left: 100,
    width: 120,
    height: 80,
    fill: '#4a90d9'
  })

  canvas.add(rect)
</script>

This creates a basic canvas with a selectable rectangle. The following sections explain how to customize the selection interface.

Control Handles

Control handles (often called "corners") appear around selected objects. Fabric.js provides extensive customization options.

Filled vs Hollow Handles

By default, handles are hollow with only a border. To create filled handles:

const rect = new fabric.Rect({
  transparentCorners: false,
  cornerColor: '#ff6b6b',
  cornerSize: 15
})

Handle Color

The cornerColor property sets both the border and fill color:

const rect = new fabric.Rect({
  cornerColor: '#e74c3c'
})

Handle Border Color

To set only the border color separately from the fill:

const rect = new fabric.Rect({
  transparentCorners: false,
  cornerColor: '#e74c3c',
  cornerStrokeColor: '#2c3e50'
})

Handle Size

Modify handle dimensions using cornerSize:

const rect = new fabric.Rect({
  cornerSize: 25
})

Handle Dash Pattern

The cornerDashArray property creates dashed borders. The array defines alternating dash and gap lengths:

Single element - equal dash and gap:

const rect = new fabric.Rect({
  cornerDashArray: [8]
})

Two elements - specified dash and gap:

const rect = new fabric.Rect({
  cornerDashArray: [8, 12]
})

Three or more elements - alternating pattern:

const rect = new fabric.Rect({
  cornerDashArray: [5, 10, 15]
})

Handle Shape

By default, handles are squares. Change to circles:

const rect = new fabric.Rect({
  cornerStyle: 'circle'
})

Selection Border

The selection border surrounds the object bounding box.

Border Color

Set using borderColor:

const rect = new fabric.Rect({
  borderColor: '#27ae60'
})

Border Thickness

Control border width with borderScaleFactor:

const rect = new fabric.Rect({
  borderScaleFactor: 3
})

Border Dash Pattern

Apply dashed borders using borderDashArray:

const rect = new fabric.Rect({
  borderDashArray: [8, 4, 2, 4]
})

Additional Styling Options

Padding

The padding property controls the space between the object bounds and the selection border:

const rect = new fabric.Rect({
  padding: 15
})

Background Color

Fabric.js distinguishes between fill (interior color) and backgroundColor (bounding box color):

const rect = new fabric.Rect({
  fill: '#3498db',
  backgroundColor: '#f39c12',
  padding: 20
})

Selection Highlight Color

The selectionBackgroundColor property sets the background when an object is actively selected:

const rect = new fabric.Rect({
  fill: '#3498db',
  backgroundColor: '#f39c12',
  selectionBackgroundColor: '#1abc9c',
  padding: 15
})

Note: When both backgroundColor and selectionBackgroundColor are set, backgroundColor takes priority in overlapping areas (the space outside padding).

Drag Transparency

During object movement, control border opacity using borderOpacityWhenMoving:

const rect = new fabric.Rect({
  borderOpacityWhenMoving: 0.4
})

Accepts values from 0 (invisible) to 1 (fully opaque).

Object States

Disabling Selection

Prevent objects from being selected:

const rect = new fabric.Rect({
  selectable: false
})

Pixel-Perfect Selection

By default, clicking any where within the bounding box selects the object. Enable pixel-perfect detection:

const circle = new fabric.Circle({
  radius: 50,
  fill: '#9b59b6',
  perPixelTargetFind: true
})

This requires clicking the actual filled area of non-rectangular objects.

Hiding Control Handles

Remove all handles to prevent scaling and rotation:

const rect = new fabric.Rect({
  hasControls: false
})

Hiding Selection Border

Remove the selection border:

const rect = new fabric.Rect({
  hasBorders: false
})

Selective Handle Visibility

Fabric.js allows granular control over individual handles.

Control Point Identifiers

The eight handles plus rotation control are identified as:

  • mt - middle top
  • mb - middle bottom
  • ml - middle left
  • mr - middle right
  • tl - top left
  • tr - top right
  • bl - bottom left
  • br - bottom right
  • mtr - rotation handle

Batch Configuration

Use setControlsVisibility() to modify multiple handles:

rect.setControlsVisibility({
  tl: false,
  tr: false,
  mtr: false
})

Single Handle Configuration

Use setControlVisible() for individual handles:

rect.setControlVisible('bl', false)

Query Handle State

Check if a specific handle is visible:

console.log(rect.isControlVisible('br')) // true or false

Retrieving Selected Objects

Single Selection

getActiveObject() returns the current selected object:

const active = canvas.getActiveObject()
if (active) {
  active.set('fill', '#e74c3c')
  canvas.renderAll()
}

Returns null when nothing is selected.

Multiple Selection

getActiveObjects() returns an array of all selected objects:

const selected = canvas.getActiveObjects()
selected.forEach(obj => {
  obj.set('opacity', 0.5)
})
canvas.renderAll()

Returns an empty array when nothing is selected.

Practical Example

Combining multiple properties for a custom selection style:

const customRect = new fabric.Rect({
  left: 150,
  top: 150,
  width: 100,
  height: 100,
  fill: '#2ecc71',
  
  // Control handles
  cornerStyle: 'circle',
  cornerColor: '#ffffff',
  cornerStrokeColor: '#27ae60',
  cornerSize: 12,
  transparentCorners: false,
  
  // Selection border
  borderColor: '#27ae60',
  borderScaleFactor: 2,
  
  // Spacing
  padding: 10,
  
  // During interaction
  borderOpacityWhenMoving: 0.7
})

canvas.add(customRect)

This creates a green square with circle handles, custom colors, and optimized visibility during drag operations.

Tags: fabric.js Canvas javascript frontend UI Customization

Posted on Mon, 24 Aug 2026 16:17:13 +0000 by JessePHP