Curved Text
by Steve Eberhardt
HTML
<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="400"></canvas>
CSS
canvas {
border: 1px solid #999;
}
JavaScript
var canvas = new fabric.Canvas('c');
var path = new fabric.Path('M 0 0 A 20 20 0 0 1 300 0', {
strokeWidth: 2,
stroke: 'red',
left: 100,
top: 150,
fill: 'transparent'
});
var text = new fabric.Text('One Ring to rule them', {
path: path,
fontSize: 44,
left: 100,
top: 150,
startOffset: 0.1
});
canvas.add(path);
canvas.add(text);
fabric.Text.prototype._measureLine = function(lineIndex) {
var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,
graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length),
positionInPath = 0, startingPoint, totalPathLength, path = this.path;
this.__charBounds[lineIndex] = lineBounds;
if (path) {
startingPoint = fabric.util.getPointOnPath(path.path, 0, path.segmentsInfo);
totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length;
startingPoint.x += path.pathOffset.x;
startingPoint.y += path.pathOffset.y;
positionInPath = this.startOffset ? this.startOffset * totalPathLength : 0;
}
for (i = 0; i < line.length; i++) {
grapheme = line[i];
graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);
if (path) {
if (positionInPath > totalPathLength) {
positionInPath %= totalPathLength;
}
// it would probably much fater to send all the grapheme position for a line
// and calculate path position/angle at once.
this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint);
}
lineBounds[i] = graphemeInfo;
width += graphemeInfo.kernedWidth;
positionInPath += graphemeInfo.kernedWidth;
prevGrapheme = grapheme;
}
// this latest bound box represent the last character of the line
// to simplify cursor handling in interactive mode.
lineBounds[i] = {
left: graphemeInfo ? graphemeInfo.left +...