【问题标题】:Adjust height of SVG within JS/CSS在 JS/CSS 中调整 SVG 的高度
【发布时间】:2019-08-29 02:44:31
【问题描述】:

我有一个包含世界上所有国家/地区的 svg 文件。每个国家/地区都有自己的路径,例如:

<path
      inkscape:connector-curvature="0"
      id="PH"
      data-name="Philippines"
      data-id="PH"
      d="m 1684.6,518.6 -0.6,-2.3 -0.8,-3.2 -4.8,-3 0.8,4.9 -3.9,0.2 -0.7,2.8 -4.2,1.7 -2.2,-2.8 -2.8,2.4 -3.4,1.7 -1.9,5.4 1.1,1.9 3.9,-3.6 2.7,0.3 1.5,-2.7 3.8,3 -1.5,3.1 1.9,4.6 6.8,3.7 1.4,-3 -2.1,-4.7 2.4,-3.2 2.5,6.4 1.5,-5.8 -0.6,-3.5 -0.8,-4.3 z m -14.5,-11.8 0,-6.1 -3.6,6.1 0.5,-4.2 -3,0.3 -0.3,4 -1.2,1.8 -1,1.7 3.8,4.4 1.6,-1.9 1.4,-4 1.8,-2.1 z m -30.1,6.1 2.6,-4.4 3.4,-3.5 -1.5,-5.2 -2.4,6.3 -2.9,4.4 -3.8,4 -2.4,4.4 7,-6 z m 17.4,-16.4 1.2,3 -0.1,3.3 0.5,2.9 3.3,-1.9 2.4,-2.7 -0.2,-2.6 -3.6,0 -3.5,-2 z m 20,-1.7 -1.8,-2.4 -5.4,-0.1 4,4.8 0.3,2.4 -3.3,-0.5 1.2,3.9 1.7,0.3 0.7,4.5 2.5,-1.4 -1.7,-4 -0.4,-2.1 4.5,1.7 -2.3,-7.1 z m -22.9,-5.8 -2.2,-2.3 -4.8,-0.2 3.4,4.8 2.8,3.2 0.8,-5.5 z m -6.4,-34.6 -3.3,0 -0.9,5.8 1.1,9.9 -2.6,-2 1.2,6 1.2,2.8 3.3,3.7 0.4,-2.3 1.8,1.4 -1.5,1.7 0.1,2.6 2.9,1.4 5,-0.9 4,3.8 1.1,-2.4 2.5,3.4 4.8,3.1 0.2,-2.9 -2,-1.6 0.1,-3.4 -7.5,-3.6 -2.3,0.8 -3.1,-0.7 -2,-5.1 0.1,-5.1 3,-2.1 0.6,-5.3 -2.7,-4.6 0.4,-2.6 -0.7,-1.6 -1.5,1.6 -3.7,-1.8 z"
      style="fill:#1abc9c;fill-rule:evenodd;" />

<path
      inkscape:connector-curvature="0"
      id="PL"
      data-name="Poland"
      data-id="PL"
      d="m 1069.4,228.3 -4.6,-0.1 -0.5,-1.4 -4.8,-1.1 -5.7,2.1 -7.1,2.8 -3.1,1.7 1.4,3.1 -1.2,1.6 2,2.2 1.4,3.3 -0.1,2.1 2.3,3.9 2.4,1.9 3.7,0.6 -0.1,1.7 2.7,1.2 0.6,-1.5 3.4,0.6 0.7,2 3.6,0.3 2.6,3.1 0.3,0.4 1.9,-0.9 2.7,2.2 2.8,-1.3 2.4,0.6 3.4,-0.8 4.9,2.3 1.1,0.4 -1.6,-2.8 3.8,-5.1 2.3,-0.7 0.3,-1.8 -3.1,-5.3 -0.5,-2.7 -1.9,-2.9 2.7,-1.2 -0.3,-2.4 -1.7,-2.3 -0.6,-2.7 -1.4,-1.9 -2.5,-0.6 -8.7,0.1 -5.9,-0.7 z"
      style="fill:#f2f2f2;fill-rule:evenodd" />

现在我想通过 JS 中的一个函数访问每个国家。所以我在国家前加了一个href:

<a href = "#" onclick = "SelectCountry('ph');" id = 'country_ph'> 
   <path
      inkscape:connector-curvature="0"
      id="PH"
      data-name="Philippines"
      data-id="PH"
      d="m 1684.6,518.6 -0.6,-2.3 -0.8,-3.2 -4.8,-3 0.8,4.9 -3.9,0.2 -0.7,2.8 -4.2,1.7 -2.2,-2.8 -2.8,2.4 -3.4,1.7 -1.9,5.4 1.1,1.9 3.9,-3.6 2.7,0.3 1.5,-2.7 3.8,3 -1.5,3.1 1.9,4.6 6.8,3.7 1.4,-3 -2.1,-4.7 2.4,-3.2 2.5,6.4 1.5,-5.8 -0.6,-3.5 -0.8,-4.3 z m -14.5,-11.8 0,-6.1 -3.6,6.1 0.5,-4.2 -3,0.3 -0.3,4 -1.2,1.8 -1,1.7 3.8,4.4 1.6,-1.9 1.4,-4 1.8,-2.1 z m -30.1,6.1 2.6,-4.4 3.4,-3.5 -1.5,-5.2 -2.4,6.3 -2.9,4.4 -3.8,4 -2.4,4.4 7,-6 z m 17.4,-16.4 1.2,3 -0.1,3.3 0.5,2.9 3.3,-1.9 2.4,-2.7 -0.2,-2.6 -3.6,0 -3.5,-2 z m 20,-1.7 -1.8,-2.4 -5.4,-0.1 4,4.8 0.3,2.4 -3.3,-0.5 1.2,3.9 1.7,0.3 0.7,4.5 2.5,-1.4 -1.7,-4 -0.4,-2.1 4.5,1.7 -2.3,-7.1 z m -22.9,-5.8 -2.2,-2.3 -4.8,-0.2 3.4,4.8 2.8,3.2 0.8,-5.5 z m -6.4,-34.6 -3.3,0 -0.9,5.8 1.1,9.9 -2.6,-2 1.2,6 1.2,2.8 3.3,3.7 0.4,-2.3 1.8,1.4 -1.5,1.7 0.1,2.6 2.9,1.4 5,-0.9 4,3.8 1.1,-2.4 2.5,3.4 4.8,3.1 0.2,-2.9 -2,-1.6 0.1,-3.4 -7.5,-3.6 -2.3,0.8 -3.1,-0.7 -2,-5.1 0.1,-5.1 3,-2.1 0.6,-5.3 -2.7,-4.6 0.4,-2.6 -0.7,-1.6 -1.5,1.6 -3.7,-1.8 z"
      style="fill:#1abc9c;fill-rule:evenodd;" />
   </a>

并在此处访问它们:

var phCountry = document.getElementById("PH");

function SelectCountry(country)
{
    alert(country);
}

但是,我想缩放用户点击的国家/地区。我试过 phCountry.setAttribute("height", "100px");
phCountry.style.height = "100px"; 我对 svg 和 js 很陌生,所以我可能以错误的方式做这件事。 我怎样才能解决这个问题?非常感谢!

【问题讨论】:

  • phCountry 是一个元素,每个元素都有自己的heightwidth 属性。你试过了吗?
  • @r3wt 是的,我也试过那个。我认为调整元素是行不通的。我什至尝试将style = "width: 100px;" 放在svg 本身的标签中。我想必须真正修改 svg 属性或什么?或者可能包含对象内的元素然后缩放它?我不知道._.
  • 您是否尝试过使用 javascript 插入针对特定路径的 css? like path[id="PH"] { // your css }
  • @r3wt 这不适用于 SVG 元素。大多数不支持高度和宽度。
  • 你可能想看看这个答案:stackoverflow.com/questions/57579893/…这可能是你需要的。

标签: javascript css svg


【解决方案1】:

&lt;path&gt; 元素没有可以更改的宽度或高度属性。您需要做的是应用transform,当您点击它们时,它会缩放国家/地区路径。

另外,您不需要将&lt;a&gt; 标签添加到您的SVG。只需为每个路径添加一个点击处理程序。

请参见下面的示例。我已经在代码 cmets 中描述了它是如何工作的。

// Look for all <path> elements in the SVG and add a click handler to each one
document.querySelectorAll("svg path").forEach(function(item) {
  item.addEventListener("click", countryClick);
});


function countryClick(e) {
  // e.target is the path we clicked on.
  // classList.toggle("enlarge") will cause the "enlarge" class to be added then removed on alternate clicks
  e.target.classList.toggle("enlarge");
}
.enlarge {
  /* Use the bounds of the path to calculate the transform origin */
  transform-box: fill-box;
  /* Set the origin for scaling to the centre of the path bounds */
  transform-origin: 50% 50%;
  /* Scale up by 2 in both the x and y directions */
  transform: scale(2, 2);
}
<svg viewBox="1000 200 800 400">

  <path
      inkscape:connector-curvature="0"
      id="PH"
      data-name="Philippines"
      data-id="PH"
      d="m 1684.6,518.6 -0.6,-2.3 -0.8,-3.2 -4.8,-3 0.8,4.9 -3.9,0.2 -0.7,2.8 -4.2,1.7 -2.2,-2.8 -2.8,2.4 -3.4,1.7 -1.9,5.4 1.1,1.9 3.9,-3.6 2.7,0.3 1.5,-2.7 3.8,3 -1.5,3.1 1.9,4.6 6.8,3.7 1.4,-3 -2.1,-4.7 2.4,-3.2 2.5,6.4 1.5,-5.8 -0.6,-3.5 -0.8,-4.3 z m -14.5,-11.8 0,-6.1 -3.6,6.1 0.5,-4.2 -3,0.3 -0.3,4 -1.2,1.8 -1,1.7 3.8,4.4 1.6,-1.9 1.4,-4 1.8,-2.1 z m -30.1,6.1 2.6,-4.4 3.4,-3.5 -1.5,-5.2 -2.4,6.3 -2.9,4.4 -3.8,4 -2.4,4.4 7,-6 z m 17.4,-16.4 1.2,3 -0.1,3.3 0.5,2.9 3.3,-1.9 2.4,-2.7 -0.2,-2.6 -3.6,0 -3.5,-2 z m 20,-1.7 -1.8,-2.4 -5.4,-0.1 4,4.8 0.3,2.4 -3.3,-0.5 1.2,3.9 1.7,0.3 0.7,4.5 2.5,-1.4 -1.7,-4 -0.4,-2.1 4.5,1.7 -2.3,-7.1 z m -22.9,-5.8 -2.2,-2.3 -4.8,-0.2 3.4,4.8 2.8,3.2 0.8,-5.5 z m -6.4,-34.6 -3.3,0 -0.9,5.8 1.1,9.9 -2.6,-2 1.2,6 1.2,2.8 3.3,3.7 0.4,-2.3 1.8,1.4 -1.5,1.7 0.1,2.6 2.9,1.4 5,-0.9 4,3.8 1.1,-2.4 2.5,3.4 4.8,3.1 0.2,-2.9 -2,-1.6 0.1,-3.4 -7.5,-3.6 -2.3,0.8 -3.1,-0.7 -2,-5.1 0.1,-5.1 3,-2.1 0.6,-5.3 -2.7,-4.6 0.4,-2.6 -0.7,-1.6 -1.5,1.6 -3.7,-1.8 z"
      style="fill:#1abc9c;fill-rule:evenodd;" />

  <path
      inkscape:connector-curvature="0"
      id="PL"
      data-name="Poland"
      data-id="PL"
      d="m 1069.4,228.3 -4.6,-0.1 -0.5,-1.4 -4.8,-1.1 -5.7,2.1 -7.1,2.8 -3.1,1.7 1.4,3.1 -1.2,1.6 2,2.2 1.4,3.3 -0.1,2.1 2.3,3.9 2.4,1.9 3.7,0.6 -0.1,1.7 2.7,1.2 0.6,-1.5 3.4,0.6 0.7,2 3.6,0.3 2.6,3.1 0.3,0.4 1.9,-0.9 2.7,2.2 2.8,-1.3 2.4,0.6 3.4,-0.8 4.9,2.3 1.1,0.4 -1.6,-2.8 3.8,-5.1 2.3,-0.7 0.3,-1.8 -3.1,-5.3 -0.5,-2.7 -1.9,-2.9 2.7,-1.2 -0.3,-2.4 -1.7,-2.3 -0.6,-2.7 -1.4,-1.9 -2.5,-0.6 -8.7,0.1 -5.9,-0.7 z"
      style="fill:#f2f2f2;fill-rule:evenodd" />
      
</svg>

但是,您不可避免地需要做一个额外的步骤。如果您单击了我在第一个示例中添加的方块,那么您已经发现了它。 SVG 中的元素具有绘制顺序。文件中较早的路径在后面的路径之前绘制。所以你会发现,当你扩大一个国家时,它可能落后于另一个未扩大的国家。

这可能不是你想要的。所以要解决这个问题,你还需要把你正在扩大的国家移到前面。您可以通过将其移动到 SVG 的末尾来做到这一点。

在下一个示例中,我添加了执行此操作的代码。

// Look for all <path> elements in the SVG and add a click handler to each one
document.querySelectorAll("svg path").forEach(function(item) {
  item.addEventListener("click", countryClick);
});


function countryClick(e) {
  // e.target is the path we clicked on.
  // classList.toggle("enlarge") will cause the "enlarge" class to be added then removed on alternate clicks
  e.target.classList.toggle("enlarge");
  
  // If we are enlarging, then also move the path to the end of the SVG
  if (e.target.classList.contains("enlarge")) {
    var svg = e.target.ownerSVGElement;
    // appendChild() adds an element to the end of the SVG.
    // If it is already in the SVG, it gets moved from it's current position in the order.
    svg.appendChild(e.target);
  }
}
.enlarge {
  /* Use the bounds of the path to calculate the transform origin */
  transform-box: fill-box;
  /* Set the origin for scaling to the centre of the path bounds */
  transform-origin: 50% 50%;
  /* Scale up by 2 in both the x and y directions */
  transform: scale(2, 2);
}
<svg viewBox="1000 200 800 400">

  <path
      inkscape:connector-curvature="0"
      id="PH"
      data-name="Philippines"
      data-id="PH"
      d="m 1684.6,518.6 -0.6,-2.3 -0.8,-3.2 -4.8,-3 0.8,4.9 -3.9,0.2 -0.7,2.8 -4.2,1.7 -2.2,-2.8 -2.8,2.4 -3.4,1.7 -1.9,5.4 1.1,1.9 3.9,-3.6 2.7,0.3 1.5,-2.7 3.8,3 -1.5,3.1 1.9,4.6 6.8,3.7 1.4,-3 -2.1,-4.7 2.4,-3.2 2.5,6.4 1.5,-5.8 -0.6,-3.5 -0.8,-4.3 z m -14.5,-11.8 0,-6.1 -3.6,6.1 0.5,-4.2 -3,0.3 -0.3,4 -1.2,1.8 -1,1.7 3.8,4.4 1.6,-1.9 1.4,-4 1.8,-2.1 z m -30.1,6.1 2.6,-4.4 3.4,-3.5 -1.5,-5.2 -2.4,6.3 -2.9,4.4 -3.8,4 -2.4,4.4 7,-6 z m 17.4,-16.4 1.2,3 -0.1,3.3 0.5,2.9 3.3,-1.9 2.4,-2.7 -0.2,-2.6 -3.6,0 -3.5,-2 z m 20,-1.7 -1.8,-2.4 -5.4,-0.1 4,4.8 0.3,2.4 -3.3,-0.5 1.2,3.9 1.7,0.3 0.7,4.5 2.5,-1.4 -1.7,-4 -0.4,-2.1 4.5,1.7 -2.3,-7.1 z m -22.9,-5.8 -2.2,-2.3 -4.8,-0.2 3.4,4.8 2.8,3.2 0.8,-5.5 z m -6.4,-34.6 -3.3,0 -0.9,5.8 1.1,9.9 -2.6,-2 1.2,6 1.2,2.8 3.3,3.7 0.4,-2.3 1.8,1.4 -1.5,1.7 0.1,2.6 2.9,1.4 5,-0.9 4,3.8 1.1,-2.4 2.5,3.4 4.8,3.1 0.2,-2.9 -2,-1.6 0.1,-3.4 -7.5,-3.6 -2.3,0.8 -3.1,-0.7 -2,-5.1 0.1,-5.1 3,-2.1 0.6,-5.3 -2.7,-4.6 0.4,-2.6 -0.7,-1.6 -1.5,1.6 -3.7,-1.8 z"
      style="fill:#1abc9c;fill-rule:evenodd;" />

  <path
      inkscape:connector-curvature="0"
      id="PL"
      data-name="Poland"
      data-id="PL"
      d="m 1069.4,228.3 -4.6,-0.1 -0.5,-1.4 -4.8,-1.1 -5.7,2.1 -7.1,2.8 -3.1,1.7 1.4,3.1 -1.2,1.6 2,2.2 1.4,3.3 -0.1,2.1 2.3,3.9 2.4,1.9 3.7,0.6 -0.1,1.7 2.7,1.2 0.6,-1.5 3.4,0.6 0.7,2 3.6,0.3 2.6,3.1 0.3,0.4 1.9,-0.9 2.7,2.2 2.8,-1.3 2.4,0.6 3.4,-0.8 4.9,2.3 1.1,0.4 -1.6,-2.8 3.8,-5.1 2.3,-0.7 0.3,-1.8 -3.1,-5.3 -0.5,-2.7 -1.9,-2.9 2.7,-1.2 -0.3,-2.4 -1.7,-2.3 -0.6,-2.7 -1.4,-1.9 -2.5,-0.6 -8.7,0.1 -5.9,-0.7 z"
      style="fill:#f2f2f2;fill-rule:evenodd" />

  <path d="M 1100,228 h 30 v 30 h -30 z" fill="#ccaa88"/>

</svg>

【讨论】:

  • 非常感谢,这正是我所需要的!对此还有一个询问:1.如何使所选国家重新定位到中心。 2.点击后如何传递/获取国家ID?再一次感谢你! :D
  • 你可以使用event.target.id获取你点击的东西的id。至于将路径移动到中心,除了scale() 之外,您还需要在transform 属性中包含translate() 操作。但是,每条路径都会有所不同,因为它们需要从不同的地方移动。有很多关于如何做到这一点的信息。所以我会把这部分留给你去试一试。祝你好运。如果你被卡住了,你总是可以问另一个问题。但这很简单。
  • 非常感谢!很抱歉回复晚了! :) 上帝保佑!
  • 先生,如果我想让其他国家/地区在点击时变暗/调整不透明度怎么办?
  • 一种方法是给你选择的一个类(例如“选择”)。然后你可以有一个 CSS 规则,比如:svg &gt; :not(.selected) { opacity: 0.5; }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
相关资源
最近更新 更多