将div放在svg轨道上

时间:2018-10-08 11:02:00

标签: javascript jquery html html5 svg

我正在尝试将25px * 25px div放置在svg轨道的特定百分比上。这就是我现在做的方式:

getCheckpointPercent(); 

//Get the readers from the Json file, and add the percentage to the array.
function getCheckpointPercent(){
    $.getJSON("readers.json", function (data) {
        var total = 0;
        var semitotal = 0;
        var currentdistance = 0;
        $.each(data, function (index, value) {
            total = total + value['distanceToNext'];
        });
        console.log(total);  

        $.each(data, function (index, value) {
            value['percent'] = semitotal / total * 100;
            semitotal = semitotal + value['distanceToNext'];

        });                
        console.log(data);
        placeCheckpoints(data);
    });
}



//Place the checkpoints on the track, on the spot the corresponds to their percentage
function placeCheckpoints(readers){
    $.each(readers, function (index, value) {
        var punt = getPointOnTrack(value['percent']);
        $('#cps').append('<div class="checkpoint" id="'+index+'"></div>');
        $( "#"+index ).css('left',punt.x);
        $( "#"+index ).css('top',punt.y);
        $( "#"+index ).css('position','absolute');
    });
}




//Get coords of point on track using percentage
function getPointOnTrack(prcnt){

    var track = $( '#track' );
    var trackLength = document.getElementById( 'track' ).getTotalLength();
    var part = trackLength * prcnt / 100;
    pt = document.getElementById( 'track' ).getPointAtLength(part);
    return pt;
}

具有以下结果: https://imgur.com/a/bW0KuCN

如您所见,它偏离了一些像素。我如何正确放置它们?

编辑:SVG跟踪:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="100%" height="100%"  viewBox="0 0 1783 903" id="svg">
      <path d="M1697.17,63.491c-105.906,-119.003 -609.921,-29.945 -876.794,34.426c-164.703,39.726 -224.547,269.311 -335.753,272.609c-214.672,6.366 -258.259,-379.064 -345.329,-337.073c-178.323,85.998 -184.301,834.002 13.654,836.966c177.382,2.655 251.631,-254.971 409.655,-235.198c181.21,22.674 152.502,168.163 391.991,209.317c228.308,39.232 223.472,-183.574 312.715,-193.699c73.817,-8.375 276.248,275.455 417.573,244.156c130.744,-28.956 112.095,-279.189 12.288,-326.222c-157.212,-74.083 -693.907,-55.006 -724.395,-117.798c-54.001,-111.215 464.9,-139.592 415.502,-226.446c-53.998,-94.941 428.86,-26.236 308.893,-161.038Z" stroke="#000000" stroke-width="2" fill="none" id="track"/>
</svg>

1 个答案:

答案 0 :(得分:0)

我不太确定这是您想要的:div #label的位置是鼠标在div #SVG上的位置#label的文本内容是路径上点的x和y属性的值。

请阅读代码中的注释。

const SVG_NS = "http://www.w3.org/2000/svg";
// the total length of the path
let l = test.getTotalLength();
// the array of the points on the path
let points = [];

for (let i = 0; i < l; i += l / 4) {
  // test is the id for the path 
  let point = test.getPointAtLength(i);
  points.push(point);
}

// for every point I draw a circle
let circles = [];

for (let i = 0; i < points.length; i++) {
  let o = { cx: points[i].x, cy: points[i].y, r: 30, fill: "blue" };
  // create a new circle and save the circle in the circles array
  circles.push(drawCircle(o, svg));
}

// a function to draw a circle
function drawCircle(o, parent) {
  let circle = document.createElementNS(SVG_NS, "circle");
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      circle.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(circle);
  return circle;
}


// for each circle there is an event listener  that calculate the position of the div #label
circles.forEach(c => {
  c.addEventListener("mouseenter", evt => {
    let x = parseInt(c.getAttribute("cx"));
    let y = parseInt(c.getAttribute("cy"));
    label.innerHTML = `x: ${x} <br> y: ${y}`;
    
    let m = oMousePos(svg, evt);

    label.style.cssText = `top:${m.y}px; left:${m.x}px; opacity:1`;
  });
});


//when the mouse is not over the circle, the label's opacity is 0
divSVG.addEventListener("mouseover", () => {
  label.style.opacity = 0;
});


// a function that gets the position of the mouse over an HTML element 
function oMousePos(elmt, evt) {
  var ClientRect = elmt.getBoundingClientRect();
  return {
    //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
  };
}
path {
  stroke: black;
  fill:none;
}
#label {
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  opacity: 0;
  background:white;
  pointer-events:none;
  transition: all 0.5s;
}
.svg {
  position: relative;
}
<div class="svg" id="divSVG">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="100%" height="100%"  viewBox="0 0 1783 903" id="svg">
      <path id="test"  d="M1697.17,63.491c-105.906,-119.003 -609.921,-29.945 -876.794,34.426c-164.703,39.726 -224.547,269.311 -335.753,272.609c-214.672,6.366 -258.259,-379.064 -345.329,-337.073c-178.323,85.998 -184.301,834.002 13.654,836.966c177.382,2.655 251.631,-254.971 409.655,-235.198c181.21,22.674 152.502,168.163 391.991,209.317c228.308,39.232 223.472,-183.574 312.715,-193.699c73.817,-8.375 276.248,275.455 417.573,244.156c130.744,-28.956 112.095,-279.189 12.288,-326.222c-157.212,-74.083 -693.907,-55.006 -724.395,-117.798c-54.001,-111.215 464.9,-139.592 415.502,-226.446c-53.998,-94.941 428.86,-26.236 308.893,-161.038Z" stroke="#000000" stroke-width="2" fill="none" id="track"/>


  
</svg>

  <div id="label" ></div>
  
  
  
</div>