【问题标题】:Making a SVG path like a smooth line instead of being ragged使 SVG 路径像一条平滑线而不是参差不齐
【发布时间】:2015-04-22 16:24:36
【问题描述】:

在我的项目中,我从 pathes 创建了河流。而且由于我的 大笔画宽度 它非常衣衫褴褛

我已经四处搜寻了。但我发现的唯一东西是stroke-linejoin: round;。正如你在这里看到的:

好多了,但我还是不满意。

有什么办法可以得到一条真正平滑的线。或者假设也有一个均匀的“rounder” linejoin

【问题讨论】:

    标签: svg path smoothing topojson


    【解决方案1】:

    一个有趣的方向是利用 d3.svg.line 从 geoJSON 特征的坐标生成路径,此时您将能够使用 D3 的插值方法。

    参见 E. Meeks 的 D3js-Topojson : how to move from pixelized to Bézier curves?Geodata to d3.svg.line interpolation,以及 Crispy edges with topojson?


    编辑: 有一个minimal stand alone case study for line smoothing,您可以通过其关联的 gist 的 git 存储库 fork。 d3.svg.line 的想法以及用于线条平滑的y 坐标的插值来自 E.Meeks。 E. Meeks 解释了他的方法here


    Edit2 & 解决方案: Í 突然想起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");
    })
    

    现场演示:Minimal d3js line smoothing, topojson version

    【讨论】:

    • 我自己最终选择通过 topojson 命令行工具使用更微妙的 topojson 简化。但是这种@Emeeks 方式也吸引了我的眼球。
    • 但是简化意味着我丢失了数据。但我希望它像我画的那样详细打印=)所以这对我来说没有解决方案。正如我所说的在工作或遇到问题时回来=)谢谢。
    • 我在这里只是一个指针。你必须阅读 E.Meeks 的解释,所有的感谢都应该归功于他。 D3js 还可以即时将 topojson 转换为 geojson。不知道是什么水平,呵呵。重点是,这应该是可能的,但确实需要在 Stackoverflow 上提出一些进一步的问题,并挖掘 topojson 数据 => 线平滑答案。我很快(过去一个小时)制作了 E.Meek 代码的最小独立版本,这个新版本更容易破解。看我的回答。
    • @kwoxer:刚刚添加了一个可能值得一试的 topojson 解决方案。欢呼。
    • 查看我的块代码,fork,放一些console.log(JSON.stringify(d)) 并检查数据。通用解决方案已完成,您的代码触手可及。
    【解决方案2】:

    如果您对stroke-linejoin:round不满意 你可以考虑创建path outline

    但如果您尝试使用cubic beziers 来平滑您的路径,可能会更容易。

    【讨论】:

    • 三次贝塞尔曲线并不是一个真正的选择,出于某些原因我需要走这条路。另一个例子看起来很困难,但很有趣=/但不知道如何开始,一个 css 解决方案会更好。
    【解决方案3】:

    如果您对它的外观不满意,那么在我看来问题在于您的河流定义的点太少。

    您用来平滑路径的任何技术(例如曲线拟合算法)都可能导致您的河流表示比您现在拥有的更不准确。

    【讨论】:

    • 其实是topojson,原来的河道在河道上有很多不同的点。所以它可能是topojson,它以某种方式减少点以获得更小的文件。
    猜你喜欢
    • 1970-01-01
    • 2014-10-20
    • 2014-06-09
    • 2013-08-12
    • 2012-10-06
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多