fabric.js cannot get the text aligned witht the textAlign - javascript

I cannot get the textAlign working in fabric.js The fontSize, fontBackground work properly, but not textAlign. Am I missing something?
var canvas = new fabric.Canvas('myCanvas');
$('button.addText').click(function() {
var text = new fabric.Text($(this).siblings().val(), {
textAlign: 'center',
fontSize: 40
});
canvas.add(text);
});

var canvas = new fabric.Canvas('myCanvas');
var align = ["left", "center", "right" , "justify"];
var el = document.getElementById('res');
var txt = 'FabricJS \n is \nAwsome';
var text = new fabric.Text(txt, {
textAlign: 'left', //"left", "center", "right" or "justify".
width:450,
fontSize: 40
});
canvas.add(text);
changeAlign();
function changeAlign(){
var val = align[Math.floor(Math.random() * align.length)];
text.set('textAlign',val);
el.innerHTML = 'Text Alignment : ' +val;
canvas.setActiveObject(text);
canvas.renderAll();
}
canvas {
border : 2px dotted blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.17/fabric.min.js"></script>
<canvas id="myCanvas" width="600" height="300"></canvas><br>
<button onclick='changeAlign()'>Change align</button><p id='res'></p>
#AndreaBogazzi He is right. In Text, box depends on the width of first line, if you want then it will work for multi line texts . Check Snippet.

I guess the main point is that if the text is one line only, fabric will size the text bounding box to the necessary length and there will not be any alignment to do.
If the text is multiline the alignment should work.
The alignment is INSIDE the box and is not the direction where the box grows when the text grows.

It depends on the type of the object. If you have for example IText or Text the alignment will work only in the area of the canvas itself.
For example if you want to align an IText type on the center of the canvas you would use:
canvas.getActiveObject().centerV();
canvas.getActiveObject().setCoords();
canvas.renderAll();
If you want to center the text itself it would apply only to Textbox type, you would then be able to use:
canvas.getActiveObject().textAlign = "center";

Related

Add background to text in Pixi.js?

Is there any way I can add a background to my text in Pixi.js? I'm looking for an effect like this:
Creating a background sprite, and giving it the same position and dimensions as the text object does not work here, as that would always give me a rectangle which is not what I want. I guess I could make on text object per line and use that approach, but since the text is arbitrarily set by the user I would have to work out my own linebreaking algorithm to be able to do that. That seems overly complicated.
Here is my code without any background (fiddle):
var app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x2c3e50
});
document.body.appendChild(app.view);
var text = new PIXI.Text("HELLO\nWORLD!", {
align: "center"
})
text.anchor.set(0.5);
text.x = app.renderer.width / 2;
text.y = app.renderer.height / 2;
app.stage.addChild(text);

Snap.svg and dynamic text

I'm trying to place text dynamically into an svg created by Snap, this is what I tried:
this.setContent(
`<svg id="${this.svgId}"></svg>`
);
var snap = Snap($(`#${this.svgId}`)[0]);
text = "asdfsdfsdsfd";
var rect = snap.paper.rect(0, 0, 50, text.length*3 + 4, 10);
snap.text(1.5,10, text);
console.log("rect", rect);
console.log("snap", snap);
rect.attr({
fill: "#FFFFFF",
fillOpacity: 0.6,
});
I get this:
I want the rectangle to be just a little bigger than the text, but there must be a better way to do it than to calculate the length and height of the text, and that's assuming the font size won't change.
This is the only result I found regarding text in the snap docs: http://snapsvg.io/docs/#Paper.text
You could try using getBBox() on the text element, and use that to figure the size of the rect. getBBox() wll give you the x,y,width,height,x2,y2 figures to help.
var text = s.text(0,0,'blah blah')
var bb = text.getBBox();
var rect = s.rect(bb.x, bb.y, bb.width, bb.height )
Adjusting with offsets for whatever padding etc that you want. You may also need to allow for stroke widths, as I don't think that's included.

interactive text box with fabricjs

I am working fabricjs textbox. I wrote the following code to change text options like font-size, font-weight, line-height.
My code is working but the problem is When I select a textbox object and change font-size or font weight or line height it does not work unless I click on canvas outside textbox.
But I want to change these value when I make change on input fields. My code are as following:
canvas = new fabric.Canvas('canvas');
// Add Text to Canvas
$('#canvasAddText').on('click', function(){
var _text = $('#canvasText').val();
var _color = $('#textColor').val();
var _fontSize = $('#fontSize').val();
var _fontWeight = $('#fontWeight').val();
var _lineHeight = $('#lineHeight').val();
var TextBox = new fabric.Textbox( _text, {
top: 30,
left: 30,
width: 200,
fill: _color,
fontSize: _fontSize,
fontWeight: _fontWeight,
lineHeight: _lineHeight,
fontFamily: 'Comic Sans',
textDecoration: 'none',
textAlign: 'left',
});
canvas.add(TextBox);
});
// Change Font Size
$('#fontSize').on('change', function (){
canvas.getActiveObject().setFontSize($(this).val());
});
// Change Font Weight
$('#fontWeight').on('change', function (){
canvas.getActiveObject().setFontWeight($(this).val());
});
// Change Line Height
$('#lineHeight').on('change', function (){
canvas.getActiveObject().setLineHeight($(this).val());
});
You should trigger object modified event and then renderAll() function to make sure changes reflect. Below is example code which you need to have for on change event of font size.
// Change Font Size
$('#fontSize').on('change', function (){
canvas.getActiveObject().setFontSize($(this).val());
canvas.trigger("object:modified",{target: canvas.getActiveObject()});
canvas.renderAll();
});

Fabricjs Textbox make the text shrink to fit

I would define a text box (single-line)
By default, with a character size of 16 (for example)
When the text gets bigger than the text box, I do not want it to wrap or the text box gets bigger, I want the text size to fit the maximum size of the text box. text. When the text returns to a smaller size, it can resume its initial size (in our example 16). Possibly manage a minimum size
If you have an idea, I take :)
thanks in advance
Test Case : http://jsfiddle.net/Da7SP/273/
// initialize fabric canvas and assign to global windows object for debug
var canvas = window._canvas = new fabric.Canvas('c');
// ADD YOUR CODE HERE
var canvas = window._canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('My Text', {
width: 200,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center'
});
var t2 = new fabric.Textbox('My text is longer, but I do not want the box to grow, or the text to wrap. I only want the text to fit the available size', {
width: 200,
height: 200,
top: 250,
left: 5,
fontSize: 16,
textAlign: 'center'
});
canvas.add(t1);
canvas.add(t2);
A small video to explain what I want :
When the text gets bigger than the text box, I want the text size fit the maximum size of the text box.
This is a basic fiddle that can replicate your idea.
The point is that you have an event that fires on every text change and that can be used to do something before the textbox is rendered.
In this case i m shrinking font size based on a non standard parameter i added to textbox called fixedWidth
// ADD YOUR CODE HERE
var canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('MyText', {
width: 150,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center',
fixedWidth: 150
});
canvas.on('text:changed', function(opt) {
var t1 = opt.target;
if (t1.width > t1.fixedWidth) {
t1.fontSize *= t1.fixedWidth / (t1.width + 1);
t1.width = t1.fixedWidth;
}
});
canvas.add(t1);
canvas {
border: 1px solid #999;
}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
Here's a similar answer to https://stackoverflow.com/a/41335051/1469525 but this example modifies the fontSize up to a maxFontSize (the initial fontSize). This allows the text to shrink and then grow back to the original size, as well as preventing line wraps.
(Note, if you use this, you'll have to find a way to prevent the user from using the enter key. I put in a check that basically cancels it if an enter key is detected. My app actually has a separate form to enter the text, so I can control prevention through normal javascript. I'm not quite sure how to do that directly on a canvas element when it is editable like here...)
var canvas = new fabric.Canvas('c');
var t1 = new fabric.Textbox('MyText', {
width: 150,
top: 5,
left: 5,
fontSize: 16,
textAlign: 'center',
maxFontSize: 16,
});
canvas.on('text:changed', function(opt) {
var t1 = opt.target;
if (t1.text.match(/[\r\n]/)) return;
t1.set({
fontSize: t1.maxFontSize,
});
while (t1._textLines.length > 1) {
t1.set({
fontSize: t1.fontSize - 1,
});
}
});
canvas.add(t1);
canvas {
border: 1px solid #999;
}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

jointjs rect text overflow

I'm using jointjs to draw diagrams.
My problem is that in my jointjs rect, the text inside is too long. The size of my rect is assumed fixed.
I have used joint.util.breakText to control the height and width, but the overflow disappears. And I have set the font-size small enough. How to fix this problem?
Thanks in advance.
I had a similar problem. In my case I have empty shapes. By click-event I can add a comment (text) to the shape. This example enlarges the shape's size and wraps the text inside additionally. Hope it helps!
function enterText(viewShape) {
var shapeText = prompt('Enter your new comment:', '');
if (viewShape.model.id === 'CommentID') {
//change comment text here
if (shapeText.length > 5) {
var wraptext = joint.util.breakText(shapeText, {
width: 200
//height: optionalHeight
});
//resize attribute and add it to paper
viewShape.model.resize(wraptext.length * 8, 67);
viewShape.model.attr('text/text', wraptext).attr('text/ref-y', 0.45);
} else {
viewShape.model.attr('text/text', shapeText).attr('text/ref-y', 0.45);
}
}
}

Categories