我想要达到的结果是:

Goal

到目前为止,我所取得的成就是:

Current situation

我搞不懂的是:

  1. 如何使半圆中的线条的拐角变圆
  2. 如何在填充的半圆的末端添加垂直线

Still need to figure this out

有人能帮帮忙吗?

完整的代码如下:

function App() {
  return <SemiCircleProgress percentage={70} />;
}

function SemiCircleProgress({ percentage }) {
    const strokeWidth = 25;
    const background = "#D9D9D9";
    const diameter = 400;

    const coordinateForCircle = diameter / 2;
    const radius = (diameter - 2 * strokeWidth) / 2;
    const circumference = Math.PI * radius;
    const semiCirclePercentage = percentage * (circumference / 100);

    return (
        <div className="semicircle-container">
            <svg
                width={diameter}
                height={diameter / 2}
                style={{ transform: "rotateY(180deg)", overflow: "hidden" }}
            >
                <linearGradient id="gradient">
                    <stop offset="0%" stopColor="#B8F1C6" />
                    <stop offset="100%" stopColor="#EBF8A1" />
                </linearGradient>

                <circle
                    cx={coordinateForCircle}
                    cy={coordinateForCircle}
                    r={radius}
                    fill="none"
                    stroke={background}
                    strokeWidth={8}
                    strokeDasharray={circumference}
                    style={{
                        strokeDashoffset: circumference
                    }}
                />
                <circle
                    cx={coordinateForCircle}
                    cy={coordinateForCircle}
                    r={radius}
                    fill="none"
                    stroke="url(#gradient)"
                    strokeWidth={strokeWidth}
                    strokeDasharray={circumference}
                    style={{
                        strokeDashoffset: semiCirclePercentage,
                        transition:
                            "stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
                    }}
                />
            </svg>
        </div>
    );
}


ReactDOM.render( < App / > , document.getElementById("root"));
body {
  background: #292929;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

推荐答案

线帽由stroke-linecap attribute控制.这个特殊的例子的问题是,它的一端是圆形的,另一端是正方形的.因此,我使用一个面具来创造"米"的形状."值"由蒙版中的黑色圆圈笔触控制.

跟在"米"后面的那条线被放在中间,然后旋转.

document.forms.f1.range.addEventListener('change', e => {
  let angle = 180 / 100 * e.target.value;
  document.getElementById('c1').setAttribute('stroke-dasharray', `180 ${angle}`);
  document.getElementById('l1').setAttribute('transform', `translate(50 50) rotate(${angle})`);
  document.getElementById('t1').textContent = e.target.value;
});
body {
  background: #292929;
}
<form name="f1">
  <input type="range" name="range" min="0"
    max="100" value="90" />
</form>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60"
  width="400">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0%" stop-color="#B8F1C6" />
      <stop offset="100%" stop-color="#EBF8A1" />
    </linearGradient>
    <mask id="m1">
      <circle cx="50" cy="50" r="43" fill="none"
        stroke="white" stroke-width="6" stroke-dasharray="180"
        pathLength="360" stroke-linecap="round"
        transform="rotate(184 50 50)"/>
      <circle id="c1" cx="50" cy="50" r="43" fill="none"
        stroke="black" stroke-width="8"
        stroke-dasharray="180 162" pathLength="360" />
    </mask>
  </defs>
  <circle cx="50" cy="50" r="43" fill="none"
    stroke="gray" stroke-width="2" stroke-dasharray="175 360"
    pathLength="360" stroke-linecap="round" transform="rotate(184 50 50)"/>
  <rect width="100" height="60" fill="url(#gradient)" mask="url(#m1)"/>
  <line id="l1" x1="-36" y1="0" x2="-50" y2="0" stroke="white"
    stroke-width=".3" transform="translate(50 50) rotate(162)" />
  <text id="t1" x="50" y="40" text-anchor="middle" fill="#EBF8A1"
    font-family="sans-serif">90</text>
  <text x="7" y="57" text-anchor="middle" fill="gray"
    font-family="sans-serif" font-size="5">0</text>
  <text x="93" y="57" text-anchor="middle" fill="gray"
    font-family="sans-serif" font-size="5">100</text>
</svg>

Javascript相关问答推荐

使用print This时, map 容器已在LeafletJS中初始化

是什么原因导致此Angular 16应用程序中类型错误时属性结果不存在?

使用useup时,React-Redux无法找到Redux上下文值

单击子元素时关闭父元素(JS)

Chrome是否忽略WebAuthentication userVerification设置?""

查找最长的子序列-无法重置数组

JS,当你点击卡片下方的绿色空间,而它是在它的背后转动时,

Angular 订阅部分相互依赖并返回数组多个异步Http调用

如何将zoom 变换应用到我的d3力有向图?

一个实体一刀VS每个实体多刀S

按下单键和多值

如何使用基于promise (非事件emits 器)的方法来传输数据?

不协调嵌入图片

如何使用Reaction路由导航测试挂钩?

Promise.race()返回已解析的promise ,而不是第一个被拒绝的promise

当达到高度限制时,如何裁剪图像?使用html和css

如何使用useparams从react路由中提取id

如何格式化API的响应

:host::ng-Deep不将样式应用于material 复选框

调试jQuery代码以获取所有行的总和(票证类型)