Curve Through Points

by soulwire

CSS

html, body {
    margin: 0;
}

Babel + JSX

let c = document.createElement('canvas');
let g = c.getContext('2d');

c.width = window.innerWidth;
c.height = window.innerHeight;

document.body.appendChild(c);

const generatePoints = (count = 20) => {
    let points = [];
    let width = c.width - 20;
    let step = width / (count - 1);
    let pad = (c.width - width) / 2;
    let amp = 150;
    for (let i = 0; i < count; i++) {
        points.push({
            x: pad + i * step,
            y: window.innerHeight/2 + (Math.random()-0.5) * amp
        });
    }
    return points;
}

const drawPoints = points => {
    points.forEach(point => {
        g.beginPath();
        g.arc(point.x, point.y, 3, 0, Math.PI * 2);
        g.stroke();
    });
}

const drawCurve = points => {
    g.beginPath();
    g.moveTo(points[0].x, points[0].y);
    let i = 1, n = points.length - 2;
    for (; i < n; i++) {
        let cx = (points[i].x + points[i + 1].x) / 2;
        let cy = (points[i].y + points[i + 1].y) / 2;
        g.quadraticCurveTo(points[i].x, points[i].y, cx, cy);
    }
    g.quadraticCurveTo(points[i].x, points[i].y, points[i+1].x, points[i+1].y);
    g.stroke();
};

const update = () => {
    g.fillStyle = 'rgba(255,255,255,0.75)';
    g.fillRect(0, 0, c.width, c.height);
    const points = generatePoints();
    drawPoints(points);
    drawCurve(points);
}

setInterval(update, 1000);
update();