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 topmb- middle bottomml- middle leftmr- middle righttl- top lefttr- top rightbl- bottom leftbr- bottom rightmtr- 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.