Updating font size from an input to fabric js canvas generated text - fabricjs

i want to update the font size from this
<input value="1" id="fontSize" type="text">
input to
$("#fontSize").on("change", () => {
let fontsize = document.querySelector("#fontSize");
sizeFromInput = fontsize.value;
canvas.getActiveObject().set("fontSize", sizeFromInput);
canvas.renderAll();
});
this is my text generation function in fabric js
$("#typeTool").click(() => {
var textEditable = new fabric.Textbox("ASR Textbox", {
width: 500,
editable: true,
fontFamily: "Delicious_500",
left: 100,
top: 100,
fontSize: 18,
fill: "#000",
});
canvas.add(textEditable);
});

I think your code is working as expected.
Maybe you could use the input event for an instant update as the change event fires in most browsers when content is changed and the element loses focus.
It will not fire for every single change as in the case input event.
https://stackoverflow.com/a/17047588/5646527
var canvas = new fabric.Canvas('c');
canvas.renderAll.bind(canvas);
$("#fontSize").on("change", () => {
let fontsize = document.querySelector("#fontSize");
sizeFromInput = fontsize.value;
var activeObject = canvas.getActiveObject();
if (activeObject) {
activeObject.set("fontSize", sizeFromInput);
}
canvas.renderAll();
});
$("#typeTool").click(() => {
var textEditable = new fabric.Textbox("ASR Textbox", {
width: 50,
editable: true,
left: 10,
top: 10,
fontSize: 18,
fill: "#000",
});
canvas.add(textEditable);
canvas
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fabric#5.2.4-browser/dist/fabric.min.js"></script>
<button id="typeTool">Add Text</button>
<input type="text" id="fontSize" />
<br>
<canvas id="c" width="400" height="400"></canvas>
<br>
<p class="save">
</p>

Related

Can't manipulate grouped objects in fabric.js after loading from JSON

I'm trying to implement load/save functionality in a fabric.js project (using fabric.js 5.2.1). The canvas reloads correctly, but I can no longer interact with objects in groups. Non-grouped objects are fine, but pretty much everything in my project is in a group.
<input type="button" id="loadJSON" value="Load JSON" />
<input type="button" id="colorize2" value="Background" />
<input type="button" id="colorize3" value="Square" />
<input type="button" id="colorize" value="Line" />
<canvas id="below" width="960" height="448" style="position:absolute; top:10; left:10;"></canvas>
var jsonString = '{"version":"5.2.1","objects":[{"type":"rect","version":"5.2.1","originX":"left","originY":"top","left":100,"top":100,"width":100,"height":100,"fill":"orange","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"square","rx":0,"ry":0,"selectable":true,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true},{"type":"group","version":"5.2.1","originX":"left","originY":"top","left":477.7,"top":25.62,"width":5.25,"height":396.17,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"ElementGroup","selectable":false,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true,"objects":[{"type":"path","version":"5.2.1","originX":"left","originY":"top","left":-2.63,"top":-198.09,"width":4.25,"height":395.17,"fill":"yellow","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"centerLine01","selectable":false,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true,"path":[["M",478.19727,26.119141],["L",478.19727,421.29297],["L",482.45117,421.29297],["L",482.45117,26.119141],["L",478.19727,26.119141],["z"]]}]}],"background":"green","perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":false,"backgroundColor":"blue"}'
var below = new fabric.Canvas('below', {
enableRetinaScaling: false,
preserveObjectStacking: true,
backgroundColor: 'green'
});
rect = new fabric.Rect({
top: 100,
left: 100,
width: 100,
height: 100,
fill: 'blue',
id: 'square'
})
centerLine01 = new fabric.Path("M 478.19727 26.119141 L 478.19727 421.29297 L 482.45117 421.29297 L 482.45117 26.119141 L 478.19727 26.119141 z", {
fill: 'red',
id: 'centerLine01',
visible: true,
selectable: false,
evented: false
});
ElementGroup = new fabric.Group([centerLine01], {
id: 'ElementGroup',
visible: true,
selectable: false,
evented: false
})
below.add(rect)
below.add(ElementGroup)
below.renderAll()
$("#loadJSON").on("click", function(e) {
below.loadFromJSON(jsonString, below.renderAll.bind(below), function(o, object) {
below.add(object)
});
below.renderAll.bind(below)
console.log("JSON loaded!")
})
$("#colorize").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
ElementGroup.getObjects().forEach(function(o) {
if (o.id == "centerLine01") {
o.set("fill", randomColor)
below.renderAll()
}
})
})
$("#colorize2").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
below.setBackgroundColor(randomColor, below.renderAll.bind(below))
})
$("#colorize3").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
below.getObjects().forEach(function(o) {
if (o.id == "square") {
o.set("fill", randomColor)
below.renderAll()
}
})
})
In this sample, the Background, Square and Line buttons all work out of the gate, but as soon as you reload the canvas from JSON the Line button no longer does anything, even though the object is still getting found (a simple console.log() verifies that). Not quite sure what the issue is, though.
jsfiddle here: https://jsfiddle.net/eriqjaffe/jo25d8qs/8/

Fabricjs, selection handles shown but not clickable before selected together with other shapes

I'm trying to develop a vue.js component to draw shapes with fabricjs.
After a rectangle been drawn, it is selectable, but can't be resized or rotated with the selection handle, which is not what I was expecting. I think it has something to do with vue.js 3, because everything works with vue.js 2.
In this demo at JSFiddle, corner handles won't work on rectangles, untill after you have selected the rectangle together with other shapes.
<div id="app">
<canvas ref="c"></canvas>
<div>
<button type="button" #click="add('red')">
Add
</button>
Select the blue rectangle. The corner handles are visible but not working.
Now, click "add“, then select both rectangles. Then just select any single item, now the corner handles are working.
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.2.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.global.js"></script>
var vm = Vue.createApp({
data: () => ({
canvas: null
}),
mounted: function() {
var c = this.$refs.c
this.canvas = new fabric.Canvas(c, {
width: c.clientWidth,
height: c.clientHeight
});
this.add('blue')
},
methods: {
add(color) {
this.canvas.add(new fabric.Rect({
top: 20,
left: 20,
width: 40,
height: 40,
fill: color
}))
}
}
}).mount('#app');
// Select the blue rectangle. The corner handles are visible but not working.
// Now, click "add", then select both rectangles.
// Then just select any single item, now the corner handles are working.
How do I work around this while sticking to vue.js 3?
Fabricjs does not like having the canvas converted to a proxy. One way to get around it is to use a global variable instead of using the data. You can also just remove canvas from the data() declaration, which will make it still accessible throughout the template and code, but not make it reactive.
Example:
var vm = Vue.createApp({
mounted: function() {
var c = this.$refs.c
this.canvas = new fabric.Canvas(c, {
width: c.clientWidth,
height: c.clientHeight
});
this.add('blue')
},
methods: {
add(color) {
this.canvas.add(new fabric.Rect({
top: 20,
left: 20,
width: 40,
height: 40,
fill: color
}))
}
}
}).mount('#app');
<div id="app">
<canvas ref="c"></canvas>
<div>
<button type="button" #click="add('red')">
Add
</button>
Select the blue rectangle. The corner handles are visible but not working.
Now, click "add“, then select both rectangles. Then just select any single item, now the corner handles are working.
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.global.prod.js"></script>
You can use toRaw(). The function can change proxy object to common object.
add(color) {
toRaw(this.canvas).add(new fabric.Rect({
top: 20,
left: 20,
width: 40,
height: 40,
fill: color
}))
}

Center Fabricjs iText produces a blurry effect

I'm trying to add an IText element to the center of the canvas, but when I call the canvas.centerObject(object) method, the text gets blurred.
You have an example in this fiddle.
var canvas = new fabric.Canvas('canvas',{
width:400,
height:400
});
canvas.setBackgroundColor('#f4f2f2', canvas.renderAll.bind(canvas));
$('#add-text-btn').click(function() {
var text = new fabric.IText('Tap and Type', {
fill: '#333',
fontSize: 14,
});
canvas.add(text);
})
$('#add-ugly-text-btn').click(function() {
var text = new fabric.IText('Tap and Type', {
fill: '#333',
fontSize: 14,
});
canvas.add(text);
//canvas.centerObject(text);
text.center();
text.setCoords();
canvas.renderAll();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.3/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add-text-btn">Add text</button>
<button id="add-ugly-text-btn">Add centered text</button><br>
<canvas id="canvas"></canvas>

setText() not working in fabricjs version 2

I am trying to set text to textbox explicitly,in older fabricjs versionobject.setText("something")
was working but not working in fabric js version 2. Any other way introduced in this version?
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) {
var objTEmp = e.target;
objTEmp.setText("some");
});
canvas{
border:1px solid #000;
}
<script type="text/javascript" src="
https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-rc.4/fabric.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #000000;"></canvas>
That build doesn't have setter/getter (optional). If you want to set text you can use
obj.text = text;
//or
obj.set({
text:text
});
//or
obj.set('text', text);
DEMO
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) {
var objTEmp = e.target;
objTEmp.set({
text : "some"
});
});
canvas{
border:1px solid #000;
}
<script type="text/javascript" src="
https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-rc.4/fabric.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #000000;"></canvas>
You can build your own version of Fabric.js here: http://fabricjs.com/build/
Check "Named accessors" to bring back support for setters and getters. Not recommended and unsupported, who knows how long it will stay in there, but if you just need a quick solution now, that will do the trick.

Fabric JS canvas objects below remote image not selectable

I'm trying to setup FabricJS but canvas become unselectable below remote images.
I figured it out, that selection area is calculated before images are loaded and then canvas is "pushed" below images, so its objects becomes unselectable. This only occurs when you refresh page. When you enter new link everything is fine.
<body>
<div class="product thumbnail">
<a href="remoteimage">
<img src="remoteimage" alt="1232g" />
1232g
</a>
</div>
<div>
<canvas id="canvas-id"></canvas>
</div>
<script>
$(function() {
var canvas = new fabric.Canvas('canvas-id');
// create a rectangle with angle=45
var circle = new fabric.Circle({
radius: 20, fill: 'red', left: 100, top: 100
});
var triangle = new fabric.Triangle({
width: 20, height: 30, fill: 'blue', left: 50, top: 50
});
canvas.add(circle, triangle);
});
</script>
</body>
How to setup FabricJS properly in this scenario ?
I think this is what you are talking about
var canvas = new fabric.Canvas('c');
var imgElement = document.getElementById('my-img');
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 30,
opacity: 0.85
});
canvas.add(imgInstance);
You can check the documentation here : http://fabricjs.com/fabric-intro-part-1/ in the Images Section

Resources