如何获取tspan或文本svg元素的计算y值?
我需要知道每个如何获取tspan或文本svg元素的计算y值?,svg,Svg,我需要知道每个text和tspan的计算y值(垂直基线位置)。但是编写一个函数来遍历树并计算计算出的y值非常复杂 <svg height="500"> <text> <tspan x="0" y="17.6">Compare the way things are going in</tspan> <tspan x="0" dy="1.1em&q
text
和tspan
的计算y
值(垂直基线位置)。但是编写一个函数来遍历树并计算计算出的y
值非常复杂
<svg height="500">
<text>
<tspan x="0" y="17.6">Compare the way things are going in</tspan>
<tspan x="0" dy="1.1em">the United States with how they were</tspan>
<tspan x="0" y="17.6" dy="1.1em">going five years ago.</tspan>
<tspan x="0">Something else</tspan>
</text>
</svg>
比较事情发展的方式
美国和他们是怎样的
五年前去的。
别的
这有捷径吗
一个更清楚的问题可能是:“我如何计算所有文本和TSPAN的y
属性,这些属性允许我删除所有dy
值,并且仍然以完全相同的方式呈现SVG”
请注意,
getBBox().y
和getStartPositionOfChar(n).y
不返回基线位置。如果元素可以变异,这里有一些东西可能适用于y
。对于x
,也可以做类似的事情
function calcualteXY(el: SVGTextElement) {
const dominantBaseline = getAttribute(el, "dominant-baseline");
const alignmentBaseline = getAttribute(el, "alignment-baseline");
if (dominantBaseline) el.removeAttribute("dominant-baseline");
if (alignmentBaseline) el.removeAttribute("alignment-baseline");
el.setAttribute("y", el.getStartPositionOfChar(0).y.toString());
if (dominantBaseline) el.setAttribute("dominant-baseline", dominantBaseline);
if (alignmentBaseline) el.setAttribute("alignment-baseline", alignmentBaseline);
}
迄今为止最好的尝试
type ElementWithAttribute = {
element: Element;
attribute: keyof typeof svgAttributeToCssStyle;
value: string;
};
const hAlignAttributes: (keyof typeof svgAttributeToCssStyle)[] = ["text-anchor"];
const vAlignAttributes: (keyof typeof svgAttributeToCssStyle)[] = ["dominant-baseline", "alignment-baseline"];
function calcualteX(svg: SVGSVGElement) {
const elementsWithAttributes: ElementWithAttribute[] = [];
for (const attr of hAlignAttributes) {
const elements = querySelectorAll<SVGElement>(svg, `[${attr}]`);
for (const element of elements) {
const val = getAttribute(element, attr);
if (val !== null) {
elementsWithAttributes.push({ element, attribute: attr, value: val });
element.removeAttribute(attr);
}
}
}
const elements = querySelectorAll<SVGTSpanElement>(svg, `tspan`);
for (const element of elements) {
element.setAttribute("x", element.getStartPositionOfChar(0).y.toString());
element.removeAttribute("dx");
}
for (const elementWithAttribute of elementsWithAttributes) {
elementWithAttribute.element.setAttribute(elementWithAttribute.attribute, elementWithAttribute.value);
}
}
function calcualteY(svg: SVGSVGElement) {
const elementsWithAttributes: ElementWithAttribute[] = [];
for (const attr of vAlignAttributes) {
const elements = querySelectorAll<SVGElement>(svg, `[${attr}]`);
for (const element of elements) {
const val = getAttribute(element, attr);
if (val !== null) {
elementsWithAttributes.push({ element, attribute: attr, value: val });
element.removeAttribute(attr);
}
}
}
const elements = querySelectorAll<SVGTSpanElement>(svg, `tspan`);
for (const element of elements) {
element.setAttribute("y", element.getStartPositionOfChar(0).y.toString());
element.removeAttribute("dy");
}
for (const elementWithAttribute of elementsWithAttributes) {
elementWithAttribute.element.setAttribute(elementWithAttribute.attribute, elementWithAttribute.value);
}
}
type ElementWithAttribute={
元素:元素;
属性:svgAttributeToCssStyle类型的键;
值:字符串;
};
const hAlignAttributes:(svgAttributeToCssStyle的类型键)[]=[“文本锚定”];
const valignAttribute:(svgAttributeToCssStyle类型的键)[]=[“主基线”、“对齐基线”];
函数Calculatex(svg:SVGSVGElement){
常量元素属性:属性为[]=[]的元素;
for(盐属性常数){
常量元素=querySelectorAll(svg,`[${attr}]`);
for(元素的常量元素){
const val=getAttribute(元素,属性);
如果(val!==null){
push({element,属性:attr,值:val});
元素。删除属性(attr);
}
}
}
const elements=queryselectoral(svg,`tspan`);
for(元素的常量元素){
setAttribute(“x”,element.getStartPositionOfChar(0.y.toString());
元素。删除属性(“dx”);
}
for(常量元素,元素属性为WITHATTRIBUTES){
elementWithAttribute.element.setAttribute(elementWithAttribute.attribute,elementWithAttribute.value);
}
}
函数计算器(svg:SVGSVGElement){
常量元素属性:属性为[]=[]的元素;
for(vAlignAttributes常量属性){
常量元素=querySelectorAll(svg,`[${attr}]`);
for(元素的常量元素){
const val=getAttribute(元素,属性);
如果(val!==null){
push({element,属性:attr,值:val});
元素。删除属性(attr);
}
}
}
const elements=queryselectoral(svg,`tspan`);
for(元素的常量元素){
setAttribute(“y”,element.getStartPositionOfChar(0.y.toString());
元素。删除属性(“dy”);
}
for(常量元素,元素属性为WITHATTRIBUTES){
elementWithAttribute.element.setAttribute(elementWithAttribute.attribute,elementWithAttribute.value);
}
}
假设1em=16px,您可以用上一个tspan(17.6)+1.1*16=35.2的y值替换dy=“1.1”。这是一个良好的开端。我想通过编程计算任何元素的y位置。这并不能解释之前元素上有dy的情况(这也会影响y),或者当元素没有y时。@enxaneta看到我自己的答案,有些东西不漂亮,但这可能解决了问题,在问了这个问题后提出了这个问题。当子元素设置了任何列出的属性时,这个失败了。这将影响为父元素返回的getStartPosition