This Rectangle i have created on canvas using fabicjs , now on change of text box i want to set border width . i tried following but its not working.
image[img] = new fabric.Rect({
top : 100,
left : 100,
width : 50,
height : 50,
fill : '#f55',
stroke : 'black',
strokeWidth : 1
});
Changing Border Width ::
$('#shape_border_size').change(function() {
console.log(' size changed to ' + $(this).val());
var obj = canvas.getActiveObject();
if (!obj)
return;
//obj.set('strokeWidth', $(this).val());
canvas.renderAll();
});
I think your code is fine, don't know why it's not working.
Check this http://jsfiddle.net/hellomaya/kNEaX/3/
var rect = new fabric.Rect({
top: 100,
left: 100,
width: 50,
height: 50,
fill: '#f55',
stroke: 'white',
strokeWidth: 1
});
canvas.add(rect);
canvas.renderAll();
$('#a').click(function () {
rect.set('strokeWidth', 20);
canvas.renderAll();
});
$('#b').click(function () {
rect.set('strokeWidth', 20);
rect.width += 20;
rect.height += 20;
canvas.renderAll();
});
Related
I'm trying to check for a collision between 2 text objects and using the intersectsWithObject. It's working but it's taking the bouding rect into account. Is it possible to check on pixel level?
Current behaviour:
Wanted behaviour:
const canvas = new fabric.Canvas('canvas');
canvas.setWidth(document.body.clientWidth);
canvas.setHeight(document.body.clientHeight);
const text = new fabric.Textbox('some text', {
width: 300,
fontSize: 70,
top: 120,
left: 100
});
const text2 = new fabric.Textbox('some more text', {
width: 350,
fontSize: 50,
top: 200,
left: 20,
})
if (text.intersectsWithObject(text2, true, true)) {
text.set('fill', 'red');
}
else {
text.set('fill', 'black');
}
canvas.on('after:render', function() {
canvas.contextContainer.strokeStyle = '#555';
canvas.forEachObject(function(obj) {
var bound = obj.getBoundingRect();
canvas.contextContainer.strokeRect(
bound.left + 0.5,
bound.top + 0.5,
bound.width,
bound.height
);
})
});
canvas.add(text);
canvas.add(text2);
https://jsbin.com/menadejato/edit?js,console,output
I am having a situation where I am drawing a ellipse in fabric.js from originX='right' and
afterwards changing it to originX='left'.
What I see is after changing the originX to left and adjusting the left by the following calculation :
ellipse.left -= ellipse.width
I still see a difference in the left positions.
To explain it , I added a fiddle where I added a timeout of 3 seconds before changing the originX. So, please open the fiddle and wait 3 seconds and see how the position changes which ideally shouldn't .
Any mistakes I am doing or any suggestions ?
Code :
var canvas = new fabric.Canvas('paper');
var ellipse = new fabric.Ellipse({
left: 300,
top: 10,
rx: 145,
ry: 65,
strokeWidth: 4,
stroke: 'blue',
fill: '',
originX: 'right',
originY: 'top'
});
canvas.add(ellipse);
canvas.renderAll();
var log = document.getElementById('log');
log.innerHTML = ellipse.left;
//changing the origin
setTimeout(function() {
ellipse.originX = 'left';
ellipse.left -= ellipse.width;
canvas.renderAll();
log.innerHTML += ', ' + ellipse.left;
}, 3000);
Since, the ellipseĀ's stroke has some width to it, hence, you would also need to exclude that, from ellipseĀ's left position, like so ...
ellipse.left -= ellipse.width + ellipse.strokeWidth;
or
ellipse.left = ellipse.left - ellipse.width - ellipse.strokeWidth;
Here is the revised version of your code ...
var canvas = new fabric.Canvas('paper', {
isDrawingMode: false
});
var ellipse = new fabric.Ellipse({
left: 300,
top: 10,
rx: 145,
ry: 65,
strokeWidth: 4,
stroke: 'blue',
fill: false,
originX: 'right',
originY: 'top'
});
canvas.add(ellipse);
canvas.renderAll();
var log = document.getElementById('log');
log.innerHTML = ellipse.left;
//changing the origin
setTimeout(function() {
ellipse.originX = 'left';
ellipse.left -= ellipse.width + ellipse.strokeWidth;
canvas.renderAll();
log.innerHTML += ', ' + ellipse.left;
}, 3000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.min.js"></script>
<canvas id="paper" width="400" height="400" style="border:1px solid #ccc"></canvas>
<div id='log'></div>
I am trying to use FabricJS to animate any object when it is selected.
So when selected an object 'shrinks' from center on mouse:down (10px off the width and 10px off the height)
And on mouse:up it returns to the original size and state.
I don't know if I need to use FabricJS built in animation for this. I wanted it to grow and shrink linear though.
Right now my Fiddle does pretty much nothing, I can't get far enough without errors.
Does anyone have any examples of this or similar? I couldn't find anything about changing the appearance of FabricJS objects on mouse:up/:down when selected.
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
var touchedObject;
var rect = new fabric.Rect({
left: 50,
top: 50,
width: 50,
height: 50,
fill: 'blue',
hasBorders: false,
});
canvas.add(rect);
var rect2 = new fabric.Rect({
left: 190,
top: 50,
width: 50,
height: 50,
fill: 'red',
hasBorders: false,
});
canvas.add(rect2);
canvas.on('object:selected', function(evn) {
/*animate({
'width': ,
'height':
}, {
duration: 200,
});*/
});
canvas.renderAll();
})();
You could accomplish that using the fabric.util.animate() method.
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
var touchedObject;
var rect = new fabric.Rect({
left: 50,
top: 50,
width: 50,
height: 50,
fill: '#07C',
hasBorders: false,
});
canvas.add(rect);
// disable controls and set hover-cursor
canvas.forEachObject(function(o) {
o.hasBorders = o.hasControls = false;
});
canvas.hoverCursor = 'pointer';
// mouse events
canvas.on('mouse:down', function(e) {
animate(e, 1);
});
canvas.on('mouse:up', function(e) {
animate(e, 0);
});
function animate(e, p) {
if (e.target) {
fabric.util.animate({
startValue: e.target.get('height'),
endValue: e.target.get('height') + (p ? -10 : 50 - e.target.height),
duration: 200,
onChange: function(v) {
e.target.setHeight(v);
canvas.renderAll();
},
onComplete: function() {
e.target.setCoords();
}
});
fabric.util.animate({
startValue: e.target.get('width'),
endValue: e.target.get('width') + (p ? -10 : 50 - e.target.width),
duration: 200,
onChange: function(v) {
e.target.setWidth(v);
canvas.renderAll();
},
onComplete: function() {
e.target.setCoords();
}
});
fabric.util.animate({
startValue: e.target.get('top'),
endValue: e.target.get('top') + (p && 5),
duration: 200,
onChange: function(v) {
e.target.setTop(v);
canvas.renderAll();
},
onComplete: function() {
e.target.setCoords();
}
});
fabric.util.animate({
startValue: e.target.get('left'),
endValue: e.target.get('left') + (p && 5),
duration: 200,
onChange: function(v) {
e.target.setLeft(v);
canvas.renderAll();
},
onComplete: function() {
e.target.setCoords();
}
});
}
}
canvas.renderAll();
})();
#canvas {
border: 1px solid lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
<canvas id="canvas" width="150"></canvas>
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;
});
I have got a lot of helps from this site and contributors here, thanks. Now I have a question about the Rectangle in Fabric.js with stroke, as I used it as kind of placeholder for images and text, when I scaled it, the border line width is scaled too, I think it's kind a problem as I want to keep the border width not changed.
var canvas = new fabric.Canvas("c1");
var el = new fabric.Rect({
originX: "left",
originY: "top",
left: 5,
top: 5,
stroke: "#ccc",
strokWidth: 1,
fill: 'transparent',
opacity: 1,
width: 200,
height: 200,
cornerSize: 6
});
canvas.add (el);
canvas.renderAll ();
See example here http://jsfiddle.net/9yb46/, try scale it horizontally. And a image is here too, and see the left border and right border width, supposed as same as top and bottom border, but not:
This can be done so that you can scale independently.
In the scaling event check the width, height and scale factors, set the height and width to the new effective values and reset the scaleX and scaleY.
This quite probably will break other things that are scaled with the object so you'd have to handle those attributes in a similar fashion.
Demo Fiddle.
var canvas = new fabric.Canvas("c1");
var el = new fabric.Rect({
originX: "left",
originY: "top",
left: 5,
top: 5,
stroke: "rgb(0,0,0)",
strokeWidth: 1,
fill: 'transparent',
opacity: 1,
width: 200,
height: 200,
cornerSize: 6
});
el.on({
'scaling': function(e) {
var obj = this,
w = obj.width * obj.scaleX,
h = obj.height * obj.scaleY,
s = obj.strokeWidth;
obj.set({
'height' : h,
'width' : w,
'scaleX' : 1,
'scaleY' : 1
});
}
});
canvas.add (el);
canvas.renderAll ();
First of all you have miss-typed the name of the property in your fiddle : strokWidth - e is missing. But this is not the cause of the problem since the default value for the strokeWidth is 1.
The scaled stroke issue is the expected behavior and what you ask to do is not. Anyway, before you check my code, read here and here and maybe some more here.
Then try this code to help with your needs, this will work perfectly only if you keep the scale ratio of your rectangle as 1:1 (scaleX = scaleY).
This is jsfiddle:
var canvas = new fabric.Canvas("c1");
var el = new fabric.Rect({
originX: "left",
originY: "top",
left: 5,
top: 5,
stroke: "rgb(0,0,0)",
strokeWidth: 1,
fill: 'transparent',
opacity: 1,
width: 200,
height: 200,
cornerSize: 6
});
el.myCustomOptionKeepStrokeWidth = 1;
canvas.on({
'object:scaling': function(e) {
var obj = e.target;
if(obj.myCustomOptionKeepStrokeWidth){
var newStrokeWidth = obj.myCustomOptionKeepStrokeWidth / ((obj.scaleX + obj.scaleY) / 2);
obj.set('strokeWidth',newStrokeWidth);
}
}
});
canvas.add (el);
canvas.renderAll ();
Fabricjs now has a strokeUniform property on fabric.Rect that can be used to prevent the stroke width from mis-transforming.
When you set strokeUniform to false it will scale with the object if true it will match the pixel size of the stroke width.
var el = new fabric.Rect({
originX: "left",
originY: "top",
left: 5,
top: 5,
stroke: "#ccc",
strokWidth: 1,
fill: 'transparent',
opacity: 1,
width: 200,
height: 200,
cornerSize: 6,
strokeUniform: true
});