fabric.js: Curved Text
Works with FabricJS 1.7.x.
by Anuraj MS
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<tr>
<td>Text</td>
<td><input type="text" id="text" value="Lorem ipsum di samet"></td>
</tr>
<tr>
<td>Diameter</td>
<td><input type="range" id="diameter" min="100" max="2500" value="250" step="1"></td></tr>
<tr>
<td>Font size</td>
<td><input type="range" id="fontSize" min="8" max="100" value="24" step="1"></td>
</tr>
<tr>
<td>Kerning</td>
<td><input type="range" id="kerning" min="-10" max="10" value="0" step="1"></td>
</tr>
<tr>
<td>Flip</td>
<td><input type="checkbox" id="flip" value="1"></td>
</tr>
<tr>
<td></td>
<td><button type="button" id="newObject">Add to Canvas</button></td>
</tr>
</table>
<hr>
<div id="canvasContainer">
<canvas id="c" width="450" height="450"></canvas>
</div>
CSS
body, input, button {
font: 12pt Arial, Helvetica;
}
#canvasContainer {
background-image: url(data:image/gif;base64,R0lGODlhCgAKAIAAAOLi4v///yH5BAAHAP8ALAAAAAAKAAoAAAIRhB2ZhxoM3GMSykqd1VltzxQAOw==);
border: 2px solid #ccc;
display: inline-block;
}
input[type=range], input[type=text] {
width: 200px;
}
JavaScript
(function(fabric) {
/*
* CurvedText object for fabric.js
* @author Arjan Haverkamp (av01d)
* @date January 2018
*/
fabric.CurvedText = fabric.util.createClass(fabric.Object, {
type: 'curved-text',
editable:true,
diameter: 250,
kerning: 0,
text: '',
flipped: false,
fill: '#000',
fontFamily: 'Times New Roman',
fontSize: 24, // in px
fontWeight: 'normal',
fontStyle: '', // "normal", "italic" or "oblique".
cacheProperties: fabric.Object.prototype.cacheProperties.concat('diameter', 'kerning', 'flipped', 'fill', 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'strokeStyle', 'strokeWidth'),
strokeStyle: null,
strokeWidth: 0,
initialize: function(text, options) {
options || (options = {});
this.text = text;
this.callSuper('initialize', options);
this.set({lockUniScaling: true,editable:true});
// Draw curved text here initially too, while we need to know the width and height.
var canvas = this.getCircularText();
this._trimCanvas(canvas);
this.set('width', canvas.width);
this.set('height', canvas.height);
},
_getFontDeclaration: function()
{
return [
// node-canvas needs "weight style", while browsers need "style weight"
(fabric.isLikelyNode ? this.fontWeight : this.fontStyle),
(fabric.isLikelyNode ? this.fontStyle : this.fontWeight),
this.fontSize + 'px',
(fabric.isLikelyNode ? ('"' + this.fontFamily + '"') : this.fontFamily)
].join(' ');
},
_trimCanvas: function(canvas)
{
var ctx = canvas.getContext('2d'),
w = canvas.width,
h = canvas.height,
pix = {x:[], y:[]}, n,
imageData = ctx.getImageData(0,0,w,h),
fn = function(a,b) { return a-b };
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
if (imageData.data[((y * w + x) * 4)+3] > 0) {
pix.x.push(x);
pix.y.push(y);
}
}
}
pix.x.sort(fn);
pix.y.sort(fn);
n = pix.x.length-1;
w = pix.x[n] - pix.x[0];
h = pix.y[n] - pix.y[0];
var cut = ctx.getImageData(pix.x[0], pix.y[0], w,...