Why fabric.Path on FabricJS is display different from svg file? - html5-canvas

I want to display an path in Fabric.JS, in svg file:
<g>
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;"
d="M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72"/>
</g>
And code in my Fabricjs
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill: 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
But result is not same:
Expected:
Path in FabricJS display same as in SVG file.
Here is my code:
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
// fill : 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
canvas.add(Path_0_1);
canvas.moveTo(Path_0_1, 1);
setObjectCoords();
canvas.renderAll();
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
And here is my svg file:
https://svgur.com/s/Bw6

Set fill value '' || null || 'transparent', so on ctx.fill() it wont fill anything to the object.
DEMO
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill : null,
stroke: '#000000',
});
canvas.add(Path_0_1);
#canvasContainer {
width: 100%;
height: 100vh;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>

Related

How to increase touch area control points on mobile device ( not increase display size of control points ) in fabricjs?

How to increase touch area of control points on mobile device with FabricJS? Because on mobile they are too small for smooth interactive with. But not change size of control points ( for nice view ).
Here is my code:
How to increase interactive of control points = view control points size x 2 ?
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
// test customize control points
var rect = new fabric.Rect({
left: 30,
top: 30,
fill: 'red',
width: 150,
height: 150
});
canvas.add(rect);
rect.set({
transparentCorners: false,
cornerColor: 'white',
cornerStrokeColor: 'rgba(14,19,24,.15)',
borderColor: 'rgba(41,198,203,1)',
selectionLineWidth: 8,
cornerSize: 12,
cornerStyle: 'circle',
});
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.3.2/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
Please show me the way to resolve this problem.
By the way: ( on mobile device ) is there any way to allow drag object only object is selected before?
Thank you very much!
You need to override _setCornerCoords method of object and change the value of cornerHypotenuse.
DEMO
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
// test customize control points
var rect = new fabric.Rect({
left: 30,
top: 30,
fill: 'red',
width: 150,
height: 150
});
canvas.add(rect);
rect.set({
transparentCorners: false,
cornerColor: 'white',
cornerStrokeColor: 'rgba(14,19,24,.15)',
borderColor: 'rgba(41,198,203,1)',
selectionLineWidth: 8,
cornerSize: 5,
cornerStyle: 'circle'
});
rect._setCornerCoords = function() {
var coords = this.oCoords,
newTheta = fabric.util.degreesToRadians(45 - this.angle),
cornerHypotenuse = this.cornerSize * 2 * 0.707106,
cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),
sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),
x, y;
for (var point in coords) {
x = coords[point].x;
y = coords[point].y;
coords[point].corner = {
tl: {
x: x - sinHalfOffset,
y: y - cosHalfOffset
},
tr: {
x: x + cosHalfOffset,
y: y - sinHalfOffset
},
bl: {
x: x - cosHalfOffset,
y: y + sinHalfOffset
},
br: {
x: x + sinHalfOffset,
y: y + cosHalfOffset
}
};
}
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.3.2/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>

FabricJS not render SVG correct when SVG include text with custom font?

I have a problem with render SVG in fabricjs when SVG include text with custom font.
How to make SVG in Fabricjs display correct with custom font?
Here is my code:
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: null,
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var imageObj = new fabric.Image();
canvas.add(imageObj);
imageObj.setSrc('https://futushigame.firebaseapp.com/group_test.svg', function(imageObject) {
imageObject.set({top: 0, left: 0});
imageObject.set('dirty', true);
canvas.renderAll();
setObjectCoords();
});
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<style>
#font-face {
font-family: 'CurlzMT';
src: url("https://futushigame.firebaseapp.com/CurlzMT.ttf") format("ttf");
font-weight: 'normal';
font-style: 'normal';
}
</style>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
Here is my resources:
1. Font file: CurlzMT
2. SVG file: group_test.svg
Thank you!
You need to embed the font in svg file.
The content of the svg must be like this
https://files.fm/f/qhvbe8jj

How to mapping "letter-spacing" value from text node of SVG to "charSpacing" property of fabric.TextBox in FabricJS?

I have problem with how to re-presentation of node in SVG with "letter-spacing" in SVG document to fabric.TextBox.
In file SVG text node is:
<text transform="matrix(1 0 0 1 51.5211 22.2889)" style="fill:#3C2415; font-size:11px; letter-spacing:3;">MINH TUẤN</text>
And my fabric.TextBox is:
var textbox_0_1 = new fabric.Textbox("MINH TUẤN", {
width: 200,
fontSize: 11,
fill: "#3C2415",
editable: true,
textAlign: "center",
charSpacing: 3,
});
Here is display on SVG & FabricJS:
How to find correct charSpacing which is respectively with letter-spacing attribute in SVG's Text node ?
Notes:
In fabric.TextBox document write:
charSpacing :Number
additional space between characters expressed in thousands of em unit
And in document for SVG write:
(if no unit identifier is provided) values in user space — for example, "15"
And Here is my code:
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var textbox_0_1 = new fabric.Textbox("MINH TUẤN", {
top: 20,
left: 20,
width: 200,
fontSize: 11,
fill: "#000000",
editable: true,
textAlign: "center",
charSpacing: 3,
});
canvas.add(textbox_0_1);
setObjectCoords();
canvas.renderAll();
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
Thank you,
You need to parse from pixel to em.
DEMO
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
width: 300,
height: 100
});
var letterSpacing = 5, fontSize = 30;
var textbox = new fabric.Text("MINH TUẤN", {
top: 20,
fontSize: fontSize,
fill: "#000000",
fontFamily : "Verdana"
});
canvas.add(textbox);
var parsedSpacing = fabric.util.parseUnit(letterSpacing, fontSize) / fontSize * 1000;
textbox.set({charSpacing : parsedSpacing});
canvas.requestRenderAll();
console.log(parsedSpacing)
canvas{
border:1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<svg width="300" height="100" viewBox="0 0 300 100">
<text font-size="30" letter-spacing="5" font-family="Verdana" y="40">MINH TUẤN</text>
</svg>
<canvas id="editorCanvas"></canvas>

How to create an Editable Text which is curved along a Path in Fabricjs?

I want to make Editable Text which is curved along a fabric.Path as bellow expected image.
Here is my code:
I created a curved fabric.Path & a fabric.TextBox, but I don't know how to curve text along that Path. Please help me resolve this problem.
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M127.91,99.29c32.16,10.73,53.41,7.33,67.81,0 c34.07-17.34,41.99-62.82,60.98-60.98c8.19,0.79,14.11,9.98,17.91,17.91', {
fill : null,
stroke: '#000000',
});
canvas.add(Path_0_1);
var curvedText = new fabric.IText("Anh Minh", {
left: 50,
top: 50,
width: 200,
fontSize: 24,
fontFamily: 'Times New Roman',
fontWeight: 'normal',
textAlign: 'center',
lineHeight: 1,
fill: "#404041",
});
canvas.add(curvedText);
#canvasContainer {
width: 100%;
height: 500px;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
Addition information:
After few hours google search, I see an interesting Konva.TextPath, I wonder If can we make same Object like that Konva.TextPath in Fabric.js?
Thank you!

Fabric.js - Rotate change the position of object

I would rotate an object on FabricJS canvas, but when I rotate, its position changed. And I can't use center origin, just left/top, beacuse I save coordinates to database reference by left/top position.
Can you help me? Any idea?
Here is the example.
Thanks
var canvas = window._canvas = new fabric.Canvas('c');
canvas.add(new fabric.Triangle({
width: 100,
height: 100,
left: 0,
top: 0,
angle: 0,
fill: '#00AC6B'
}));
function rotateObject(angleOffset) {
var obj = canvas.getActiveObject();
if (!obj) return;
var angle = obj.getAngle() + angleOffset;
angle = angle > 360 ? 90 : angle < 0 ? 270 : angle;
obj.setAngle(angle).setCoords();
canvas.renderAll();
document.getElementById('log').innerHTML += 'Left: ' + obj.left + ', top: ' + obj.top + '<br>';
}
fabric.util.addListener(document.getElementById('rotate-left'), 'click', function () {
rotateObject(-90);
});
fabric.util.addListener(document.getElementById('rotate-right'), 'click', function () {
rotateObject(90);
});
canvas {
border: 1px solid #999;
}
.log {
height: 220px;
overflow: auto;
border: 1px solid #999;
padding: 5px;
margin-top: 10px;
}
<script src="https://rawgit.com/kangax/fabric.js/1.x/dist/fabric.js"></script>
<canvas id="c" width="400" height="400"></canvas>
<div>
<button id="rotate-left">Rotate left</button>
<button id="rotate-right">Rotate right</button>
</div>
<div id="log" class="log">
</div>

Resources