Deselecting mouse event 'mouse:down' after initial event has been rendered - javascript

I am very new to fabric.js, but I am learning quickly.
I have a few items that, when clicked, will fill with the color red.
My problem lies with clicking the image again to reset only that image back to default (black).
Can someone explain how to achieve this?
canvas.on('mouse:down', function(e) {
e.target.setFill('red');
e.target.lockMovementX = e.target.lockMovementY = true;
e.target.lockScalingX = e.target.lockScalingY = true;
e.target.lockUniScaling = true;
canvas.deactivateAll().renderAll();
});
Please see the JSFIDDLE for the full example code

Look at the if statement below. It detects the current color and switches it:
(function(){
var canvas = new fabric.Canvas('c4');
canvas.hoverCursor = 'default';
canvas.on('mouse:down', function(e) {
var color = e.target.fill;
if(color == '#000')
{
e.target.setFill('red');
} else {
e.target.setFill('#000');
}
e.target.lockMovementX = e.target.lockMovementY = true;
e.target.lockScalingX = e.target.lockScalingY = true;
e.target.lockUniScaling = true;
canvas.deactivateAll().renderAll();
});
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 200 }));
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 150 }));
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 100 }));
})();

Look at this Fiddle : http://jsfiddle.net/hpyrk05w/3/
it is so simple :
you have to check on mouse down if current fill of object is what?
if current fill is red than fill it with black color and if not, than fill it with red color
(function(){
var canvas = new fabric.Canvas('c4');
canvas.hoverCursor = 'default';
canvas.on('mouse:down', function(e) {
if(e.target.getFill()=="red")
e.target.setFill('black');
else
e.target.setFill('red');
e.target.lockMovementX = e.target.lockMovementY = true;
e.target.lockScalingX = e.target.lockScalingY = true;
e.target.lockUniScaling = true;
canvas.deactivateAll().renderAll();
});
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 200 }));
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 150 }));
canvas.add(new fabric.Circle({ radius: 10, fill: '#000', top: 100, left: 100 }));
})();
pre { margin-left: 15px !important }
canvas{border: 1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://fabricjs.com/lib/fabric.js"></script>
<canvas id="c4" width="450" height="500"></canvas>

Related

delete selected objects in fabric.js

My aim is to get three buttons in fabric.js:
"Copy",
"Paste",
"Delete".
Button with name "Copy" should copy selected objects.
Button with name "Paste" should paste copied objects.
Button with name "Delete" should delete selected objects from canvas.
"Copy" and "paste" buttons helps to work with selected objectives.
Buttons with copy and paste works well at that time remove button shows error:
How should I solve my problem?
function Copy()
{
canvas.getActiveObject().clone(function(cloned)
{
_clipboard = cloned;
});
}
function Delete()
{
canvas.getActiveObject().remove();
}
function Paste() {
_clipboard.clone(function(clonedObj) {
canvas.discardActiveObject();
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});
if (clonedObj.type === 'activeSelection') {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function(obj) {
canvas.add(obj);
});
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}
_clipboard.top += 10;
_clipboard.left += 10;
canvas.setActiveObject(clonedObj);
canvas.requestRenderAll();
});
}
var canvas = this.__canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
left: 100,
top: 50,
fill: '#D81B60',
width: 100,
height: 100,
strokeWidth: 2,
stroke: "#880E4F",
rx: 10,
ry: 10,
angle: 45,
hasControls: true
});
canvas.add(rect);
<div>
<button type="button" onclick="Copy()">copy</button>
<button type="button" onclick="Paste()">paste</button>
<button type="button" onclick="Delete()">delete</button>
</div>
<div style="display:flex;flex-direction:row;">
<div>
<canvas id="c" width="1300" height="1300"></canvas>
</div>
</div>
<script src="https://unpkg.com/fabric#4.6.0/dist/fabric.js"></script>
The error is clear you are getting:
remove is not a function
You should be using canvas.remove(object) here is a working sample:
function Delete() {
var active = canvas.getActiveObject()
if (active) {
canvas.remove(active)
if (active.type == "activeSelection") {
active.getObjects().forEach(x => canvas.remove(x))
canvas.discardActiveObject().renderAll()
}
}
}
var canvas = this.__canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
left: 100,
top: 50,
fill: '#D81B60',
width: 100,
height: 100,
strokeWidth: 2,
stroke: "#880E4F",
rx: 10,
ry: 10,
angle: 45,
hasControls: true
});
canvas.add(rect);
var rect2 = new fabric.Rect({
left: 160,
top: 10,
fill: '#D81B60',
width: 60,
height: 60,
strokeWidth: 2,
stroke: "#880E4F",
hasControls: true
});
canvas.add(rect2);
<div>
<button type="button" onclick="Delete()">delete</button>
</div>
<div style="display:flex;flex-direction:row;">
<div>
<canvas id="c" width="1300" height="1300"></canvas>
</div>
</div>
<script src="https://unpkg.com/fabric#4.6.0/dist/fabric.js"></script>

Fabric JS How to call a function from another function

I have a function that hides and shows an image whenever it's clicked, but I want to do the same thing, by clicking another object.
Here is the code for the image
function drawCheckbox(left, top, width, height){
var imgClass = new fabric.Image.fromURL('https://image.flaticon.com/icons/svg/33/33281.svg',function(img){
img.width = width;
img.height = height;
img.left = left;
img.top = top;
img.set({
hoverCursor: 'default',
selectable: true,
opacity: 0
})
img.on('mousedown', function(e) {
if(e.target.opacity <= 0.5){
e.target.opacity = 1;
}else{
e.target.opacity = 0;
}
canvas.renderAll();
});
canvas.add(img);
canvas.renderAll();
})
}
And this is the code for the rectangle object:
function addRect(left, top, width, height, id) {
const o = new fabric.Rect({
width: width,
height: height,
fill: tableFill,
stroke: tableStroke,
strokeWidth: 2,
shadow: tableShadow,
originX: 'center',
originY: 'center',
centeredRotation: true,
snapAngle: 45,
selectable: true
})
const t = new fabric.IText(number.toString(), {
fontFamily: 'Calibri',
fontSize: 14,
fill: '#fff',
textAlign: 'center',
originX: 'center',
originY: 'center'
})
const g = new fabric.Group([o, t], {
left: left,
top: top,
centeredRotation: true,
snapAngle: 45,
selectable: true,
type: 'table',
id: id,
number: number
})
canvas.add(g)
number++
g.on('selected', function () {
// here I want to make de image dissapear, when the object is clicked
})
canvas.hoverCursor = 'pointer';
canvas.discardActiveObject();
canvas.renderAll();
return g;
}
I tried creating the image inside the rectangle, but it doesn't do anything when the rectangle it's clicked. Does anyone had a similar problem?
Here is the codepen: codepen.io/Zerro1/pen/PoZvmOE .
Here i have created a codepen for you, this is one way to do it. I tried to create a square and clicking on that square i am toggling the last checkbox visibility.
portion of code:
var square = new fabric.Rect({
width: 100,
height: 100,
fill: '#000',
left:120
});
square.on('mousedown', function(e) {
if(img.opacity <= 0.5){
img.opacity = 1;
}else{
img.opacity = 0;
}
canvas.renderAll();
});
canvas.add(img);
canvas.add(square);
canvas.renderAll();

How to set fill color for selection in fabricjs?

I'd like to select a bunch of objects on fabricjs(2.7.0) canvas and show selection as filled with low opacity.
Current:
Desired:
I tried this:
fabric.Group.prototype.selectionBackgroundColor = '#2dcfab';
fabric.Group.prototype.backgroundColor = '#2dcfab';
But no luck. here is the jsfiddle. Any help would be appreciated!
You set the selectionBackgroundColor to an rgba string to give the color an opacity value.
Example:
fabric.Group.prototype.selectionBackgroundColor = 'rgba(45,207,171,0.25)';
var canvas = new fabric.Canvas("canvas");
fabric.Group.prototype.selectionBackgroundColor = 'rgba(45,207,171,0.25)';
canvas.add(new fabric.Rect({
width: 50,
height: 50,
left: 50,
top: 100,
fill: 'green'
}));
canvas.add(new fabric.Rect({
width: 60,
height: 60,
left: 250,
top: 100,
fill: 'red'
}));
canvas.on('object:selected', function (e) {
e.target.transparentCorners = false;
e.target.borderColor = '#cccccc';
e.target.cornerColor = '#0CB7F0';
e.target.minScaleLimit = 2;
e.target.cornerStrokeColor = '#0CB7F0';
e.target.cornerStyle = 'circle';
e.target.minScaleLimit = 0;
e.target.lockScalingFlip = true;
e.target.padding = 5;
e.target.selectionDashArray = [10, 5];
e.target.borderDashArray = [10, 5];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.0/fabric.min.js"></script>
<canvas id="canvas" height="400" width="400"></canvas>

Fabric.js - Attach object creation to mouse click

When you create a new fabric object, you can specify the location for it to appear on the canvas. Is there a way to attach the generated object to the mouse and then place the object on click (or touch)?
E.g. way to generate a circle which appears on the canvas.
var circle = new fabric.Circle({
radius: 20, fill: 'green', left: 100, top: 100
});
It's fairly easy to update the position of an object to match that of the mouse's position and on mouse:up clone that object and place it on the canvas.
var canvas = new fabric.Canvas('c');
var mousecursor = new fabric.Circle({
left: 0,
top: 0,
radius: 5,
fill: '#9f9',
originX: 'right',
originY: 'bottom',
})
canvas.add(mousecursor);
canvas.on('mouse:move', function(obj) {
mousecursor.top = obj.e.y - mousecursor.radius;
mousecursor.left = obj.e.x - mousecursor.radius;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
// put circle off screen
mousecursor.top = -100;
mousecursor.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(mousecursor.clone())
canvas.renderAll()
})
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
var canvas = new fabric.Canvas('c');
var mousecursor = new fabric.Circle({
left: 0,
top: 0,
radius: 50,
fill: '#9f9',
originX: 'right',
originY: 'bottom',
})
canvas.add(mousecursor);
canvas.on('mouse:move', function(obj) {
mousecursor.top = obj.e.y;
mousecursor.left = obj.e.x;
canvas.renderAll()
})
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

Can i set inside stroke in fabric js

I am working on a fabricjs application & i need to set a inside stroke to object, it means apply stroke to a object without increase it's size.
eg if i apply strokeWidth 20 to 100*100 rect then it's size is also increase but i want if stroke is apply to object then size will also remain same
var recta = new fabric.Rect({
left: 10,
top: 10,
fill: '#000',
width: 100,
height: 100,
});
var rectb = new fabric.Rect({
left: 150,
top: 10,
fill: '#000',
width: 100,
height: 100,
});
canvas.add(recta, rectb);
rectb.set('stroke', '#f00');
rectb.set('strokeWidth', 20);
canvas.renderAll();
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas style="border:#000 1px solid" id="design-canvas" width="500" height="400">
<script type="text/javascript">
canvas = new fabric.Canvas('design-canvas');
</script>
Is there is any way or trick to apply stroke without increase size
Thanks in Advance
Assuming it'd just be for rectangles, The best way would likely be too attach 4 lines which you update the positions based off of that rectangles x, y, width and height. You can then set the stroked width of those lines separately.
The other way would be too simply resize the owning element. Look at this JSFiddle.
var canvas = new fabric.Canvas('c', { selection: false });
var circle, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: pointer.x,
top: pointer.y,
radius: 1,
strokeWidth: 5,
stroke: 'red',
selectable: false,
originX: 'center', originY: 'center'
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
circle.set({ radius: Math.abs(origX - pointer.x) });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});

Categories

Resources