Javascript SVG平滑手绘

Javascript SVG平滑手绘,javascript,svg,Javascript,Svg,我使用原生JS实现了路径的徒手绘制。但正如预期的那样,路径边缘几乎没有攻击性且不平滑。所以我可以选择使用SimpleJS来简化点,然后重新绘制路径。但就像,我不是在画画后进行平滑处理,而是在画画时尝试找到简化的边 这是我的密码: var x0, y0; var dragstart = function(event) { var that = this; var pos = coordinates(event); x0 = pos.

我使用原生JS实现了路径的徒手绘制。但正如预期的那样,路径边缘几乎没有攻击性且不平滑。所以我可以选择使用SimpleJS来简化点,然后重新绘制路径。但就像,我不是在画画后进行平滑处理,而是在画画时尝试找到简化的边

这是我的密码:

    var x0, y0;

    var dragstart = function(event) {
        var that = this;
        var pos = coordinates(event);
        x0 = pos.x;
        y0 = pos.y;
        that.points = [];
    };

    var dragging = function(event) {
        var that = this;
        var xy = coordinates(event);
        var points = that.points;
        var x1 = xy.x, y1 = xy.y, dx = x1 - x0, dy = y1 - y0;
        if (dx * dx + dy * dy > 100) {
            xy = {
                x: x0 = x1, 
                y: y0 = y1
            };
        } else {
            xy = {
                x: x1, 
                y: y1
            };
        }
        points.push(xy);
    };
但它并不像上面添加的链接那样工作。仍然是边缘不好。请帮忙


在github上已经有了一些实现,例如


你不需要改变你的输入,只需要改变画图功能,点之间的线是平滑的。因此,在简化过程中,点不会有丝毫滑动。

下面的代码片段通过计算最后鼠标位置的平均值,使曲线更加平滑。平滑级别取决于保留这些值的缓冲区的大小。您可以尝试使用下拉列表中提供的不同缓冲区大小。12点缓冲区的行为与您在问题中提到的类似

可以使用更复杂的技术从缓冲区中存储的位置(加权平均、线性回归、三次样条平滑等)获得平滑点,但这种简单的平均方法可能足够精确,满足您的需要

var strokeWidth=2;
变量缓冲区大小;
var svgElement=document.getElementById(“svgElement”);
var rect=svgElement.getBoundingClientRect();
var path=null;
var-strPath;
变量缓冲区=[];//包含鼠标光标的最后位置
svgElement.addEventListener(“鼠标向下”,函数(e){
bufferSize=document.getElementById(“CMBufferSize”).value;
path=document.createElements('http://www.w3.org/2000/svg","路径",;
setAttribute(“填充”、“无”);
setAttribute(“笔划”,“#000”);
setAttribute(“笔划宽度”,笔划宽度);
缓冲区=[];
var pt=getMousePosition(e);
附属物缓冲液(pt);
strPath=“M”+pt.x+“”+pt.y;
setAttribute(“d”,strPath);
svgElement.appendChild(路径);
});
svgElement.addEventListener(“mousemove”,函数(e){
如果(路径){
appendToBuffer(getMousePosition(e));
updateSvgPath();
}
});
svgElement.addEventListener(“mouseup”,函数(){
如果(路径){
path=null;
}
});
var getMousePosition=函数(e){
返回{
x:e.pageX-右左,
y:e.pageY-rect.top
}
};
var appendToBuffer=函数(pt){
缓冲推送(pt);
while(buffer.length>bufferSize){
buffer.shift();
}
};
//从缓冲区中的偏移量开始计算平均点
var getAveragePoint=函数(偏移量){
var len=buffer.length;
if(len%2==1 | | len>=bufferSize){
var totalX=0;
var totalY=0;
var-pt,i;
var计数=0;
对于(i=偏移;i
html,正文
{
填充:0px;
边际:0px;
}
#svgElement
{
边框:1px实心;
利润上限:4倍;
左边距:4倍;
游标:默认值;
}
#分割平滑因子
{
位置:绝对位置;
左:14px;
顶部:12px;
}

缓冲区大小:
1-无平滑
4-尖锐曲线
8-平滑曲线
12-非常平滑的曲线
16-超光滑曲线
20-超光滑曲线

不清楚你的问题是什么-考虑添加更多信息,屏幕截图,更好地描述你的预期结果和你的实际结果,EtChelp我们来帮助你。请创建一个链接,以便我们能更清楚地看到您的问题所在。@PaulLeBeau在上面添加了截图。创建fiddle有点困难,因为我有这么多依赖代码。为什么不使用Mike Bostock在参考链接()中给出的代码呢?我没有使用d3 js。我尝试过使用逻辑,但它不起作用这是一个如此惊人的答案!等着分配赏金,但我不能在50分钟内完成minutes@ConnorsFan非常酷的例子。我使用您的代码在Svelte3中创建了一个svg行编辑器:如何实现上面提到的橡皮擦功能?