Fabric.js: Text position at right half of canvas (horizontal center) - fabricjs

"centerH()" positions the text at the horizontal center of the complete canvas size. I want to center my text at the right half (as if 50% of the left canvas was cropped). I could implement a while loop which always checks the distance to the right and left until it is equal but maybe there is an easier way to do this?

You can set left of text as half of canvas width.
text.set({
left:canvas.width/2
});
var canvas = new fabric.Canvas('canvas');
var text = new fabric.Text('FabricJS',{
left:10,top:20
});
canvas.add(text);
function setToCenter(){
text.set({
left:canvas.width/2
});
text.setCoords();
canvas.requestRenderAll();
}
canvas {
border: 1px solid #999;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<button onclick='setToCenter()'>Center</button>
<canvas id="canvas" width="400" height="400"></canvas>

Related

FabricJS 2 - Image isn't stretching to the given width

I have just upgraded from fabric 1.7 to 2 and now the image object is behaving differently.See the screenshot, the image where the arrow is is completely ignoring the fact that i set a width on it, it looks like it's actually scaling it based on the given height to keep the image ratio. I don't want this to happen, the image needs to stretch to the size i tell it to.
Anyone have any idea to stop it doing this? I mean if i set a width in the options for the image object i expect it to respect those dimensions. It should be stretching to fill where the red box is.
This is happening when loading the image initially as a square and setting {width:1000,height:400} for example, but instead it looks like it's taking the height and scaling the width down to keep it square.
You need to set scaleX for width and scaleY for height. It's a breaking change for v2.
DEMO
var canvas = new fabric.Canvas('c');
var index = 0,
json;
var url = '//fabricjs.com/assets/pug.jpg';
fabric.Image.fromURL(url, function(img) {
var elWidth = img.naturalWidth || img.width;
var elHeight = img.naturalHeight || img.height;
img.set({
scaleX:200/elWidth,
scaleY:200/elHeight
})
canvas.add(img);
})
canvas{
border:2px solid #000;
}
<script type="text/javascript" src="
https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="400" height="400"></canvas>

Setting Control Visibility for Drawn Objects

I have a fabricjs canvas with a button that toggles drawing on and off. How can I apply the custom controls to any/all drawn objects that I draw; for example, I'd like to select any of the lines that I draw and only be able to rotate them. I've read the example but must be missing something. How would I accomplish this?
JSFiddle of what I'm working with now
Use cornerStyle to change corner style(rect/circle) and setControlsVisibility to set visibility of controls.
DEMO
var canvas = this.__canvas = new fabric.Canvas('canvas', {
backgroundColor: 'white',
centeredScaling: true,
isDrawingMode: true
});
fabric.Object.prototype.cornerStyle = 'circle';//default rect
fabric.Object.prototype.setControlsVisibility({
tl:false, //top-left
mt:false, // middle-top
tr:false, //top-right
ml:false, //middle-left
mr:false, //middle-right
bl:false, // bottom-left
mb:false, //middle-bottom
br:false //bottom-right
})
$("#drawButton").click(function() {
canvas.isDrawingMode = !canvas.isDrawingMode;
var val = canvas.isDrawingMode ? 'selection' : 'pen_tool';
$("#select").text(val);
});
canvas {
border:1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<canvas id="canvas" height="400" width="400"></canvas>
<button class="btn" id='drawButton' value="True"><span><i id="select" class="material-icons">selection</i></span></button>

Fabricjs textbox for large text content stuck in first line

In fabricjs textbox if text content(no space) is larger than the textbox width it won't go to next line, it stuck at first line. So that I get the content width using text:changed event and try to press enter programmatically if content is greater than textbox width but its not working. Is there any other way?
I don't want to override fabricjs default method for breakwords it has other conflicts and cursor get misplaced.
var canvas = new fabric.Canvas('c');
var text1 = new fabric.Textbox('Text', {
left: 10,
top: 20,
width: 300
})
canvas.add(text1);
canvas.on('text:changed', function(e) {
if (e.target.width > 300) {
console.log("text over width");
$('#canvas').trigger(jQuery.Event('keypress', {
keyCode: 87,
which: 13
}));
}
});
canvas{
border:1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #000000;"></canvas>

Zoom issue with latest version of library

The below code snippets are identical, except for the version of FabricJS being used.
The first one uses version 1.4.13, the second uses the latest (1.7.3).
When clicking Zoom In on the first version, the black square remains exactly top-left (0, 0). So far, so good.
When doing the same on the second version, the black square "drifts" where you can see the pink background above and to the left of the black square.
Does anyone why this behaviour has changed, is there a workaround or other fix?
var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('http://placehold.it/640x480/dd0055/?text=FabricJS Demo', canvas.renderAll.bind(canvas), {
backgroundImageOpacity: 0.5,
backgroundImageStretch: false
});
canvas.add( new fabric.Rect({
left: 0,
top: 0,
width:100,
height:100,
fill:"rgb(0,0,0)"
}) );
canvas.renderAll();
$("#btnZoomIn").click(function(){
canvas.setZoom(canvas.getZoom()*1.3);
});
$("#btnZoomOut").click(function(){
canvas.setZoom(canvas.getZoom()/1.3);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.13/fabric.min.js"></script>
<button id="btnZoomIn">ZoomIn</button>
<button id="btnZoomOut">ZoomOut</button>
<br/>
<canvas id="c" width="640" height="480"></canvas>
var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('http://placehold.it/640x480/dd0055/?text=FabricJS Demo', canvas.renderAll.bind(canvas), {
backgroundImageOpacity: 0.5,
backgroundImageStretch: false
});
canvas.add( new fabric.Rect({
left: 0,
top: 0,
width:100,
height:100,
fill:"rgb(0,0,0)"
}) );
canvas.renderAll();
$("#btnZoomIn").click(function(){
canvas.setZoom(canvas.getZoom()*1.3);
});
$("#btnZoomOut").click(function(){
canvas.setZoom(canvas.getZoom()/1.3);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.3/fabric.min.js"></script>
<button id="btnZoomIn">ZoomIn</button>
<button id="btnZoomOut">ZoomOut</button>
<br/>
<canvas id="c" width="640" height="480"></canvas>
Being the main difference after fabric 1.5 the inclusion of strokeWidth in the object bounding box, i guess that if you initialize the fabric.Rect with strokeWidth: 0 OR with a stroke: 'blue' you will se that the object is not drifting, simply is moving from is left top corner.
What cause the drift is a transparent border that is growing in size.

Top-Left coordinates not updated on rotating image using fabricjs

When I rotate an image in fabricjs, the top-left corner's coordinates are not updated after rotated. Instead, the top-left corner of the image still refers to the old point. I believe that it should recalculate the top-left corner based on the image's new position. Is there a way to achieve this? Any help is appreciated!
Below is the code for image rotation:
function rotate(){
activeCanvas.forEachObject(function(obj){
if(obj instanceof fabric.Image){
curAngle = obj.getAngle();
obj.setAngle(curAngle-90);
}
});
activeCanvas.renderAll();
}
Now, after the rotation, I want top-left coordinates of the new rotated image but it still returns top and left from the old image state.
For example, let say the image's top-left corner was originally at (100,200) and the image's dimensions are 500x600. Now, if I rotate the image in 90 degrees, the new dimensions are 600x500 and the top-left corner changes as well, as the image is rotated related to its center. But the fabricjs image still refers to the old top-left corner. Is there any method just like setCoords() to get the new upper left corner point as its top left?
As you can see from the snippet below, if you only rotate your object, only the bounding box will be updated, you have to move your object to have the position of your object updated.
var canvas = this.__canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
left: 120,
top: 30,
width: 100,
height: 100,
fill: 'green',
angle: 20
});
canvas.on("object:rotating", function() {
var ao = canvas.getActiveObject();
if(ao){
console.log('top and left are the same after rotation');
console.log('top:' + ao.top);
console.log('left:' + ao.left);
console.log('but not the bounding box');
var bound = ao.getBoundingRect();
console.log('bounding box - top:' + bound.top);
console.log('bounding box - left:' + bound.left);
}
})
canvas.add(rect);
canvas.renderAll();
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<script src="https://seikichi.github.io/tmp/PDFJS.0.8.715/pdf.min.js"></script>
<canvas id="c" style="border:1px solid black"></canvas>
I guess you are looking for something like this:
canvas.on('object:rotating', function(options) {
options.target.setCoords();
var left = options.target.oCoords.tl.x,
top = options.target.oCoords.tl.y;
console.log(left, top);
});

Resources