猿问

根据具有变换属性的另一个路径协调插入 svg 路径

我想在我已经应用了属性的另一条路径(带有进度参数)上插入一条路径transform。


问题是,当我从 和 params 获取点位置时,getPointAtLength(//h2 path//)与h2 的位置不同x。y


所以他们的定位是开箱即用的。


let paths = d3.select('svg').select("#h2").selectAll('path.train').data([1,2]);

let branch=d3.select('svg').select("#h2").select('path')

paths.enter().append('path')

          .attr('d', d3.symbol().type(d3.symbolTriangle))

          .attr('class', 'train')

          .attr('fill','black')

          .attr('transform',(d,i)=>  {

          let point = branch.node()

              .getPointAtLength(30)

           return `translate(${point.x},${point.y}`

          })

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.0/d3.min.js"></script>

<svg viewBox="0 0 388.71 412.14">

    <g data-id="branch" id="h2" transform="translate(-885 -562) ">

        <g class="branch-label" id="h2select" transform="translate(-240 -340)"></g>

        <rect fill="rgba(255,255,255,1)" height="11" id="h2" width="12"></rect>

        <path d="M1093.763,1595.658 v -82.417 c 0,0 5,-14.987 -18.452,-16.644 -23.452,-1.657 -40.9,2.386 -54.093,-11.537 -13.193,-13.923 -132.873,-159.193 -132.873,-159.193 0,0 -6.456,-10.249 -24.986,-14.661 -18.53,-4.412 -11.029,-16.736 -2.10392,-28.6309 2.68431,-3.5775 12.32475,-15.4715 21.44325,-26.363" data-name="h2" fill="none" id="h2-3" stroke="#efcf2f" stroke-linecap="round" stroke-width="2" transform="translate(208.67 -656.38)" style="opacity: 1;"></path>

    </g>

</svg>

我想要的是如何将三角形定位在路径的 30% 处而不删除 svg 上的“变换属性”?


炎炎设计
浏览 104回答 0
0回答

偶然的你

我们可以将路径“包装”在 ag 元素中,并为 g 元素提供路径的变换并将其从路径中删除吗?那么你的方法应该有效吗?var child = document.getElementById('h2-3');var parent = child.parentNode;var i = Array.prototype.indexOf.call(parent.children, child);console.log(i);child = parent.removeChild(child);var g = document.createElementNS('http://www.w3.org/2000/svg','g');g.setAttribute('transform', child.getAttribute('transform'));child.removeAttribute('transform');g.appendChild(child);if (i < parent.childNodes.length) {  parent.insertBefore(g, parent.childNodes[i]);} else {  parent.appendChild(g);}const len = child.getTotalLength();//console.log(len)const point = child.getPointAtLength(0.99*len);var circle = document.createElementNS('http://www.w3.org/2000/svg','circle')circle.setAttribute('cx', point.x);circle.setAttribute('cy', point.y);circle.setAttribute('r', 10);circle.setAttribute('fill', 'black');g.appendChild(circle);var myInterval;var currProgress = 0.995;var direction = -1;var count = 0;myInterval = setInterval(myAnimate, 50);function myAnimate() {  if (currProgress <= 0.0 || currProgress >= 1.0) {    direction *= -1;  }  //console.log(currProgress);  const myPoint = child.getPointAtLength(currProgress * len);  circle.setAttribute("cx", myPoint.x);  circle.setAttribute("cy", myPoint.y);  currProgress += direction * 0.005;  if (count >= 5) {    clearInterval(myInterval);  }}/*let paths = d3.select('svg').select("#h2").selectAll('path.train').data([1,2]);let branch = d3.select('svg').select("#h2").select('path')paths.enter().append('path')          .attr('d', d3.symbol().type(d3.symbolTriangle))          .attr('class', 'train')          .attr('fill','black')          .attr('transform',(d,i)=>  {          let point = branch.node()              .getPointAtLength(30)           return `translate(${point.x},${point.y}`          }) */<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.0/d3.min.js"></script><svg viewBox="0 0 450 500">    <g data-id="branch" id="h2" transform="translate(-885 -562) ">        <g class="branch-label" id="h2select" transform="translate(-240 -340)"></g>        <rect fill="rgba(255,255,255,1)" height="11" id="h2" width="12"></rect>        <path d="M1093.763,1595.658 v -82.417 c 0,0 5,-14.987 -18.452,-16.644 -23.452,-1.657 -40.9,2.386 -54.093,-11.537 -13.193,-13.923 -132.873,-159.193 -132.873,-159.193 0,0 -6.456,-10.249 -24.986,-14.661 -18.53,-4.412 -11.029,-16.736 -2.10392,-28.6309 2.68431,-3.5775 12.32475,-15.4715 21.44325,-26.363" data-name="h2" fill="none" id="h2-3" stroke="#efcf2f" stroke-linecap="round" stroke-width="2" transform="translate(208.67 -656.38)" style="opacity: 1;"></path>    </g></svg>我们可以用下面的 JS 来做到这一点:var child = document.getElementById('h2-3');var parent = child.parentNode;var i = Array.prototype.indexOf.call(parent.children, child);console.log(i);child = parent.removeChild(child);var g = document.createElementNS('http://www.w3.org/2000/svg','g');g.setAttribute('transform', child.getAttribute('transform'));child.removeAttribute('transform');g.appendChild(child);if (i < parent.childNodes.length) {  parent.insertBefore(g, parent.childNodes[i]);} else {  parent.appendChild(g);}这样,您可以将路径“包装”在 ag 元素中,并为 g 元素提供路径的变换并将其从路径中删除。生成的 DOM 为:然后我们可以使用以下 JS 在路径长度的 30% 处放置一个圆:const len = child.getTotalLength();console.log(len)const point = child.getPointAtLength(0.3*len);var circle = document.createElementNS('http://www.w3.org/2000/svg','circle')circle.setAttribute('cx', point.x);circle.setAttribute('cy', point.y);circle.setAttribute('r', 10);circle.setAttribute('fill', 'black');g.appendChild(circle);然后我们将其作为输出(您可以使用child.getPointAtLength(0.3*len)其他值,例如 0.6*len 来查看其他位置的圆):更新实际上,我注意到你的一些路径被切断,因为它位于 svg 视图框之外,所以我修改了视图框,如下所示:<svg viewBox="0 0 450 500">然后我还添加了一些动画代码,因为,为什么不呢!var myInterval;var currProgress = 0.995;var direction = -1;var count = 0;myInterval = setInterval(myAnimate, 50);function myAnimate() {  if (currProgress <= 0.0 || currProgress >= 1.0) {    direction *= -1;  }  //console.log(currProgress);  const myPoint = child.getPointAtLength(currProgress * len);  circle.setAttribute("cx", myPoint.x);  circle.setAttribute("cy", myPoint.y);  currProgress += direction * 0.005;  if (count >= 5) {    clearInterval(myInterval);  }}
随时随地看视频慕课网APP

相关分类

Html5
我要回答