在SVG或Raphael.js中的路径或多边形内写入文本

时间:2012-09-21 16:28:57

标签: html svg geometry raphael

我正在使用Raphael.js在图像上创建多边形(或实际上是封闭的路径)。我想将文本放在多边形内。有没有办法创建一个文本元素,然后调整它的大小和位置,以便整个事物将在多边形的范围内?

至少有哪些算法可以让我猜测我可以手动调整吗?

1 个答案:

答案 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 - 只需单击多边形即可生成新的代码。

快乐的编码。