Fabric.js / fabricjs in Svelte, is there any workaround? - html5-canvas

I have tried this code in REPL but couldn't find any working example. I am trying to free drawing on canvas using fabric pencil brush, however, this is only a rectangle:
<script>
const fabric = () => {
fabric = new window.fabric();
}
function drawMD(){
let canvas = new fabric.Canvas('c')
let rect = new fabric.Rect({
left:150, top, 150, fill: 'red, width: 200, height: 200, angle: 45
})
canvas.add(rect)
}
</script>
<svelte:head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/500/fabric.min.js" on:load={fabric}></script>
</svelte:head>
<div className="MarkdownEditor">
<canvas id="c" width="600" height="600" style="border:1px solid #000000;" on:click={drawMD}>
</canvas>
</div>

You don't need the window part, there are some typos in the Rect object and className won't work in Svelte. If you want to directly draw without having to click on the canvas, you can do this inside onMount. Here's a working REPL
(when opening the REPL there might be an errorfabric is not defined - just move the <svelte:head> one line down, then it's working...)
<svelte:head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/500/fabric.min.js"></script>
</svelte:head>
<script>
import {onMount} from 'svelte'
onMount(() => {
let canvas = new fabric.Canvas('c2')
let rect = new fabric.Rect({
left:120, top: 10, fill: 'teal', width: 150, height: 150, angle: 45
})
canvas.add(rect)
})
function drawMD(){
let canvas = new fabric.Canvas('c')
let rect = new fabric.Rect({
left:120, top: 10, fill: 'red', width: 150, height: 150, angle: 45
})
canvas.add(rect)
}
</script>
<div class="MarkdownEditor">
<canvas id="c" width="250" height="250" style="border:1px solid #000000;" on:click={drawMD}></canvas>
</div>
<canvas id="c2" width="250" height="250" style="border:1px solid #000000;"></canvas>

Related

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!

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

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>

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