1

简单示例:我在 Illustrator 中绘制了一条 1000 像素的水平线(在 CS5 和 CS6 中尝试过)并在其上放置文本。我将路径上文本的起点拖到250px。

当我导出到 SVG 时,我希望 Illustrator 将 textPath 标记的“startOffset”属性设置为 25%。相反,它大约是 32%(三分之一??)。

但是,当我将文本拖动到 500 像素时,“startOffset”按预期设置为 50%。

在 750 像素处,属性将为 67%。

问题是,在 Firefox 中查看 SVG,文本显示在不同的位置,因为它似乎以线性方式应用百分比。所以 32% 真的意味着 320 像素,而不是 Illustrator 计算出来的 250 像素……

我在这里错过了什么吗?或者有人知道重新计算百分比以便在 SVG 中正确显示的方法吗?

感谢任何帮助

4

1 回答 1

2

好的,所以我想出了如何计算正确的百分比:

  • 显然,Illustrator 会根据路径段的数量计算百分比。如果路径由两段(即 3 个顶点)组成,并且应用路径文本并将其定位在第二个顶点(“中间”),这将导致 SVG 文件中的 startOffset 为 50%,而不管每个路径段的大小。第一段可以长 1000px,第二段只有 4px(总路径长度为 1004px):将文本放置在第二个顶点将始终导致 50%。

  • 另一边的 SVG/浏览器根据总路径长度计算百分比。所以,参考上面的例子,文本不会被放置在 1000px 的长度(如果你查看段的数量,因此是 50%,因此是第一个段的结尾),而是 502px,即 50%总路径长度。

为了将“插图画家百分比”转换为“浏览器百分比”,您可以执行以下操作(未优化):

 // Get the current percentage    
 var oldPercent = parseFloat(textPathNode.getAttribute('startOffset').split('%')[0])/100;

 // Get the path
 var parentPath = document.getElementById(textPathNode.getAttribute('xlink:href').split('#')[1])

 // Get the path segments
 var parentPath.getAttribute('d').match(/[MmLlHhCc][\d\,\.\-\s]+/g);

 // Calculate the percentage for one segment
 var percentPerSegment = 1/segments.length;

 // Find out on which segment the textPath lies
 var offsetIsOnSegmentNo = Math.floor(oldPercent/percentPerSegment);

 // Calculate the length of that segment
 var virtualPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
 virtualPath.setAttribute('d', 'M0,0'+segments[offsetIsOnSegmentNo]);
 var segLength = virtualPath.getTotalLength();

 // Calculate the total path length of the previous segments
 var prevSegLength=0;
 var prevD = '';
 for(var i=0; i<offsetIsOnSegmentNo; i++)
    prevD += segments[s];

 var virtualPrevPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
 virtualPrevPath.setAttribute('d', 'M0,0'+prevD);
 var prevPathLength = virtualPrevPath.getTotalLength();

 // Calculate the actual path length for the old percentage             
 var totalLength = prevPathLength + segLength*(oldPercent-(percentPerSegment*offsetIsOnSegmentNo))/(percentPerSegment);

 // Calculate the correct percentage
 var newPercentage = totalLength / parentPath.getTotalLength();

 textPathNode.setAttribute('startOffset', newPercentage*100+'%');
于 2013-02-05T11:30:16.467 回答