I am working on fabricjs app & i need to draw a path & polygon shapes with round corner I did't get any fabric js parameter to do this & I also search but didn't get any result matching with my requirement
Can anyone describe me how draw a path & polygon shapes with round corner in detail with step by step , I need to draw various shapes.
eg- i need round corners at red dots as in image
canvas = new fabric.Canvas('canvas');
var path = new fabric.Path('M 170.000 210.000L 217.023 234.721 L 208.042 182.361 L 246.085 145.279 L 193.511 137.639 L 170.000 90.000 L 146.489 137.639 L 93.915 145.279 L 131.958 182.361 L 122.977 234.721 L 170.000 210.000');
path.set({ left: 120, top: 120 });
canvas.add(path);
var pol = new fabric.Polygon([
{x: 200, y: 0},
{x: 250, y: 50},
{x: 250, y: 100},
{x: 150, y: 100},
{x: 150, y: 50} ], {
left: 250,
top: 150,
angle: 0,
fill: 'green'
}
);
canvas.add(pol);
<script src=".js/1.5.0/fabric.min.js"></script>
<script src=".1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
I am working on fabricjs app & i need to draw a path & polygon shapes with round corner I did't get any fabric js parameter to do this & I also search but didn't get any result matching with my requirement
Can anyone describe me how draw a path & polygon shapes with round corner in detail with step by step , I need to draw various shapes.
eg- i need round corners at red dots as in image
canvas = new fabric.Canvas('canvas');
var path = new fabric.Path('M 170.000 210.000L 217.023 234.721 L 208.042 182.361 L 246.085 145.279 L 193.511 137.639 L 170.000 90.000 L 146.489 137.639 L 93.915 145.279 L 131.958 182.361 L 122.977 234.721 L 170.000 210.000');
path.set({ left: 120, top: 120 });
canvas.add(path);
var pol = new fabric.Polygon([
{x: 200, y: 0},
{x: 250, y: 50},
{x: 250, y: 100},
{x: 150, y: 100},
{x: 150, y: 50} ], {
left: 250,
top: 150,
angle: 0,
fill: 'green'
}
);
canvas.add(pol);
<script src="http://cdnjs.cloudflare./ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
Share
Improve this question
edited Jun 18, 2018 at 16:12
Cœur
38.8k25 gold badges206 silver badges278 bronze badges
asked Nov 23, 2015 at 10:33
DineshDinesh
8652 gold badges19 silver badges41 bronze badges
4 Answers
Reset to default 2There is no embedded function to add rounded corners to shapes.
What you can use is the drawing canvas property "lineJoin" that is accessible for every path using object.strokeLineJoin = 'round';
To have a visible effect you have to use a big stroke. i used 20 here to make the effect visible.
canvas = new fabric.Canvas('canvas');
var path = new fabric.Path('M 170.000 210.000L 217.023 234.721 L 208.042 182.361 L 246.085 145.279 L 193.511 137.639 L 170.000 90.000 L 146.489 137.639 L 93.915 145.279 L 131.958 182.361 L 122.977 234.721 L 170.000 210.000');
path.set({ left: 120, top: 120, strokeLineJoin: 'round', strokeWidth: 20, stroke: 'black' });
canvas.add(path);
var pol = new fabric.Polygon([
{x: 200, y: 0},
{x: 250, y: 50},
{x: 250, y: 100},
{x: 150, y: 100},
{x: 150, y: 50} ], {
left: 250,
top: 150,
angle: 0,
fill: 'green',
strokeLineJoin: 'round',
strokeWidth: 20,
stroke: 'green'
}
);
canvas.add(pol);
<script src="http://cdnjs.cloudflare./ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
add = new fabric.Rect({
width: 200, height: 100, left: 10, top: 10, angle: 0,
fill: 'rgba(0, 0, 0, 0)',
stroke: '#000000',
strokeWidth: lineWidth,
strokeLineJoin: 'round',
rx: 10,
ry: 10
});
There doesn't seem to be such an option in fabricjs Polygon constructor.
What you could do however, is to set the strokeLineJoin
of your object to 'rounded', apply a huge stroke of the same color as your fill
, and down-scale the shape.
However, I didn't found the right method to calculate the down-scale factor yet, so I did it approximately, by view.
// the bigger, the rounder
var sW = 50;
var canvas = new fabric.Canvas('canvas');
var path = new fabric.Path('M 170.000 210.000L 217.023 234.721 L 208.042 182.361 L 246.085 145.279 L 193.511 137.639 L 170.000 90.000 L 146.489 137.639 L 93.915 145.279 L 131.958 182.361 L 122.977 234.721 L 170.000 210.000', {
stroke: 'black',
strokeWidth: sW,
scaleX : 0.7,
scaleY : 0.7,
strokeLineJoin : 'round',
left: 120,
top: 120}
);
canvas.add(path);
var pol = new fabric.Polygon([
{x: 200, y: 0},
{x: 250, y: 50},
{x: 250, y: 100},
{x: 150, y: 100},
{x: 150, y: 50} ], {
left: 250,
top: 160,
angle: 0,
fill: 'green',
stroke: 'green',
strokeWidth: sW,
scaleX : 0.7,
scaleY : 0.7,
strokeLineJoin : 'round'
}
);
canvas.add(pol);
<script src="http://cdnjs.cloudflare./ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
i think that you need something like this
it is transparent because i set fill:'transparent'
, you can change it to whatever color you like.
my example is not perfect because i tried these properties in order to move the polygone to background but with no success, these are the properties to move back/front the objects:
canvas.sendBackwards(myObject)
canvas.sendToBack(myObject)
canvas.bringForward(myObject)
canvas.bringToFront(myObject)
a little about the code here:
var roof = null;
var roofPoints = [];
var lines = [];
var dots = [];
var lineCounter = 0;
var dotsCounter = 0;
var drawingObject = {};
drawingObject.type = "";
drawingObject.background = "";
drawingObject.border = "";
function Point(x, y) {
this.x = x;
this.y = y;
}
$("#btnRoof").click(function () {
if (drawingObject.type == "roof") {
drawingObject.type = "";
lines.forEach(function(value, index, ar){
canvas.remove(value);
});
//canvas.remove(lines[lineCounter - 1]);
roof = makeRoof(roofPoints);
canvas.add(roof);
canvas.renderAll();
} else {
drawingObject.type = "roof"; // roof type
}
});
// canvas Drawing
var canvas = new fabric.Canvas('canvas');
var x = 0;
var y = 0;
window.addEventListener('dblclick', function(){
var left = findLeftPaddingForRoof(roofPoints);
var top = findTopPaddingForRoof(roofPoints);
drawingObject.type = "";
lines.forEach(function(value, index, ar){
canvas.remove(value);
});
dots.forEach(function(value, index, ar){
canvas.remove(value);
});
canvas.remove(lines[lineCounter - 1]);
roof = makeRoof(roofPoints);
dots.push(roof);
var alltogetherObj = new fabric.Group(dots,{
left:left,
top: top,
originX:'center',
originY:'center'});
canvas.add(alltogetherObj);
canvas.renderAll();
});
canvas.on('mouse:down', function (options) {
if (drawingObject.type == "roof") {
canvas.selection = false;
setStartingPoint(options); // set x,y
roofPoints.push(new Point(x, y));
var points = [x, y, x, y];
lines.push(new fabric.Line(points, {
strokeWidth: 1,
selectable: false,
stroke: 'red'
}).setOriginX(x).setOriginY(y));
canvas.add(lines[lineCounter]);
canvas.sendToBack(lines[lineCounter]);
lineCounter++;
//add red dot
dots.push(new fabric.Circle({
selectable:false,
left: x-5,
top: y-5,
centerX:'center',
centerY:'top',
radius: 10,
fill: "#dd0000"
}));
canvas.add(dots[dotsCounter]);
//it does not do anything here
canvas.bringToFront(dots[dotsCounter]);
//it does not do anything here either
canvas.bringForward(dots[dotsCounter]);
dotsCounter++;
canvas.on('mouse:up', function (options) {
canvas.selection = true;
});
}
});
canvas.on('mouse:move', function (options) {
if (lines[0] !== null && lines[0] !== undefined && drawingObject.type == "roof") {
setStartingPoint(options);
lines[lineCounter - 1].set({
x2: x,
y2: y
});
canvas.renderAll();
}
});
function setStartingPoint(options) {
var offset = $('#canvas').offset();
x = options.e.pageX - offset.left;
y = options.e.pageY - offset.top;
}
function makeRoof(roofPoints) {
var left = findLeftPaddingForRoof(roofPoints);
var top = findTopPaddingForRoof(roofPoints);
var roof = new fabric.Polyline(roofPoints, {
fill: 'transparent',
stroke:'#7F7F7F',
sendToBack:true
});
roof.set({
left: left,
top: top
});
return roof;
}
function findTopPaddingForRoof(roofPoints) {
var result = 999999;
for (var f = 0; f < lineCounter; f++) {
if (roofPoints[f].y < result) {
result = roofPoints[f].y;
}
}
return Math.abs(result);
}
function findLeftPaddingForRoof(roofPoints) {
var result = 999999;
for (var i = 0; i < lineCounter; i++) {
if (roofPoints[i].x < result) {
result = roofPoints[i].x;
}
}
return Math.abs(result);
}
i 've made some fixes to the code, so the shape closes , always, on double click. live example (new): http://jsfiddle/tornado1979/avmomzh4/