简体   繁体   English

用画布绘制流畅的线条

[英]Drawing smooth lines with canvas

So far none of the threads here on smooth lines are correct. 到目前为止,平滑线上的线程都没有正确。

how to draw smooth curve through N points using javascript HTML5 canvas? 如何使用javascript HTML5画布通过N个点绘制平滑曲线?

Smooth user drawn lines in canvas 在画布中平滑用户绘制的线条

Both result in jagged lines. 两者都会产生锯齿状的线条。 By smooth I mean using the x,y points as control points to make the line smooth. 通过平滑我的意思是使用x,y点作为控制点以使线条平滑。 The line does NOT need to go through the points. 该线不需要经过这些点。 It simply has to draw a smooth line given n points. 它只需要给出n个点的平滑线。

Basically I'm recording each line segment, then when the user mouses up, it wil smooth the line. 基本上我正在记录每个线段,然后当用户将鼠标移动时,它会使线条平滑。

I've tried my own method using bezierCurveTo but that only smooths every other point, and then the connecting points are harsh still. 我已经使用bezierCurveTo尝试了自己的方法但是只能平滑每个其他点,然后连接点仍然很苛刻。 The internet seems to think what I'm looking for is called B-Spline curves. 互联网似乎认为我正在寻找的是B-Spline曲线。 I tried applying a linear algebra matrix to the problem, but I failed at that lol. 我尝试将线性代数矩阵应用于问题,但我失败了。

Here is the best curve I can get, (image). 这是我能得到的最佳曲线,(图片)。 The line in red is the "smoothed" line, as you can see it smooths every other point, but not continuous. 红线是“平滑”线,你可以看到它平滑每一点,但不是连续的。 This is using the code from 这是使用来自的代码

how to draw smooth curve through N points using javascript HTML5 canvas? 如何使用javascript HTML5画布通过N个点绘制平滑曲线?

My code does the same thing 我的代码做了同样的事情

http://www.square-bracket.com/images/smoothlines.png http://www.square-bracket.com/images/smoothlines.png

Thanks for your help! 谢谢你的帮助!

You need to keep the same tangent in the points bellowing in the line. 您需要在该行中的点中保持相同的切线。 Check http://jsfiddle.net/FHKuf/4/ . 检查http://jsfiddle.net/FHKuf/4/

Edit: 编辑:

Sorry, just noticed your comment today. 对不起,今天就注意到了你的意见。 Just happened to be testing something related and remembered your question. 恰巧正在测试相关的东西并记住你的问题。 It happens that in the past I did wrote some code to interpolate some lines. 碰巧在过去我写了一些代码来插入一些行。 It is called Catmull-Rom (just a ref. that I googleed) it passes by the middle control points. 它被称为Catmull-Rom (只是我认为的一个参考)它通过中间控制点。 I did changed the code to my test and thought that you may have some use to it. 我确实将代码更改为我的测试,并认为您可能对它有一些用处。 See at http://jsfiddle.net/FHKuf/6/ . http://jsfiddle.net/FHKuf/6/

I was exploring all techniques but did not get any proper solution for smooth free drawing on canvas. 我正在探索所有技术,但没有得到任何适当的解决方案,以便在画布上顺利自由绘画。 Then I simply used quadraticCurveTo with different logic without using original mouse points. 然后我简单地使用了quadraticCurveTo和不同的逻辑,而没有使用原始鼠标点。

I first calculated control point(mid-point) and replace old mouse move point with the control point. 我首先计算控制点(中点)并用控制点替换旧的鼠标移动点。 I did this 2 times and finally applied quadraticCurveTo to the final array and I got super smooth drawing. 我做了2次,最后将quadraticCurveTo应用到最终阵列,我得到了超级平滑的绘图。

It was amazing. 这是惊人的。 I did it without using this heavy paper.js and other smoothing libraries. 我没有使用这个沉重的paper.js和其他平滑库就做到了。

Here is my code: 这是我的代码:

currentCanvas.beginPath();
        currentCanvas.lineCap = 'round';
        currentCanvas.strokeStyle = "black";
        currentCanvas.lineWidth = "2";
        currentCanvas.moveTo(queue[0].x, queue[0].y);

        //queue is an array of original points which were stored while onmousemove event callback

        var tempQueue1 = [queue[0]];
        for (var i = 1; i < queue.length - 1;  i = i+1) {
            //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) &&  (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){
                var c = (queue[i].x + queue[i + 1].x) / 2;
                var d = (queue[i].y + queue[i + 1].y) / 2;
                //tempQueue.push(queue[i]);
                tempQueue1.push({x:c, y:d});
                //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d);
            //}
        }

        var tempQueue2 = [tempQueue1[0]];
        for (var i = 1; i < tempQueue1.length - 1;  i = i+1) {
            //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) &&  (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){
                var c = (tempQueue1[i].x + tempQueue1[i + 1].x) / 2;
                var d = (tempQueue1[i].y + tempQueue1[i + 1].y) / 2;
                //tempQueue.push(queue[i]);
                tempQueue2.push({x:c, y:d});
                //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d);
            //}
        }

        var tempQueue = [tempQueue2[0]];
        for (var i = 1; i < tempQueue2.length - 1;  i = i+1) {
            //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) &&  (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){
                var c = (tempQueue2[i].x + tempQueue2[i + 1].x) / 2;
                var d = (tempQueue2[i].y + tempQueue2[i + 1].y) / 2;
                //tempQueue.push(queue[i]);
                tempQueue.push({x:c, y:d});
                //currentCanvas.quadraticCurveTo(queue[i].x, queue[i].y, c, d);
            //}
        }

        for (var i = 1; i < tempQueue.length - 2;  i = i+1) {
            //if((Math.abs(queue[i].x - queue[i-1].x) >3 || Math.abs(queue[i].x - queue[i-1].x)<1) &&  (Math.abs(queue[i].y - queue[i-1].y) >3 || Math.abs(queue[i].y - queue[i-1].y)<1)){
                var c = (tempQueue[i].x + tempQueue[i + 1].x) / 2;
                var d = (tempQueue[i].y + tempQueue[i + 1].y) / 2;
                currentCanvas.quadraticCurveTo(tempQueue[i].x, tempQueue[i].y, c, d);
            //}
        }

        // For the last 2 points
        currentCanvas.quadraticCurveTo(
        tempQueue[i].x,
        tempQueue[i].y,
        tempQueue[i+1].x,
        tempQueue[i+1].y
        );
        currentCanvas.stroke();
        queue = [];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM