我正在使用Raphael.js在图像上创建多边形(或实际上是封闭的路径)。我想将文本放在多边形内。有没有办法创建一个文本元素,然后调整它的大小和位置,以便整个事物将在多边形的范围内?
至少有哪些算法可以让我猜测我可以手动调整吗?
答案 0 :(得分:3)
好的,我在一天的过程中对此进行了一些思考,最后有机会将一些演示代码放在一起。它在许多方面明显不完美但可能形成一个良好的起点,并且似乎与我的大多数随机生成的多边形一起工作。
第1部分:将文本居中于多边形。使用边界框证明非常不令人满意,因此我没有设计一种技术来平均给定路径中的所有点container
:
// Determine the *weighted* center of this figure
var segments = Raphael.parsePathString( container.attr( 'path' ) );
var count = 0, sum_x = 0, sum_y = 0;
for ( var i = 0; i < segments.length; i++ )
{
if ( segments[i][0] == 'L' || segments[i][0] == 'M' )
{
count++;
sum_x += segments[i][1];
sum_y += segments[i][2];
}
}
var cx = sum_x / count, cy = sum_y / count;
第2部分:碰撞检测。我需要一种机制来检查给定对象是否在当前形状内。懒惰,我只是在创建画布之前扩展了Raphael元素对象。
Raphael.el.isObjectInside = function( obj )
{
var box = obj.getBBox();
return this.isPointInside( box.x, box.y )
&&
this.isPointInside( box.x2, box.y )
&&
this.isPointInside( box.x, box.y2 )
&&
this.isPointInside( box.x2, box.y2 );
}
第3部分:迭代大小调整。基本上,我们使用上面生成的坐标并将它们应用于生成的标签文本。我们每次迭代都会缩小比例,直到我们达到某个阈值以下,此时我的代码就会放弃(你的代码可能不应该放弃):
var s = 1.0;
if ( ibox.width >= cbox.width * 0.7 )
{
s = ( cbox.width * 0.7 ) / ibox.width;
}
while ( s > 0.1 )
{
insert.attr( { transform: [ "S", s, s, ibox.x + ibox.width / 2, ibox.y + ibox.height / 2, "T",
if ( container.isObjectInside( insert ) )
return;
s *= 0.65;
}
console.log("Warning: NOT a clean fit" );
结果看起来很适合我投入的大多数纯随机多边形。我确信它的计算密集程度要远远超过它需要的程度。我的代码已暂存here - 只需单击多边形即可生成新的代码。
快乐的编码。