Fabric.js: can't get the active groups anymore - javascript

I'm using fabric 1.4.10 and i noticed that i can't get the active groups anymore! Everytime i call canvas.getActiveGroup() even when a group is selected, i get null.
My code to create groups:
var circle1 = new fabric.Circle({
radius: 50,
fill: 'red',
left: 0
});
var circle2 = new fabric.Circle({
radius: 50,
fill: 'green',
left: 100
});
var circle3 = new fabric.Circle({
radius: 50,
fill: 'blue',
left: 200
});
var group = new fabric.Group([ circle1, circle2, circle3 ], {
left: 200,
top: 100
});
canvas.add(group);
Can anyone help please?

This is because you have to check for "activeObject".
fabric.canvas.getActiveObject() will return the current selected object.
getActiveGroup will return a group if there is a temporary group selection made with interactivity layer. ( mouse )

You can add these two lines code to try:
canvas._activeObject = null;
canvas.setActiveGroup(group.setCoords()).renderAll();

Related

outline and border in fabricjs

I am using fabric.js for canvas shapes. but now i have to add border with outline on these shapes like below. How it is possible in fabricjs??. Or do we have any other js library to get same output?
I want below output:
Why not create a group out of two rectangles? Like so:
var canvas = this.__canvas = new fabric.StaticCanvas('c');
var rectBack = new fabric.Rect({
width: 170,
height: 170,
top: 0,
left: 0,
fill: 'rgba(0,0,255,1.0)',
rx: 2,
ry: 2
});
var outerMargin = 10
var innerOutlineWidth = 4
var innerOutline = new fabric.Rect({
width: 170 - outerMargin - innerOutlineWidth/2,
height: 170 - outerMargin - innerOutlineWidth/2,
top: outerMargin/2,
left: outerMargin/2,
stroke: 'rgba(255,255,255,1.0)',
fill: 'rgba(0,0,0,0.0)',
strokeWidth: innerOutlineWidth,
rx: 10,
ry: 10
});
var group = new fabric.Group([rectBack, innerOutline], {
left: 0,
top: 0,
angle: 0
});
canvas.add(group);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.7.0/fabric.min.js"></script>
<canvas id="c" width="200" height="200"></canvas>
Any framework you use is going to have some fundamental building blocks you have to piece together to get what you want. So I would not recommend jumping to another one.

fabricjs objects order in group

I have no idea how to order objects in group other then repeat add and remove to sort the objects.
I tried unshift on group objects but it does not save state.
$(document).on("click", "#addToGroup", function() {
var objects = canvas.getActiveObject();
if(objects && objects.type === "activeSelection") {
objects.toGroup();
canvas.requestRenderAll();
}
});
count = 1;
$(document).on("click", "#addObject", function() {
canvas.add(new fabric.Rect({
width: 100, height: 100, left: 100 + (count * 20), top: 20 + (count * 10), angle: -10,
fill: 'rgba(0,200,0,1)'
}));
});
Template JSFiddle
You can use fabric.Object.prototype.moveTo(). There is an undocumented behavior: if the object you call it upon is a part of a group, the object is moved within the group's _objects array, effectively changing its z-index when the group is redrawn.
Also, make sure to somehow force fabric to redraw the group after that, e.g. set group.dirty = true.
const canvas = new fabric.Canvas("c")
const a = new fabric.Rect({
width: 100,
height: 100,
left: 100,
top: 20,
angle: -10,
fill: 'rgba(0,200,0,1)'
})
const b = new fabric.Rect({
width: 50,
height: 100,
left: 150,
top: 50,
angle: 45,
stroke: '#eee',
strokeWidth: 10,
fill: 'rgba(0,0,200,1)'
})
const c = new fabric.Circle({
radius: 50,
left: 150,
top: 75,
fill: '#aac'
})
const group = new fabric.Group([a, b, c])
canvas.add(group).requestRenderAll()
document.querySelector('#b1').addEventListener('click', () => {
const bottomChild = group.getObjects()[0]
bottomChild.moveTo(group.size() - 1)
// force fabric to redraw the group
group.dirty = true
canvas.requestRenderAll()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.js"></script>
<canvas id='c' width="400" height="200"></canvas>
<button id='b1'>move bottom to top</button>

Fabric.js: Assigning background color to group

I am trying to set a background color for a group without affecting its contained objects.
So far my code looks like this:
var canvas = new fabric.Canvas('canvas');
var helloText = new fabric.Text('hello', {
fontSize: 30,
top: 10, left: 10,
originX: 0, originY: 0
});
var worldText = new fabric.Text('world!', {
fontSize: 40,
top: 50, left: 100,
originX: 0, originY: 0
});
var group = new fabric.Group([helloText, worldText], {
selectionBackgroundColor: 'red',
backgroundColor: 'blue'
});
canvas.add(group);
A jsFiddle version can be found here.
As you can see from my code, I already tried the attribute backgroundColor yet it only affects contained objects. I would like to achieve an effect similar to selectionBackgroundColor.
Slight tweak, but this should do it for you (relevant code):
var text = new fabric.Group([helloText, worldText], {});
var textBoundingRect = text.getBoundingRect();
var background = new fabric.Rect({
top: textBoundingRect.top,
left: textBoundingRect.left,
width: textBoundingRect.width,
height: textBoundingRect.height,
fill: 'blue'
});
var group = new fabric.Group([background, text], {});
Your JSFiddle updated, https://jsfiddle.net/rekrah/92ss3d86/.

Can I create more complex shapes like this one in Fabric.js?

I'm creating a simple graphic editor with JavaScript/Fabric.js and I need to be able to create somewhat more complex shape than the basic ones (line, triangle, circle, ellipse, square, rectangle ) like this one:
The green lines are the border of the shape and the black is the fill. I need to be able to manipulate the border size/color and fill color like I can for the basic shapes. Is this possible in fabric.js? If yes, could you point me in the direction I should look at because currently I have no clue how it could be done.
This should get you started.
JavaScript:
var canvas = new fabric.Canvas('c');
var defaultProperties = {
fill: 'black',
stroke: 'lime',
strokeWidth: 12
};
var ellipse = new fabric.Ellipse({
left: 30,
top: 30,
rx: 170,
ry: 110,
strokeWidth: 12
});
var horizontalLine = new fabric.Line([30, 140, 370, 140]);
var verticalLine = new fabric.Line([200, 30, 200, 140]);
var group = new fabric.Group([ellipse, horizontalLine, verticalLine]);
group.set(defaultProperties);
canvas.add(group);
var toggle = true;
document.getElementsByTagName('button')[0].addEventListener('click', function() {
if (toggle) {
group.set({
fill: 'red',
stroke: 'pink',
strokeWidth: 5
});
} else {
group.set(defaultProperties);
}
toggle = !toggle;
canvas.renderAll();
});
And the all important JSFiddle: https://jsfiddle.net/rekrah/mj5c2bx0/.
Let me know if you have any further questions.

I need to create object group on undo function with fabricjs

I have two canvas objects (Rectungle and Triangle) in group.
Then i need to delete them, then return one of objects to is past position.
Here is two objects and group
var rect1 = new fabric.Rect(
{
id: 1, left: 10, top: 10, width: 100, height: 50, angle: 45, fill: 'red'
});
var tria1 = new fabric.Triangle({
id: 2, left: 200, top: 200, width: 100, height: 50, angle: 20, fill: 'yellow'
});
var objsGroup = new fabric.Group([rect1, tria1], {left: 100, top: 100});
And the whole fiddle here. I separate all steps by alerts https://jsfiddle.net/5js60oec/
UPDATE
Have the next problem. Lets assume that existing object group making some move and rotating before deleting. Then i have to restore it to point before rotating and moving. Thats, i think the main problem.
Actions
objsGroup.top = 200;
objsGroup.left = 200;
canvas.renderAll();
alert('4');
history.push(canvas.getActiveGroup());
objsGroup.setAngle(45);
canvas.renderAll();
Here the full fiddler: https://jsfiddle.net/nppaLetn/1/
For example I am deleting the last added path in my canvas like below
var lastItemIndex = (fabricCanvas.getObjects().length - 1);
var item = fabricCanvas.item(lastItemIndex);
if(item.get('type') === 'path') {
fabricCanvas.remove(item);
fabricCanvas.renderAll();
}
This may help you to accomplish your probs!!! I think so .

Categories