block by redblobgames ba198c31af7b932875daf78c9e50d922

d3 unconf block

Full Screen

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <!-- this page assembled quick & dirty style, not for maintaining -->
  <title>d3 unconf badge</title>

  <style>
      html, body { margin: 0; padding: 0; }
      body { overflow: hidden; }
  </style>
  
  <!-- d3 of course! -->
  <script src="//d3js.org/d3.v4.min.js"></script>

  <!-- random number generator, noise generator -->
  <script src="/js/prng.js"></script>
  <script src="/js/simplex-noise.js"></script>

  <script>var exports = window; /* hack */</script>

  <!-- hexagon code from //www.redblobgames.com/grids/hexagons/implementation.html -->
  <script src="//www.redblobgames.com/grids/hexagons/codegen/output/lib-functions.js"></script>

</head>


<body>
  <canvas width="1050" height="1500"/>
  <script src="d3-unconf-badge.js"></script>
</body>

d3-unconf-badge.js

var canvas = d3.select("canvas");
var ctx = canvas.node().getContext('2d');
var SEED = 123456;
var noisegens = [];

(function makeNoiseGens() {
    for (var i = 0; i < 10; i++) {
        var rng = makeRandFloat(SEED + i);
        noisegens[i] = new SimplexNoise(rng);
    }
})();


function smooth_biome_color(z, m) {
    // This function copied from another project; see http://www.redblobgames.com/maps/terrain-from-noise/#biomes
    
    var water = 0.1;
    // Reshape these because perlin noise isn't evenly distributed
    z = z * 1.3 - 0.45;
    m = m * 3.0 - 0.7;
    
    if (z < water) {
        return d3.rgb(48 + 48*z/water, 64 + 64*z/water, 127 + 64 + 64*z/water);
    }

    // Green or brown at low elevation, and make it more white-ish
    // as you go up
    z = z * z * 0.7;
    var r = 210 - 100*m, g = 215 - 70*m, b = 139 - 45*m;
    return d3.rgb(255 * z + r * (1-z),
                  255 * z + g * (1-z),
                  255 * z + b * (1-z));
}


function noise_at(x, y, u, v, spectrum, frequency) {
    var total = 0.0;
    var z = 0;
    for (var octave = 0; octave < spectrum.length; octave++, frequency *= 2) {
        z += spectrum[octave] * (noisegens[octave].noise4D(x * frequency, y * frequency, u, v)/2 + 0.5);
        total += spectrum[octave];
    }
    return 1.2 * z / total - 0.05; /* hackery */
}


function color_at_xy(x, y, phase) {
    var z = noise_at(x, y, 2 + phase, 0, [1, 1/4, 1/8], 3);
    var m = noise_at(x, y, 0, 2 + phase, [1, 1/2, 1/3], 3);
    return smooth_biome_color(z, m);
}


function makeHexGrid(size, phase) {
    this.ctx.clearRect(0, 0, 1050, 1500);
    
    var layout = Layout(layout_pointy, Point(size, size), Point(0, 0));
    for (var row = 0; row <= 1500/size; row++) {
        for (var col = 0; col <= 1050/size; col++) {
            var hex = roffset_to_cube(EVEN, OffsetCoord(col, row));
            var center = hex_to_pixel(layout, hex);
            var color = color_at_xy(center.x / 1050, center.y / 1500, phase);
            var polygon = polygon_corners(layout, hex);

            this.ctx.beginPath();
            this.ctx.fillStyle = color.toString();
            this.ctx.strokeStyle = color.toString();
            this.ctx.moveTo(polygon[5].x, polygon[5].y);
            for (var j = 0; j < polygon.length; j++) {
                this.ctx.lineTo(polygon[j].x, polygon[j].y);
            }
            this.ctx.fill();
            this.ctx.stroke();
        }
    }
}

var frame = 0;
function redraw() {
    makeHexGrid(15, frame/20);
    frame++;
}

redraw();
setInterval(redraw, 1000);