sam kirubaharan
sam kirubaharan

Reputation: 154

How to modify the shape of a control widget in FabricJS?

I'm using FabricJS in my web application. As I draw shapes, I notice that the control widget for all the objects are rectangular. Can the shape of a control widget be modified to fit the actual shape of the object? Say, a circle with a circular control widget.

I went through the Controls Customization demo. But there is no option to modify the shape of a control widget.

I need to modify the shape of the control widgets for the following purpose: In my application whenever an object is clicked, its fill colour is toggled between black and white. In this case(refer the image below), because the circle has a rectangular control widget, clicking the pointed pixel selects the circle instead of the rectangle. I also hide the control widget from appearing by using hasControls property. So, the user will not know anything about the control widget. So, is the shape of the control widget editable? FabricJS Demo - Controls

Upvotes: 0

Views: 678

Answers (1)

shkaper
shkaper

Reputation: 4998

I don't think there is an easy way to do that with fabric.js without writing a whole bunch of extra code. Fabric.js always draws a rectangle bounding box and uses it for selection controls. However, since you're planning on hiding the controls anyway, it sounds like you might be better off using perPixelTargetFind.

When true, object detection happens on per-pixel basis rather than on per-bounding-box

Here's a quick demo:

const canvas = new fabric.Canvas('c', {
  preserveObjectStacking: true,
  perPixelTargetFind: true
})

const circle = new fabric.Circle({
  radius: 50,
  left: 50,
  top: 50,
  stroke:'green',
  fill: 'white',
  hasControls: false,
  hasBorders: false
})

const rect = new fabric.Rect({
  width: 200,
  height: 150,
  left: 50,
  top: 25,
  stroke: 'green',
  fill: 'black',
  hasControls: false,
  hasBorders: false
})

canvas.on('mouse:down', (e) => {
  const obj = e.target
  if (obj) {
    obj.set({
      fill: obj.fill === 'white' ? 'black' : 'white'
    })
    canvas.requestRenderAll()
  }
})

canvas.add(circle, rect)
circle.bringToFront()
canvas.requestRenderAll()
body {
  background: ivory;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="c" width="300" height="200"></canvas>

Upvotes: 1

Related Questions