Question: I want to free-draw shapes with fabric.js. The outline is, say, 20px (such that the user sees it clearly). 

After the user has drawn it, the shape should been filled with the same color as the outline.

The whole thing should be semi-transparent. Unfortunately, this causes the overlap between outline and fill to be less transparent and draws a strange "inner outline" to the shape.

Is there a way to make shape uniquely semi-transparent?

Maybe a trick would be: after the user has drawn the shape, "widen" the shape by half of outline thickness and set outline thickness to 1. Would that be possible?

See this <https://jsfiddle.net/4ypdwe9o/> or below for an example.

```js
var canvas = new fabric.Canvas('c', {
    isDrawingMode: true,

 });

 canvas.freeDrawingBrush.width = 10;
 canvas.freeDrawingBrush.color = 'rgb(255, 0, 0)';

canvas.on('mouse:up', function() {

  canvas.getObjects().forEach(o => {
    o.fill = 'rgb(255, 0, 0)';
    o.opacity = 0.5;
   });
  canvas.renderAll();
})
```

```css
canvas {
    border: 1px solid #ccc;
}
```

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
```

Answer: 
In fabric.js 1.7.3, they have another implementation. When I use

```
fabricCanvasObject.getObjects('path').slice(-1)[0].setFill("red");
fabricCanvasObject.getObjects('path').slice(-1)[0].setOpacity(0.5);

```

instead of 

```
fabricCanvasObject.getObjects('path').slice(-1)[0].fill = "red";
fabricCanvasObject.getObjects('path').slice(-1)[0].opacity = 0.5;

```

The boundary is painted correctly, without overlap. So, the temporary canvas from Janusz's answer is not needed anymore. For my former fabric.js 1.5.0, the answer from Janusz solved the problem.
Jetic,

You are almost finished your logic. Instead of using "opacity" use rgba:

```
 canvas.getObjects().forEach(o => {
    o.fill = 'rgba(255, 0, 0, 0.5)';
    o.stroke = 'rgba(255, 0, 0, 0)';
  //  o.opacity = 0.5;
   });
  canvas.renderAll();

```