Smooth canvas curves

by Umar

HTML

<div>
    <canvas id="unsmoothed" />
</div>
<div>
    <canvas id="expsmoothed" />
</div>
<div>
    <canvas id="smoothed" />
</div>

CSS

canvas {
    border: 1px solid black;
}

JavaScript

var unsmoothedCanvas = document.getElementById("unsmoothed");
var smoothedCanvas = document.getElementById("smoothed");
var expsmoothedCanvas = document.getElementById("expsmoothed");
var canvases = $([unsmoothedCanvas, smoothedCanvas, expsmoothedCanvas]);

var smoothLength = 4;

var minDist = 8;

canvases.mousemove(function (e) {
    if (e.which == 1) {
        var p = getPos(e, this);
        canvases.each(function () {
            clear.call(this);
            this.points.push(p);
            if (this.points.length > smoothLength) {
                this.smooth(this.points)
                drawLine(this, this.points);
            }
        });

    }
});

$("body").mousedown(function () {
    canvases.each(function () {
        clear.call(this);
        this.points = [];
    });
});



function drawLine(canvas, points) {
    var ctx = canvas.getContext("2d");
    var p0 = points[0];
    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.moveTo(p0.x, p0.y);
    for (var i = 1; i < points.length; ++i) {
        var p = points[i];
        ctx.lineTo(p.x, p.y);
    }
    ctx.stroke();
}

function clear() {
    var ctx = this.getContext("2d");
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, this.width, this.height);
}

function getPos(e, canvas) {
    return {
        x: e.pageX - canvas.offsetLeft,
        y: e.pageY - canvas.offsetTop
    };
}

function dist(a, b) {
    var x = a.x - b.x;
    var y = a.y - b.y;
    return x * x + y * y;
}

unsmoothedCanvas.smooth = function (ps) {};
expsmoothedCanvas.smooth = function (ps) {
    var a = 0.2;
    var p = ps[ps.length - 1];
    var p1 = ps[ps.length - 2];
    ps[ps.length - 1] = {
        x: p.x * a + p1.x * (1 - a),
        y: p.y * a + p1.y * (1 - a)
    };
};
smoothedCanvas.smooth = function (ps) {
    for (var i = 0; i < smoothLength; ++i) {
        var j = ps.length - i - 2;
        var p0 = ps[j];
        var p1 = ps[j + 1];
        var a = 0.2;
        var p = {
            x: p0.x * (1 - a) + p1.x *...