Well it’s been a while. I stopped posting here over two years ago because I founded a CNC machine company called Other Machine Co. and got sucked into a vortex of long hours and other large life changes. Updating the blog became a chore, Wordpress would frequently collect spam and malware and cleaning it up took time and energy away from writing.

Folks who are more up-to-date on the latest web technologies suggested I check out Jekyll and Github Pages as an alternate. Transitioning from Wordpress was a pain, as everything had to be exported, cleaned up, and restyled for my new Jekyll templates.

Now it’s done, and I can get back to writing posts nobody reads :grin:

I had some fun writing a custom generative background for the pages. It’s a theme I first started using on the graphic styling for my motorcycles. A randomly generated set of bars distributed across the page.

My first attempt used a uniform random distribution with offsets and rotations cumulating in the transformation matrix for the canvas. This would occasionally produce a nice distribution of bars, but it was fairly hit or miss.

After noodling around for a bit, I ended up using a Bezier Curve to create a path along which to randomly distribute the lines. This produced a more even and predictable distribution. Here’s the code:

// Copyright 2018 (Mike Estee)
// MIT License.

var barColor = "#eee";
var bgColor = "#222";

function randrange(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// from https://en.wikipedia.org/wiki/B%C3%A9zier_curve
//  P = (1−t)^3*P1 + 3(1−t)^2*t*P2 +3(1−t)*t^2*P3 + t^3*P4
//  returns {x,y} for t[0..1] as a point along the path.
//  p1/p4 are the end points, and p2/p3 are the control points.
function bezier(t, p1, p2, p3, p4) {
    var x = Math.pow(1-t,3)*p1.x
            + 3*Math.pow(1-t,2)*t*p2.x
            + 3*(1-t)*Math.pow(t,2)*p3.x
            + Math.pow(t,3)*p4.x;

    var y = Math.pow(1-t,3)*p1.y
            + 3*Math.pow(1-t,2)*t*p2.y
            + 3*(1-t)*Math.pow(t,2)*p3.y
            + Math.pow(t,3)*p4.y;

    return {x: x, y: y}
}

// our drawing function. It uses 2x upscaling so we have sharp rendering on HiDPI monitors
function draw() {
    var canvas = document.getElementById("example");

    // upscale 2x
    canvas.width = 1200
    canvas.height= 1000
    canvas.style.width = (canvas.width/2) + "px";
    canvas.style.height = (canvas.height/2) + "px";

    // begin drawing
    var ctx = canvas.getContext("2d");

    // bezier parameters
    var h = canvas.height/2;
    var w = canvas.width/2;
    var p1 = {x:0,   y:0};
    var p2 = {x:randrange(w*0.25,w*0.75), y:0};
    var p3 = {x:randrange(w*0.25,w*0.75), y:h};
    var p4 = {x:w,   y:h};

    // line parameters
    var scatter = 100;
    var thick = 20;     // line thickness
    var count = 100;    // line count
    
    // clear background
    ctx.fillStyle = bgColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // draw some black lines randomly along a curve
    ctx.fillStyle = barColor;
    for( var n=0; n<count; n++) {

        ctx.resetTransform();
        ctx.scale(2,2);
        
        var pt = bezier(n/count, p1, p2, p3, p4);

        ctx.translate(
            pt.x + randrange(-scatter/2,scatter/2),
            pt.y + randrange(-scatter/2,scatter/2) );
        ctx.rotate(Math.random() * 2 * Math.PI);

        ctx.fillRect(0, 0, thick, randrange(thick, thick*10));
    }
}

draw();