Drawing smooth lines with canvas

前端 未结 2 1384
遥遥无期
遥遥无期 2020-12-09 13:55

So far none of the threads here on smooth lines are correct.

how to draw smooth curve through N points using javascript HTML5 canvas?

Smooth user drawn lines

相关标签:
2条回答
  • 2020-12-09 14:26

    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.

    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.

    It was amazing. I did it without using this heavy paper.js and other smoothing libraries.

    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 = [];
    
    0 讨论(0)
  • 2020-12-09 14:38

    You need to keep the same tangent in the points bellowing in the line. Check 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. 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/.

    0 讨论(0)
提交回复
热议问题