I have a textbox in which I put text content at the time of adding it over canvas and want to make it active. so that user can start writing after the default text added. I have added enterEditing() which active textbox but move cursor at the beginning.
var object = canvas.getActiveObject('textbox');
canvas.setActiveObject(object);
object.setText("Start");
object.enterEditing();
Use setSelectionStart(length) and setSelectionEnd(length); to set the cursor upto the end of the text.
DEMO
var canvas = new fabric.Canvas('c');
var newText = new fabric.Textbox('Type \n here...', {
fontSize: 27,
top: 10,
left: 10,
width: 200
});
canvas.add(newText);
canvas.setActiveObject(newText);
newText.enterEditing();
newText.setSelectionStart(newText.text.length);
newText.setSelectionEnd(newText.text.length);
canvas{
border: 2px solid #000;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width=300 height=300></canvas>
Related
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
}))
}
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>
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.
I have more than one textbox. When I group all textboxes and scale the group horizontally height of group is not increase dynamically and content of textbox get vanish unlike independent textbox which increase height till the content end.
Below code I tried to set same height of group as of textbox but not working. Any Suggestion ?
var canvas = new fabric.Canvas('c');
var text1 = new fabric.Textbox('Text', {
left: 10,
top: 20,
fontSize : 18,
width: 300
})
canvas.add(text1);
var text2 = new fabric.Textbox('If this textbox grouped with above textbox, height will not increase on scaling horizontally and content get vanished but if scalling independently height increase', {
left: 20,
top: 40,
fontSize : 18,
width: 300
})
canvas.add(text2);
canvas.on('object:scaling', function(e) {
/* if(e.target.type == "group"){
var obj=e.target;
obj.height=obj.item(0).height;
obj.width=obj.item(0).width;
}*/
});
canvas{
border:1px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.9/fabric.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #000000;"></canvas>
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