如何沿另一个圆的路径定位 SVG 圆 [英] How to position an SVG circle along another circle's path

查看:30
本文介绍了如何沿另一个圆的路径定位 SVG 圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 React 的展示组件中构建仪表图.

我只需要传递一个百分比,然后让组件完成剩下的工作.我无法使用任何动画,因为我正在截取组件的屏幕截图以将图像放入 Powerpoint 演示文稿中.

这是我正在尝试执行的操作的屏幕截图:

正如您在我的代码片段中看到的,圆圈 被定位在灰色 的末尾而不是末尾绿色.我如何定位圆圈,使其位于绿色 stroke-linecap 处,如上图所示?

这是我目前的 HTML 代码:

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><定义><标记id="点"viewBox="0 0 10 10"refX="4"refY="4"标记宽度=4"标记高度=4"><圆CX=4"cy="4"r="2"填充=#FFFFFF"中风="#008000"笔画宽度=2"/></标记></defs><path d="M20,60a35,35 0 1,1 60,0"stroke="#D3D7DB"stroke-width="4" fill="none"stroke-linecap="round"></path><path d="M20,60a35,35 0 1,1 60,0" stroke="#008000" stroke-width="6" pathLength="100" fill="none" stroke-linecap="round" stroke-dasharray="75 35" marker-end="url(#dot)"></path></svg>

解决方案

您可以通过设置 pathLength 并使用 animationMotion 定位圆来在 SVG 中完成所有操作.

一些 JavaScript 和 W3C 标准 Web 组件(所有现代浏览器都支持)有助于在屏幕上放置多个仪表并使它们动态化.

<svg-gauge value="35" color="red"></svg-gauge><svg-gauge value="50" color="orange"></svg-gauge><svg-gauge value="75" color="green"></svg-gauge><脚本>customElements.define("svg-gauge", class extends HTMLElement {连接回调(){让弧 = "M20,60a35,35 0 1,1 60,0";let col = this.getAttribute("color")||"green";this.innerHTML =`<input type="range" min="0" max="100" step="5" value="0"`+//删除2行` oninput="this.parentNode.percent=this.value"/><br>`+//仅用于演示`<svg viewbox="0 0 100 100"><path d="${arc}" stroke="grey" stroke-width="6" fill="none"stroke-linecap="round"></path><path id="P" d="${arc}" stroke="${col}" stroke-width="8" pathLength="100"fill="none" stroke-linecap="round" stroke-dasharray="75 35"></path><circle cx="0" cy="0" fill="#fff" r="4" stroke="${col}" stroke-width="3"><animateMotion dur="0.5s" keyPoints="0;0.75"fill="freeze" keyTimes="0;1" calcMode="linear" path="${arc}"></animateMotion></circle><text x="50%" y="40%" text-anchor="middle">XXX</text></svg>`;this.style.display='inline-block';this.percent = this.getAttribute("value");}设置百分比(val = 0){this.setAttribute("value", val);让破折号 = val + " " + (105 - val);this.querySelector("#P").setAttribute('stroke-dasharray', dash);this.querySelector("animateMotion").setAttribute('keyPoints', '0;'+val/100);this.querySelector("text").innerHTML =`${val} %`;this.querySelector("animateMotion").beginElement();this.querySelector("input").value = val;}})</script>

I'm building a Gauge chart in a presentational component in React.

I just need to pass it a percentage and let the component do the rest. I can't use any animations because I'm taking a screenshot of the component to place the image in a Powerpoint presentation.

Here's a screenshot of what I'm trying to do:

As you can see in my code snippet, the circle <marker> is being positioned at the end of the grey <path> instead of at the end of the green <path>. How could I position the circle so it sits at the stroke-linecap of the green <path> as in the image above?

Here's the HTML code I have so far:

<div style="width:400px">
  <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <marker
        id="dot"
        viewBox="0 0 10 10"
        refX="4"
        refY="4"
        markerWidth="4"
        markerHeight="4"
      >
        <circle
          cx="4"
          cy="4"
          r="2"
          fill="#FFFFFF"
          stroke="#008000"
          stroke-width="2"
        />
      </marker>
    </defs>
    <path d="M20,60a35,35 0 1,1 60,0" stroke="#D3D7DB" stroke-width="4" fill="none" stroke-linecap="round"></path>
    <path d="M20,60a35,35 0 1,1 60,0" stroke="#008000" stroke-width="6" pathLength="100" fill="none" stroke-linecap="round" stroke-dasharray="75 35" marker-end="url(#dot)"></path>
  </svg>
</div>

解决方案

You can do it all in SVG by setting pathLength and using animationMotion to position the circle.

Some JavaScript and a W3C standard Web Component (supported in all modern Browsers) help in putting multiple gauges on screen and making them dynamic.

<svg-gauge value="35" color="red"></svg-gauge>
<svg-gauge value="50" color="orange"></svg-gauge>
<svg-gauge value="75" color="green"></svg-gauge>
<script>
  customElements.define("svg-gauge", class extends HTMLElement {
    connectedCallback() {
      let arc = "M20,60a35,35 0 1,1 60,0";
      let col = this.getAttribute("color")||"green";
      this.innerHTML = 
      `<input type="range" min="0" max="100" step="5" value="0"`+ // delete 2 lines
      ` oninput="this.parentNode.percent=this.value" /><br>`+ // just for demo
`<svg viewbox="0 0 100 100">
  <path d="${arc}" stroke="grey" stroke-width="6" fill="none" 
        stroke-linecap="round"></path>
  <path id="P" d="${arc}" stroke="${col}" stroke-width="8" pathLength="100" 
        fill="none" stroke-linecap="round" stroke-dasharray="75 35"></path>
  <circle cx="0" cy="0" fill="#fff" r="4" stroke="${col}" stroke-width="3">
     <animateMotion dur="0.5s" keyPoints="0;0.75" 
                    fill="freeze" keyTimes="0;1" calcMode="linear" path="${arc}">
     </animateMotion></circle>
  <text x="50%" y="40%" text-anchor="middle">XXX</text>
</svg>`;
      this.style.display='inline-block';
      this.percent = this.getAttribute("value");
    }
    set percent(val = 0) {
      this.setAttribute("value", val);
      let dash = val + " " + (105 - val);
      this.querySelector("#P").setAttribute('stroke-dasharray', dash);
      this.querySelector("animateMotion").setAttribute('keyPoints', '0;'+val/100);
      this.querySelector("text").innerHTML =`${val} %`;
      this.querySelector("animateMotion").beginElement();
      this.querySelector("input").value = val;
    }
  })
</script>

这篇关于如何沿另一个圆的路径定位 SVG 圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆