使SVG路径像平滑线一样,而不是粗糙的样子

11

在我的项目中,我从路径创建线条。 由于我使用了较大的笔画宽度,因此它非常粗糙:

输入图像描述

我已经做了一些搜索,但我找到的唯一解决方法是stroke-linejoin: round;,如下图所示:

输入图像描述

虽然这样要好得多,但我还不满意。

有没有办法获得真正平滑的线条? 或者说有更圆润的linejoin方式吗?

3个回答

8
一个有趣的方向是利用d3.svg.line从您的geoJSON要素的坐标生成路径,此时您将能够使用D3的插值方法。
参见E. Meeks的Geodata to d3.svg.line interpolation以及D3js-Topojson : how to move from pixelized to Bézier curves?Crispy edges with topojson?
编辑:这里有一个线平滑的最小独立案例研究,您可以通过它的相关gist git存储库进行fork。结合y坐标的插值,d3.svg.line的想法来实现线平滑,这个想法来自于E.Meeks。E. Meeks在这里解释了他的方法。
编辑2 & 解决方案:我突然想起了topojson是如何动态转换为geojson的。通过以下操作,您可以使用topojson文件并最终获得贝塞尔曲线,选择外推方式。以下操作将奏效:
d3.json("./world-110m.json", function(data){
    console.log(data)
    var geojson = topojson.feature(data, data.objects.countries);
    var newJson = newgeoson(geojson);
    console.log(JSON.stringify(newJson))

    d3.select("body").append("svg").attr("id","world")
      .selectAll("path")
        .data(newJson)
      .enter()
        .append("path")
        .style("stroke-width", 1)
        .style("stroke", "black")
        .style("fill-opacity", .5)
        .attr("d", d3.svg.line()
          .x(function(d){ return d[0] })
          .y(function(d){ return d[1] }).interpolate("cardinal"))
        .style("fill", "#7fc97f");
})

Live demo: 最小化的d3js线条平滑,topojson版本

enter image description here


2
我最终选择使用更加微妙的topojson简化方式,通过命令行工具来实现。但是@Emeeks的方法也吸引了我的注意。 - Hugolpz
2
但是简化意味着我会丢失数据。但是我希望它打印出来的详细程度与我绘制的一样 =) 所以这对我来说不是解决方案。就像我说的,当有工作或问题时再回来 =) 谢谢。 - kwoxer
2
我只是一个指针。你必须阅读E.Meeks的解释,所有的感谢应该归给他。D3js也可以在运行时将topojson转换为geojson。我不知道在哪个级别上,但重点是,这应该是可能的,但确实需要在Stackoverflow上提出一些进一步的问题,并挖掘topojson数据=>线平滑的答案。我快速(过去的一小时)制作了E.Meek代码的最小独立版本,这个新版本将更容易被黑客攻击。请查看我的回答。 - Hugolpz
2
@kwoxer:刚刚添加了一个topojson解决方案,值得一试。加油。 - Hugolpz
2
看看我的代码块,fork一下,加上console.log(JSON.stringify(d))并检查数据。通用解决方案已完成,你的代码可以轻松实现。 - Hugolpz
显示剩余11条评论

3
如果您对于“stroke-linejoin: round”不满意,可以尝试创建路径轮廓来解决问题。但是,也许通过使用贝塞尔曲线平滑路径更容易一些。

立方贝塞尔曲线并不是一个真正的选择,出于某些原因我需要采取这种路径。另一个例子看起来相当困难但有趣 =/ 但是我不知道如何开始,使用CSS解决方案会更好。 - kwoxer

2
如果您对其外观不满意,那么问题似乎是您的河流定义了太少的点。任何您用于平滑路径的技术,例如曲线拟合算法,都可能导致您现在拥有的河流表示甚至更不准确。

实际上,这是topojson格式,原始河流在河流线上有很多不同的点。因此,可能是topojson在某种程度上减少了点以获得较小的文件。 - kwoxer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接