Implementing smooth sketching and drawing on the element

前端 未结 7 519
粉色の甜心
粉色の甜心 2021-01-29 20:20

I am trying to create a drawing area with canvas. I am having trouble with making the lines look smooth when drawing curves and I also have changing line thickness in my algorit

7条回答
  •  庸人自扰
    2021-01-29 20:50

    Suggest the rendering be done with a chain of bezier curves which surround the curve which is thus filled. (ie end with ctx.fill) Still lots of work to do but hope this helps.

    Adapted a nice demo app for bezier curves

    added it to a fork of your fiddle http://jsfiddle.net/d3zFU/1/

    Code is

    /*
     * Canvas curves example
     *
     * By Craig Buckler,        http://twitter.com/craigbuckler
     * of OptimalWorks.net        http://optimalworks.net/
     * for SitePoint.com        http://sitepoint.com/
     *
     * Refer to:
     * http://blogs.sitepoint.com/html5-canvas-draw-quadratic-curves/
     * http://blogs.sitepoint.com/html5-canvas-draw-bezier-curves/
     *
     * This code can be used without restriction.
     */
    

    (function() {

    var canvas, ctx, code, point, style, drag = null, dPoint;
    
    // define initial points
    function Init(quadratic) {
    
        point = {
            p1: { x:100, y:250 },
            p2: { x:400, y:250 }
        };
    
        if (quadratic) {
            point.cp1 = { x: 250, y: 100 };
        }
        else {
            point.cp1 = { x: 150, y: 100 };
            point.cp2 = { x: 350, y: 100 };
        }
    
        // default styles
        style = {
            curve:    { width: 6, color: "#333" },
            cpline:    { width: 1, color: "#C00" },
            point: { radius: 10, width: 2, color: "#900", fill: "rgba(200,200,200,0.5)", arc1: 0, arc2: 2 * Math.PI }
        }
    
        // line style defaults
        ctx.lineCap = "round";
        ctx.lineJoin = "round";
    
        // event handlers
        canvas.onmousedown = DragStart;
        canvas.onmousemove = Dragging;
        canvas.onmouseup = canvas.onmouseout = DragEnd;
    
        DrawCanvas();
    }
    
    
    // draw canvas
    function DrawCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    
        // control lines
        ctx.lineWidth = style.cpline.width;
        ctx.strokeStyle = style.cpline.color;
        ctx.fillStyle = style.cpline.color;
        ctx.beginPath();
        ctx.moveTo(point.p1.x, point.p1.y);
        ctx.lineTo(point.cp1.x, point.cp1.y);
        if (point.cp2) {
            ctx.moveTo(point.p2.x, point.p2.y);
            ctx.lineTo(point.cp2.x, point.cp2.y);
        }
        else {
            ctx.lineTo(point.p2.x, point.p2.y);
        }
        ctx.stroke();
    
        // curve
    ctx.lineWidth = 1 ; //style.curve.width;
        ctx.strokeStyle = style.curve.color;
        ctx.beginPath();
        ctx.moveTo(point.p1.x, point.p1.y);
        if (point.cp2) {
            ctx.bezierCurveTo(point.cp1.x, point.cp1.y, point.cp2.x, point.cp2.y, point.p2.x, point.p2.y);
            ctx.bezierCurveTo(point.cp2.x, point.cp2.y+12, point.cp1.x, point.cp1.y+12, point.p1.x, point.p1.y);
    
        }
        else {
            ctx.quadraticCurveTo(point.cp1.x, point.cp1.y, point.p2.x, point.p2.y);
        }
    //ctx.stroke();
    ctx.fill();
    
        // control points
        for (var p in point) {
            ctx.lineWidth = style.point.width;
            ctx.strokeStyle = style.point.color;
            ctx.fillStyle = style.point.fill;
            ctx.beginPath();
            ctx.arc(point[p].x, point[p].y, style.point.radius, style.point.arc1, style.point.arc2, true);
            ctx.fill();
            ctx.stroke();
        }
    
        ShowCode();
    }
    
    
    // show canvas code
    function ShowCode() {
        if (code) {
            code.firstChild.nodeValue =
                "canvas = document.getElementById(\"canvas\");\n"+
                "ctx = canvas.getContext(\"2d\")\n"+
                "ctx.lineWidth = " + style.curve.width +
                ";\nctx.strokeStyle = \"" + style.curve.color +
                "\";\nctx.beginPath();\n" +
                "ctx.moveTo(" + point.p1.x + ", " + point.p1.y +");\n" +
                (point.cp2 ?
                    "ctx.bezierCurveTo("+point.cp1.x+", "+point.cp1.y+", "+point.cp2.x+", "+point.cp2.y+", "+point.p2.x+", "+point.p2.y+");" :
                    "ctx.quadraticCurveTo("+point.cp1.x+", "+point.cp1.y+", "+point.p2.x+", "+point.p2.y+");"
                ) +
                "\nctx.stroke();"
            ;
        }
    }
    
    
    // start dragging
    function DragStart(e) {
        e = MousePos(e);
        var dx, dy;
        for (var p in point) {
            dx = point[p].x - e.x;
            dy = point[p].y - e.y;
            if ((dx * dx) + (dy * dy) < style.point.radius * style.point.radius) {
                drag = p;
                dPoint = e;
                canvas.style.cursor = "move";
                return;
            }
        }
    }
    
    
    // dragging
    function Dragging(e) {
        if (drag) {
            e = MousePos(e);
            point[drag].x += e.x - dPoint.x;
            point[drag].y += e.y - dPoint.y;
            dPoint = e;
            DrawCanvas();
        }
    }
    
    
    // end dragging
    function DragEnd(e) {
        drag = null;
        canvas.style.cursor = "default";
        DrawCanvas();
    }
    
    
    // event parser
    function MousePos(event) {
        event = (event ? event : window.event);
        return {
            x: event.pageX - canvas.offsetLeft,
            y: event.pageY - canvas.offsetTop
        }
    }
    
    
    // start
    canvas = document.getElementById("canvas");
    code = document.getElementById("code");
    if (canvas.getContext) {
        ctx = canvas.getContext("2d");
        Init(canvas.className == "quadratic");
    }
    

    })();

提交回复
热议问题