首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在SVG元素之上添加一个标签,而不使SVG元素移动

在SVG元素之上添加一个标签,而不使SVG元素移动
EN

Stack Overflow用户
提问于 2022-11-29 14:51:36
回答 1查看 53关注 0票数 2

我有一个项目,我将一些数据可视化为包含rect元素的SVG元素。所以我想要做的是在SVG的一个特定的rect元素上添加一个标签,为了做到这一点,我必须得到rect元素的位置,以便将标签放置在这个确切的位置。

因此,为了实现这一点,我首先使用getBoundingClientRect() javascrip方法获得SVG位置,然后使用相同的方法得到rect元素位置。

在此之后,我得到svg和rect元素的位置之间的差异,得到的值是标签将要放置的位置。

这是代码,以便获取每个元素的位置,然后计算标签的新位置。

parentId参数是svg元素的id,childId参数是rect元素的id。

代码语言:javascript
运行
复制
function getElemementRelativePosition(parentId, childId) {
    var parentPos = document.getElementById(parentId).getBoundingClientRect();
    var childPos = document.getElementById(childId).getBoundingClientRect();
    var relativePos = {};

    relativePos.top = childPos.top - parentPos.top;
    relativePos.right = childPos.right - parentPos.right;
    relativePos.bottom = childPos.bottom - parentPos.bottom;
    relativePos.left = childPos.left - parentPos.left;

    return relativePos;
}

getElemementRelativePosition函数返回标签的正确值,但问题是标签的占位符在其初始位置仍然很粘稠,所以即使我改变了它的位置,标签的高度也会将svg元素向下推。

包含标签的div元素具有以下属性

代码语言:javascript
运行
复制
<div style="position:relative;z-index:10;top:@ relativePos.top; left:@ relativePos.left;">
MyLabel
</div>

对于如何在不使用svg的情况下实现这一点,有任何建议吗?

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-29 17:17:44

正如@maciek所指出的:您可以使用position:relative将svg和label包装在div中,并将position:absolute应用于您的svg和label。

选择: svg <text>标签

如果您只需要简单的单行标签- 有一些优点:您只需要得到<rect>元素的中心x和y坐标。

通过应用text-anchor:middledominant-baseline:middle,文本将垂直和水平中心相对于rect的中心。

您可以使用getBBox()方法获得中心坐标(类似于getBoundingClientRect(),但专门用于svg元素)。

简单的标签助手看起来可能如下所示:

代码语言:javascript
运行
复制
function setSvgLabelPos(rect, label){
  let bb = rect.getBBox();
  let [x, y, width, height] = [bb.x, bb.y, bb.width, bb.height];
  label.setAttribute('x', (x+width/2) )
  label.setAttribute('y', (y+height/2) )
}

同样整洁:字体大小将与父svg元素一起缩放

弊端

<text>元素不像块元素:

没有自动line-wrapping

  • no支持背景色和盒状外观respectively

示例

代码语言:javascript
运行
复制
// 1. svg text approach
setSvgLabelPos(rect2, labelSvg);

function setSvgLabelPos(rect, label) {
  let bb = rect.getBBox();
  let [x, y, width, height] = [bb.x, bb.y, bb.width, bb.height];
  label.setAttribute('x', (x + width / 2))
  label.setAttribute('y', (y + height / 2))
}


// 2. HTML relative/absolute layout
let posLabel = getElemementRelativePosition('svg', 'rect', 'label')
label.setAttribute('style', `top: ${posLabel.top}px; left: ${posLabel.left}px`);


function getElemementRelativePosition(parentId, childId, labelId) {
  var parentPos = document.getElementById(parentId).getBoundingClientRect();
  var childPos = document.getElementById(childId).getBoundingClientRect();
  var labelPos = document.getElementById(labelId).getBoundingClientRect();
  var relativePos = {};

  relativePos.top = childPos.top - parentPos.top;
  relativePos.right = childPos.right - parentPos.right;
  relativePos.bottom = childPos.bottom - parentPos.bottom;
  relativePos.left = childPos.left - parentPos.left;
  return relativePos;
}
代码语言:javascript
运行
复制
svg {
  width: 20em;
  border: 1px solid #ccc;
  background: #eee;
}

.svgWrap {
  position: relative;
}

.svgWrap>* {
  position: absolute;
}

.label {
  padding: 0.3em;
  display: inline-block;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
}
代码语言:javascript
运行
复制
<div class="svgWrap">
  <svg id="svg" viewBox="0 0 100 100">
    <rect id="rect" x="25%" y="50%" width="20" height="20" fill="red" />
    <rect id="rect2" x="50%" y="25%" width="20" height="20" fill="green" />
    <text id="labelSvg" class="label" x="50%" y="50%" style="font-size:4.5px; font-family:sans-serif;fill:currentColor " text-anchor="middle" dominant-baseline="middle">Svg label</text>
  </svg>
  <div id="label" class="label" style="">MyLabel</div>
</div>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74615924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档