计算圆SVG内路径终点的x和y

我有一个进度条,可以通过更改路径的stroke-dashoffset属性来进行更新。但是,每次更新时,我都需要计算海军路径的端点(圆形边)的x和y坐标。我将在将来的这些时候添加标签。一段时间以来,我一直在head头。我曾尝试使用与const x = radius * Math.sin(Math.PI * 2 * angle / 360);const y = radius * Math.cos(Math.PI * 2 * angle / 360);类似的东西,但我认为我没有正确使用它们。有人可以协助我吗?旁注:我只使用vanilla JS。

const setStrokeDashOffset = (e) => {
  const dashOffset = e.target.getattribute('data-attr');
  document
    .getElementById('progress-meter')
    .setattribute('stroke-dashoffset',dashOffset);
}


const btn = document.querySelectorAll('button');
btn.forEach(x => {
  x.addEventListener('click',(e) => {
    setStrokeDashOffset(e)
  });
});
.donut-progress__svg {
  transform: scaleX(-1);
}

.donut-progress__circle {
  fill: none;
  stroke: none;
}

.donut-progress__path-elapsed {
  stroke: #aaaaaa;
  stroke-width: 10;
}

.donut-progress__path-remaining {
  stroke: navy;
  stroke-linecap: round;
  stroke-width: 10;
  transform: rotate(90deg);
  transform-origin: center;
  transition: 0.3s linear all;
}

.donut-progress__path-start {
  stroke: orange;
  stroke-linecap: round;
  stroke-width: 10;
  transform: rotate(90deg);
  transform-origin: center;
}
<svg id="donut-progress__svg" class="donut-progress__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
			<g class="donut-progress__circle">
				<circle class="donut-progress__path-elapsed" cx="50" cy="50" r="45"></circle>
				<path id="progress-meter" stroke-dasharray="283 283" stroke-dashoffset="165.08333333333334" class="donut-progress__path-remaining" stroke="#4764ae" d="
					M 50,50
					m -45,0
					a 45,45 0 1,0 90,0 -90,0
					"></path>
          <path opacity="1" id="progress-meter-start" class="donut-progress__path-start" stroke-dashoffset="282" stroke-dasharray="283" d="
					M 50,0
					"></path>
			</g>
		</svg>


<button data-attr="100" class="one">move to 100</button>
<button data-attr="150" class="one">move to 150</button>
<button data-attr="200" class="one">move to 200</button>

flb1492 回答:计算圆SVG内路径终点的x和y

SVG提供了一种针对<path>元素的方法,在这里您会发现它非常有用:

myPath.getPointAtLength(len)

以下示例。

const setStrokeDashOffset = (e) => {
  const dashOffset = e.target.getAttribute('data-attr');
  document
    .getElementById('progress-meter')
    .setAttribute('stroke-dashoffset',dashOffset);
}


const showEndPoint = (e) => {
  const dashOffset = e.target.getAttribute('data-attr');
  // Get the X,Y position of a point at "dashOffset" along the path
  const pt = document
    .getElementById('progress-meter')
    .getPointAtLength(dashOffset);
  // Update our red dot to show the location
  // Note that we are switching X and Y here to compensate for the fact that you rotate the original path
  const endpoint = document.getElementById('endpoint')
  endpoint.setAttribute('cx',pt.y);
  endpoint.setAttribute('cy',pt.x);
}


const btn = document.querySelectorAll('button');
btn.forEach(x => {
  x.addEventListener('click',(e) => {
    setStrokeDashOffset(e);
    
    showEndPoint(e);
  });
});
.donut-progress__svg {
  transform: scaleX(-1);
}

.donut-progress__circle {
  fill: none;
  stroke: none;
}

.donut-progress__path-elapsed {
  stroke: #aaaaaa;
  stroke-width: 10;
}

.donut-progress__path-remaining {
  stroke: navy;
  stroke-linecap: round;
  stroke-width: 10;
  transform: rotate(90deg);
  transform-origin: center;
  transition: 0.3s linear all;
}

.donut-progress__path-start {
  stroke: orange;
  stroke-linecap: round;
  stroke-width: 10;
  transform: rotate(90deg);
  transform-origin: center;
}
<svg id="donut-progress__svg" class="donut-progress__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
			<g class="donut-progress__circle">
				<circle class="donut-progress__path-elapsed" cx="50" cy="50" r="45"></circle>
				<path id="progress-meter" stroke-dasharray="283 283" stroke-dashoffset="165.08333333333334" class="donut-progress__path-remaining" stroke="#4764ae" d="
					M 50,50
					m -45,0
					a 45,45 0 1,0 90,0 -90,0
					"></path>
          <path opacity="1" id="progress-meter-start" class="donut-progress__path-start" stroke-dashoffset="282" stroke-dasharray="283" d="
					M 50,0
					"></path>
			</g>
      <circle id="endpoint" r="3" fill="red"/>
		</svg>


<button data-attr="100" class="one">move to 100</button>
<button data-attr="150" class="one">move to 150</button>
<button data-attr="200" class="one">move to 200</button>

这是您的SVG的略微修改版本,避免了切换X和Y坐标的必要-如先前版本的代码中所述。

const setStrokeDashOffset = (e) => {
  const dashOffset = e.target.getAttribute('data-attr');
  document
    .getElementById('progress-meter')
    .setAttribute('stroke-dashoffset',Y position of a point at "dashOffset" along the path
  const path = document.getElementById('progress-meter');
  const pt = path.getPointAtLength(path.getTotalLength() - dashOffset);
  // Update our red dot to show the location
  const endpoint = document.getElementById('endpoint')
  endpoint.setAttribute('cx',pt.x);
  endpoint.setAttribute('cy',pt.y);
}


const btn = document.querySelectorAll('button');
btn.forEach(x => {
  x.addEventListener('click',(e) => {
    setStrokeDashOffset(e);
    
    showEndPoint(e);
  });
});
.donut-progress__svg {
  transform: scaleX(-1);
}

.donut-progress__circle {
  fill: none;
  stroke: none;
  transform: rotate(90deg);
  transform-origin: center;
}

.donut-progress__path-elapsed {
  stroke: #aaaaaa;
  stroke-width: 10;
}

.donut-progress__path-remaining {
  stroke: navy;
  stroke-linecap: round;
  stroke-width: 10;
  transition: 0.3s linear all;
}

.donut-progress__path-start {
  stroke: orange;
  stroke-linecap: round;
  stroke-width: 10;
}
<svg id="donut-progress__svg" class="donut-progress__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
			<g class="donut-progress__circle">
				<circle class="donut-progress__path-elapsed" cx="50" cy="50" r="45"></circle>
				<path id="progress-meter" stroke-dasharray="283 283" stroke-dashoffset="165.08333333333334" class="donut-progress__path-remaining" stroke="#4764ae" d="
					M 50,0
					"></path>

          <circle id="endpoint" r="3" fill="red"/>
			</g>
		</svg>


<button data-attr="100" class="one">move to 100</button>
<button data-attr="150" class="one">move to 150</button>
<button data-attr="200" class="one">move to 200</button>

本文链接:https://www.f2er.com/2541732.html

大家都在问