JSFiddle - React, Tailwind, and code Playground

HTML

<div>
    <p>Original: http://atomicmonks.com/terrain/world.html</p>
    <button type="button" id="go2">Generate</button><br />
    <canvas id="map" width="512" height="512" ></canvas>
    <ul>
        <li><label for="seed">Seed: </label><input type="text" size="10" id="seed" value="42" /> <button type="button" onclick="$('#seed').val(new RNG().nextInt())">Random</button></li>
        <li><label for="autogen">New Seed on Run: </label><input type="checkbox" id="autogen" checked="checked" /></li>
        <li><label for="width">Width: </label><input type="text" size="3" class="wheelable" value="256" data-exp="7" id="width" /></li>
        <li><label for="height">Height: </label><input type="text" size="3" class="wheelable" value="256" data-exp="6" id="height" /></li>
    </ul>
    <ul id="altitude">
        <li><label>Altitude Adjustment: </label><span id="altadjust">0</span></li>
        <li>
            <button type="button" id="moveup">Move Up</button> &nbsp; 
            <button type="button" id="center">Center</button> &nbsp; 
            <button type="button" id="movedown">Move Down</button></li>
        <li><label>Render Time: </label><span id="time">0</span>ms</li>
    </ul>
    <div id="history">
    <b>Used Seeds:</b>
    </div>
</div>

JavaScript

function RNG(seed) {
    var m = 0x100000000, a = 1103515245, c = 12345, state = seed ? seed : Math.floor(Math.random() * (m-1));
    
    this.nextInt = function() {
        state = (a * state + c) % m;
        return state;
    }
        
    this.nextFloat = function() {
        return this.nextInt() / (m - 1);
    }
        
    this.nextRange = function(start, end) {
        var rangeSize = end - start;
        var randomUnder1 = this.nextInt() / m;
        return start + Math.floor(randomUnder1 * rangeSize);
    }
        
    this.choice = function(array) {
        return array[this.nextRange(0, array.length-1)];
    }
        
};

function Generate(seed, width, height) {
    
    var grid = [], 
        rg = width+1,
        minh = 255, maxh=0,
        altshift = 0;
    
    while(rg--) {
        grid.push([]);
        var sd = height+1;
        while(sd--)
            grid[grid.length-1].push({h:0});
    }
    
    var rnd = new RNG(seed);
    
    var step = width > height ? height : width;
    
    while(step>1) {
        for(var y=0;y<height;y+=step) {
            for(var x =0;x<width;x+=step) {
                    subdivide(x,y,x+step,y+step);
            }
        }
        step = Math.round(step*0.5);
    }
    
    var scale = 255/(maxh-minh);
    
    function getheight(z0, z1, d) {
        var fc = d*rnd.nextFloat()-d*0.5, 
            r = (z0+z1)*0.5 + fc;
        if(minh>r) minh=r;
        if(maxh<r) maxh=r;
        return r;
    }
    
    function subdivide(x0, y0, x1, y1) {
        var xn = Math.round((x0+x1)*0.5), yn = Math.round((y0+y1)*0.5);
        
        grid[xn][y0].h = getheight(grid[x0][y0].h, grid[x1][y0].h, x1-x0);
        grid[x0][yn].h = getheight(grid[x0][y0].h, grid[x0][y1].h, y1-y0);
        
        grid[x1][yn].h = getheight(grid[x1][y0].h, grid[x1][y1].h, y1-y0);
        grid[xn][y1].h = getheight(grid[x0][y1].h, grid[x1][y1].h, x1-x0);
        
        grid[xn][yn].h = getheight(grid[x0][yn].h, grid[x1][yn].h, x1-x0);
 ...