不带伪影的SVG中的粗Bezier曲线 [英] Thick Bezier curves in SVG without artifacts

查看:115
本文介绍了不带伪影的SVG中的粗Bezier曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试绘制厚的



资料来源: http: //jsfiddle.net/stared/83jr5fub/



是否有办法避开工件,例如:




  • 确保 x1 左侧没有任何内容或 x

  • 左右的实际宽度匹配 stroke-width


解决方案

我认为他最好的解决方案在你的情况下(与给定的路径),是使你的路径关闭,并使用其fill属性。 / p>

要做到这一点,你必须在 lineTo(0,strokeWidth) code> BezierCurveTo ,然后以其他方式重绘bezierCurve:



  var svg = d3 .select(#chart); var data = [{t:5,dy:10},{t:5,dy:20},{t:5,dy:40} t:50,dy:20},{t:50,dy:20},{t:20,dy: 40},]; var ctrl = 10; var dx = 40; var spacing = 100; var colors = d3.scale.category10(); svg .attr(width,4 * spacing).attr(height 4 * spacing); svg.selectAll(path).data(data).enter().append(path).attr(d,function(d,i){var x1 = (i%3); var y1 = spacing + spacing * Math.floor(i / 3);返回M+ x1 +,+ y1 +c+ ctrl +,+ 0 ++(dx-ctrl)+,+ d.dy ++ dx + + d.dy + //向下移动所需宽度l+(0)+,+(dt)+ //取消所有值c+(ctrl * -1)+,+ 0 ++((dx-ctrl)* -1)+,+(d.dy * -1)+ ; }).style(fill,colors(0)) 

 < script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js>< / script>< svg id =chart> ;< / svg>  



这里的1万字是一个显示发生了什么,为什么它不能被称为浏览器错误:



  @keyframes dash {from {stroke-dashoffset:-10%; }到{stroke-dashoffset:90%; }} @  -  webkit-keyframes dash {from {stroke-dashoffset:-10%; }到{stroke-dashoffset:90%; }} #dashed {animation:dash 12s linear infinite; }  

 < svg height =200width = 200id =chartviewBox =290 260 100 100>< path id =brokenstyle =fill:none; stroke:rgb(31,119,180); stroke-width:50; stroke -dasharray:3,3; d =M300,300c10,0 30,40 40,40>< / path>< path style =fill:none; stroke:black; d =M300,300c10,0 30,40 40,40>< / path>< / svg>  

/ p>

I try to draw thick Bezier lines (for a custom Sankey diagram). I use SVG Paths, with Bezier curves in the form of C x1 y1, x2 y2, x y. I use stroke rather than fill, so that they have constant width (and can represent flows).

It works very well if the lines are thin or if the vertical difference is relatively low. However, if they are very thick, I get some nasty artifacts (looking like horns) - see the bottom right curve from the picture below:

Source: http://jsfiddle.net/stared/83jr5fub/

Is there a way to avoid artifacts, i.e.:

  • ensure there is nothing on the left of x1 or right of x,
  • actual widths on the left and right match stroke-width?

解决方案

I think that he best solution in your case (with the given path), is to make your path closed, and use its fill property.

To do this, you'll have to make a lineTo(0, strokeWidth) at the end of your BezierCurveTo, and then to redraw the bezierCurve in the other way :

var svg = d3.select("#chart");

var data = [
	{t: 5, dy: 10},
	{t: 5, dy: 20},
	{t: 5, dy: 40},
	{t: 20, dy: 10},
	{t: 20, dy: 20},
	{t: 20, dy: 40},
	{t: 50, dy: 10},
	{t: 50, dy: 20},
	{t: 50, dy: 40},
];

var ctrl = 10;
var dx = 40;
var spacing = 100;
var colors = d3.scale.category10();

svg
  .attr("width", 4 * spacing)
  .attr("height", 4 * spacing);

svg.selectAll("path")
  .data(data)
  .enter()
  	.append("path")
    .attr("d", function (d, i) {
      var x1 = spacing + spacing * (i % 3);
      var y1 = spacing + spacing * Math.floor(i / 3);
      return "M" + x1 + "," + y1 +
      "c" + ctrl + "," + 0 +
      " " + (dx - ctrl) + "," + d.dy +
      " " + dx + "," + d.dy +
      // move down for the wanted width
      "l" + (0) + "," + (d.t) +
      // negate all values
      "c" + (ctrl * -1) + "," + 0 +
      " " + ((dx - ctrl) * -1) + "," + (d.dy * -1) +
      " " + (dx * -1) + "," + (d.dy * -1);
  })
  .style("fill", colors(0))

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id="chart"></svg>

And since an animation worth more than 10 thousand words here is one showing what was happening and why it can't be called a browser bug :

@keyframes dash {
  from {
     stroke-dashoffset: -10%;
  }
   to {
     stroke-dashoffset: 90%;
  }
 }
@-webkit-keyframes dash {
  from {
     stroke-dashoffset: -10%;
  }
   to {
     stroke-dashoffset: 90%;
  }
 }
#dashed{
  animation : dash 12s linear infinite;
  }

<svg height="200" width="200" id="chart" viewBox="290 260 100 100">
<path id="dashed" style="fill: none; stroke: rgb(31, 119, 180); stroke-width: 50; stroke-dasharray: 3, 3;" d="M300,300c10,0 30,40 40,40"></path>
<path style="fill: none; stroke: black;" d="M300,300c10,0 30,40 40,40">
</path></svg>

这篇关于不带伪影的SVG中的粗Bezier曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆