d3.jspaintsvg-path

d3.js: paintbrush with d3.svg.area problems


I am trying to make a tool to draw an arbitrary figure like in this example - Line Drawing, but using path itself with fill - not stroke. Here is what i already done - https://jsfiddle.net/zeleniy/b14paam2/. Example already contains single arbitrary path figure, but you can draw by yourself using dragging.

As you can see a have two troubles:

  1. Nib is sloped i do not know why. As consequence when draw diagonal line from top-right to bottom-left or vice versa path almost invisible.

  2. In places where path intersect itself filling are absent.

How to fix this problems?


Solution

  • You can use line instead of area, it is more suitable for brush.

    var path;
    
    var area = d3.svg.line()
      .x(function(d) { return d[0]; })
      .y(function(d) { return d[1]; })
      .tension(0)
      .interpolate("basis");
    
    var svg = d3.select("svg")
    	.call(d3.behavior.drag()
    		.on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended));
    
    function dragstarted() {
      path = svg.append("path").datum([]).attr("class", "line")
      			.attr({
            	"fill": "none",
              "stroke": "lightblue",
              "stroke-width": 25 + "px",
              "stroke-linejoin": "round"
            });
    }
    
    function dragged() {
      path.datum().push(d3.mouse(this));
      path.attr("d", area);
    }
    
    function dragended() {
      path = null;
    }
    svg {
      border: 2px solid gray;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
    <h2>Paint with brush</h2>
    <svg width="100%" height="300px"></svg>