Fabric.js: Assigning background color to group - javascript

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/.

Related

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>

unchange the object order

We put the object1 first,then put the object2,and put the object3 finally on the canvas.
It's mean that object1 is on the bottom,and object3 is on the top.
When we want to change the object2 url or do sth on it,we remove it and add the new object2 after.
But now object2 is on the top.
I know some method like sendToBack(),moveTo(),....etc,can change the order of the object2.
There is no clue about fix the object order.
Is there some method already existed or other statement can apply?
If not,is the only way that we change their order again and again by applying method as above after change the object layer?
Thank you.
Use insertAt() to insert the object at given index.
DEMO
var canvas = new fabric.Canvas('c');
var rect1 = new fabric.Rect({
width: 100,
height: 100,
left: 10,
top: 10,
fill: 'red',
});
var rect2 = new fabric.Rect({
width: 100,
height: 100,
left: 30,
top: 30,
fill: 'green',
});
var rect3 = new fabric.Rect({
width: 100,
height: 100,
left: 50,
top: 50,
fill: 'black',
});
var rect4 = new fabric.Rect({
width: 100,
height: 100,
left: 30,
top: 30,
fill: 'yellow',
});
canvas.add(rect1,rect2,rect3);
function alter(){
var index = canvas.getObjects().indexOf(rect2);
//canvas.remove(rect2);
canvas.insertAt(rect4, index,true);
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<button onclick="alter()">Alter</button>
<canvas id="c" width="600" height="600"></canvas>

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 .

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

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();

Need to change the canvas background color while using fabric js

I've a canvas element and I create fabric object out of that. Now, I want to change the background color dynamically. The following doesn't work for me.
var x;
x = new fabric.Canvas("mycanvas", {
backgroundColor : "#fff",
selection: true
});
x.backgroundColor = "#f00";
The background color is white and it doesn't get changed to red.
You need to render canvas after changing properties, because properties of object is just properties and not handled by event
http://jsfiddle.net/oceog/gDhht/
var canvas = new fabric.Canvas('c',{backgroundColor : "#0ff"});
console.log(canvas);
canvas.backgroundColor="red";
canvas.renderTop();
canvas.add(
  new fabric.Rect({ top: 100, left: 100, width: 50, height: 50, fill: '#f55' }),
  new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
  new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
);
canvas.backgroundColor="green";
canvas.renderAll();
​
update: I tried with latest fabric, seems you not need renderAll() anymore.

Categories