SVG路径:如何标记结束箭头到圆边框?

时间:2016-07-03 04:36:25

标签: svg

我制作圆圈(约Radian为20)。里面有一些文字。 我想画箭头路径。 所以我使用“marker-end”。但是圈子覆盖箭头。 如何(我可以)将标记结束位置移动到圆形边界?

<svg width="600px" height="400px" xmlns="http://www.w3.org/2000/svg" version="1.1">


<defs><!-- ready for endpoint arrow -->
<marker id="endpoint" viewBox="-50 0 50 50" refX="0" refY="25" markerUnits="strokeWidth" markerWidth="20" markerHeight="20" orient="auto">
  <path d="M -50 0 L 0 25 L -50 50 z"></path>
</marker>
</defs>
  
<g>
<text x="10" y="50">Trouble : Arrow Hide(override) by Circle</text>
<path d="M 0,100 C 50,100 80,131 130,131 C 130,131 190,130 200,100" 
        stroke="black" fill="none" marker-end="url(#endpoint)"></path>
  <path d="M 440,100 C 350,100 350,131 300,131 C 260,131 230,60 200,100"
        stroke="black" fill="none" marker-end="url(#endpoint)"></path>
 <circle cx="200" cy="100" r="20" stroke-width="2px" stroke="#aaa" fill="#fff" opacity="0.95"></circle>
<text x="165" y="105">Some Text</text>
 </g>
 <g>
 <text x="10" y="240">What I want?</text>
 <text x="10" y="260">Auto detect arrow head to border</text>
<path d="M 0,300 C 50,300 80,331 130,331 C 130,331 180,330 200,300" stroke="black" fill="none"></path>
<path d="M 185 315 L 174 312 L 185 326 z"></path>
   
   
<path d="M 440,300 C 350,300 350,331 300,331 C 260,331 230,260 200,300" stroke="black" fill="none"></path>
<path d="M 216 289 L 223 295 L 220 283 z"></path>
 
 <circle cx="200" cy="300" r="20" stroke-width="2px" stroke="#aaa" fill="#fff" opacity="0.75"></circle>
 <text x="165" y="305">Some Text</text>
 </g>
 <!-- /////////////////////////////////////////////// -->
 </svg>

2 个答案:

答案 0 :(得分:0)

没有办法让标记沿着远离末端的线条拉回来。

你需要自己画箭头。或者让线条以圆圈边界结束。

答案 1 :(得分:0)

谢谢大家。我尝试另一种方式。 实施例。

var draw = function(type, opts) {
  var svg = document.createElementNS("http://www.w3.org/2000/svg", type);
  for (var k in opts) {
    svg.setAttribute(k, opts[k]);
  }
  return svg;
};


var getCircleDestination = function(from, to) {

  var tx = parseFloat(to.getAttribute("cx"));
  var ty = parseFloat(to.getAttribute("cy"));

  var fx = from.center.x;
  var fy = from.center.y;

  var w = fx - tx;
  var h = fy - ty;

  var z = Math.sqrt(w * w + h * h);
  var r = parseFloat(to.getAttribute("r"));

  var dz = z / r;

  var dx = tx + w / dz;
  var dy = ty + h / dz;

/* dx2,dy2 ...dz * 1.2 is no good idea. */
  var dx2 = tx + w / (dz * 1.2); 
  var dy2 = ty + h / (dz * 1.2);

  var circle = draw("circle", {
    "cx": dx,
    "cy": dy,
    "r": 3,
    "fill": "red"
  });

  return {
    "s": {
      "x": dx2,
      "y": dy2
    },
    "svg": circle
  };
};





var canvas = draw("svg", {
  "width": "400",
  "height": "150",
  "style": "background-color:#f0f0f0;border:1px solid black;"
});
var def = draw("defs", {});
var marker = draw("marker", {
  "id": "endpoint",
  "viewBox": "-50 0 50 50",
  "refX": 0,
  "refY": 25,
  "markerUnits": "strokeWidth",
  "markerWidth": 10,
  "markerHeight": 10,
  "orient": "auto"
});
var marker_path = draw("path", {
  "d": "M -50 0 L 0 25 L -50 50 z"
});
var btn = document.createElement("button");
btn.style.display = "block";
btn.innerHTML = "Add Line";

canvas.appendChild(def);
canvas.appendChild(marker);
marker.appendChild(marker_path);

document.getElementById("canvas").appendChild(canvas);
document.getElementById("canvas").appendChild(btn);

var circle = draw("circle", {
  "cx": 200,
  "cy": 75,
  "r": 10,
  "fill": "white",
  "stroke": "black",
  "stroke-width": 1,
  "opacity": 0.5
});
canvas.appendChild(circle);

var paths = new Array();
btn.addEventListener("click", function() {
  var x = Math.random() * canvas.clientWidth;
  var y = Math.random() * canvas.clientHeight;
  var from = {
    "center": {
      "x": x,
      "y": y
    }
  };

  var svg = getCircleDestination(from, circle);
  var c = svg.svg;
  var stx = svg.s.x;
  var sty = svg.s.y;

  var ttx = svg.s.x + (Math.random() * 10 + 15) * (svg.s.x < x ? 1 : -1);
  var tty = svg.s.y + (Math.random() * 10 + 15) * (svg.s.y < y ? 1 : -1);

  var p = draw("path", {
    "d": "M" + x + "," + y + " Q " + ttx + "," + tty + " " + stx + "," + sty + " " + c.getAttribute("cx") + "," + c.getAttribute("cy"),
    "stroke": "black",
    "fill": "none",
    "marker-end": "url(#endpoint)"
  });


  canvas.appendChild(c);
  canvas.appendChild(p);
  paths.push({
    "c": c,
    "p": p
  });
  if (paths.length > 5) {
    var t = paths.shift();
    t.c.remove();
    t.p.remove();
  }
});
<div id="canvas"></div>