您将需要 Javascript,但它不像前面的示例那样相当复杂。
所有文本元素都有一组相关的接口函数来定位每个字符:
http://www.w3.org/TR/SVG11/text.html#InterfaceSVGTextContentElement
最简单的方法是使用getExtentOfChar(i) 来查找每个字符字形的边界框矩形。这是@Robert Longson 的示例中使用的方法。没有所有额外的事件处理代码,它可以简化为:
var texts = document.getElementsByClassName("backgroundRect");
var svgNS ="http://www.w3.org/2000/svg";
for (var i=0, max= texts.length; i<max; i++) {
var t = texts[i];
var g = document.createElementNS(svgNS, "g");
for (var j=0, nchar=t.getNumberOfChars(); j<nchar; j++) {
var r = t.getExtentOfChar(j);
var re = document.createElementNS(svgNS, "rect");
re.setAttribute("width", r.width);
re.setAttribute("height", r.height);
re.setAttribute("x", r.x);
re.setAttribute("y", r.y);
g.insertBefore(re, null);
}
t.parentNode.insertBefore(g, t);
}
http://fiddle.jshell.net/T5qWb/1/
限制是边界框是包含字母在原始水平和垂直坐标内的最紧凑的矩形,而不是旋转的矩形,因此矩形比字母大并且重叠.
要计算出一个紧密边界矩形,您需要使用.getStartPositionOfChar(i)、.getEndPositionOfChar(i) 和一些几何图形:
var texts = document.getElementsByClassName("backgroundRect");
var svgNS ="http://www.w3.org/2000/svg";
for (var i=0, max= texts.length; i<max; i++) {
var t = texts[i];
var g = document.createElementNS(svgNS, "g");
g.setAttribute("class", "textBackground");
for (var j=0, nchar=t.getNumberOfChars(); j<nchar; j++) {
var p = document.createElementNS(svgNS, "path");
var start = t.getStartPositionOfChar(j),
end = t.getEndPositionOfChar(j),
height = parseFloat(getComputedStyle(t)["fontSize"]),
vector = [(end.x - start.x), (end.y - start.y)],
aspect = height /
Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1]),
normal = [vector[1]*aspect, -vector[0]*aspect];
var d = ["M", [start.x, start.y],
"l", normal, vector, [-normal[0], -normal[1]],
"z"
].join(" ");
p.setAttribute("d", d);
g.insertBefore(p, null);
}
t.parentNode.insertBefore(g, t);
}
http://fiddle.jshell.net/T5qWb/2/
这次我使用<path> 而不是<rect>,使用相对坐标沿角色的基线绘制直线,然后在与该线成90 度的位置向上1em。这会将每个矩形的底部定位在您的文本路径上,但它不会覆盖字母的“降序”。
为此,我决定切换回<rect> 元素并使用变换来定位矩形会更容易。我将矩形平移到起点,根据.getRotationOfChar(i) 旋转它,然后将其平移离开基线。唯一的限制是我必须硬编码估计字符高度的比例应该低于基线,因为我无法找出任何方法来计算给定字体的高度.
var texts = document.getElementsByClassName("backgroundRect");
var svgNS ="http://www.w3.org/2000/svg";
for (var i=0, max= texts.length; i<max; i++) {
var t = texts[i];
var g = document.createElementNS(svgNS, "g");
g.setAttribute("class", "textBackground");
for (var j=0, nchar=t.getNumberOfChars(); j<nchar; j++) {
var re = document.createElementNS(svgNS, "rect");
var start = t.getStartPositionOfChar(j),
end = t.getEndPositionOfChar(j),
angle = t.getRotationOfChar(j),
height = parseFloat(getComputedStyle(t)["fontSize"]),
vector = [(end.x - start.x), (end.y - start.y)],
width = Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1]),
aspect = height / width,
normal = [vector[1]*aspect, -vector[0]*aspect],
baseline = 0.2;
re.setAttribute("height", height);
re.setAttribute("width", width);
re.setAttribute("transform",
["translate(", [start.x, start.y], ")",
"rotate(", angle, ")",
"translate(0", -height*(1-baseline), ")"
].join(" ")
);
g.insertBefore(re, null);
}
t.parentNode.insertBefore(g, t);
}
http://fiddle.jshell.net/T5qWb/3/
经过测试,所有接口方法均已在最新的 Chrome 和 Firefox 以及 IE11/10/9(通过开发者的模拟器)中按预期实现和工作。