我有一个圆圈添加到画布,然后一些文字我想环绕一个圆圈。 这是我到目前为止所拥有的
var circle = new fabric.Circle({
top: 100,
left: 100,
radius: 100,
fill: '',
stroke: 'green',
});
canvas.add(circle);
var obj = "some text"
for(letter in obj){
var newLetter = new fabric.Text(obj[letter], {
top: 100,
left: 100
});
canvas.add(newLetter);
canvas.renderAll();
}
我在网上发布了一些其他解决方案,但到目前为止还没有任何正常的结构。
答案 0 :(得分:2)
圆形文字。
我开始回答这个问题,认为这很容易,但有点难看。我把它推回到更简单的版本。
我遇到的问题是基本的,但没有简单的解决方案..
我有一个完全另类的方法,因为它太重了,无法在这里得到答案。它涉及一个自定义扫描线渲染(各种GPU硬件),因此如果文本质量至关重要,您可以尝试沿着这些线寻找某些东西。
我遇到的问题是通过忽略它们来解决的,总是一个很好的解决方案。 LOL
如何在2D画布上渲染圆形文字。
由于在一次调用中无法做到这一点,我编写了一个函数,每次渲染一个角色。我使用ctx.measureText
来获取要绘制的整个字符串的大小,然后将其转换为角度像素大小。然后稍微调整各种选项,对齐,拉伸和方向(镜像),我一次一个地查看字符串中的每个字符,使用ctx.measureText
来测量它的大小,然后使用{ {1}}定位旋转并缩放角色,然后只需调用ctx.setTransform
渲染该角色。
它比ctx.fillText()
方法慢一点,但填充文字无法在圆圈上绘制。
需要进行一些计算。
为了锻炼,给定半径的像素的角度大小是微不足道的,但我常常看不到正确的。因为Javascript在弧度下工作,角度像素大小只是
ctx.fillText()
因此,要训练一些文字占据圆圈或给定半径的角度。
var angularPixelSize = 1 / radius; // simple
锻炼单个角色的大小。
var textWidth = ctx.measureText("Hello").width;
var textAngularWidth = angularPixelSize * textWidth;
因此,您可以使用角度大小来对齐圆圈上的文本,无论是居中,右侧还是左侧。有关详细信息,请参阅代码段。
然后你需要一次一个地遍历每个角色,计算变换,渲染文本,为下一个角色移动正确的角距离,直到完成。
var text = "This is some text";
var index = 2; // which character
var characterWidth = ctx.measureText(text[index]).width;
var characterAngularWidth = angularPixelSize * textWidth;
繁琐的数学部分正在设置变换。我发现直接使用转换矩阵更容易,这使得我可以使用缩放等操作,而不必使用太多的转换调用。
设置变换需要6个数字,前两个是x轴的方向,接下来的两个是y轴的方向,后两个是从画布原点的平移。
所以要获得Y轴。对于每个角色,圆心向外移动的线我们需要角色绘制的角度,并减少不对齐(注意减少不消除)角宽度,这样我们就可以使用角色的中心来对齐它。
var angle = ?? // the start angle
for(var i = 0; i < text.length; i += 1){ // for each character in the string
var c = text[i]; // get character
// get character angular width
var w = ctx.measureText(c).width * angularPixelSize;
// set the matrix to align the text. See code under next paragraph
...
...
// matrix set
ctx.fillText(c,0,0); // as the matrix set the origin just render at 0,0
angle += w;
}
现在我们有了标准化的矢量,它将是x轴。角色沿此轴从左向右绘制。我一次构建矩阵,但我将在下面分解它。请注意我在我的代码片段中用角度做了一个嘘声,所以代码是回到前面(X是Y,Y是X) 请注意,该代码段能够在两个角度之间拟合文本,因此我缩放x轴以允许此操作。
// assume angle is position and w is character angular width from above code
var xDx = Math.cos(angle + w / 2); // get x part of X axis direction
var xDy = Math.sin(angle + w / 2); // get y part of X axis direction
那就是绘制圆形字符串的数学和逻辑。我很抱歉,但我不使用fabric.js所以它可能有也可能没有选项。但是您可以创建自己的函数并直接渲染到与fabric.js相同的画布,因为它不排除访问。虽然在Fabric.js不知道状态变化时会保存并恢复画布状态。
以下是在实践中显示上述内容的片段。它远非理想,但是使用现有的canvas 2D API可以快速完成。 Snippet具有测量和绘图的两个功能以及一些基本用法示例。
// assume scale is how much the text is squashed along its length.
ctx.setTransform(
xDx * scale, xDy * scale, // set the direction and size of a pixel for the X axis
-xDy, xDx, // the direction ot the Y axis is perpendicular so switch x and y
-xDy * radius + x, xdx * radius + y // now set the origin by scaling by radius and translating by the circle center
);
&#13;