Germ generator for Code Golph puzzle

(by Jacque Goupil, released to public domain)

HTML

<div class="container" style="height: calc(100% - 120px);">
    <textarea id="input" spellcheck="false">......
.O..O.
.OO.O.
......</textarea>
    <pre id="output"></pre>
</div>
<div class="container">
    <input type="text" id="widthInput" value="6" size="3" />
    <input type="text" id="heightInput" value="4" size="3" />
    <button id="generateBtn">Generate blank map</button><br />
    <input type="text" id="cellInput" value="O" size="3" maxlength="1" />
    <input type="text" id="voidInput" value="." size="3" maxlength="1" />
    <button id="moveBtn">Move cells</button>
    <p>Any character that is not a germ will be considered an empty cell. Don't use whitespace in the input as it will be trimmed.</p>
</div>

CSS

html, body {
    width: 100%;
    height: 100%;
}

.container {
    padding: 10px;
    width: calc(100% - 20px);
}

#input, #output {
    float: left;
    width: calc(50% - 12px);
    height: calc(100% - 12px);
    margin: 0;
    padding: 5px;
    border: 1px solid black;
    outline: 0;
    resize: none;
    font-family: DejaVu, monospace;
    font-size: 12pt;
}

JavaScript

input = document.getElementById('input');
output = document.getElementById('output');
widthInput = document.getElementById('widthInput');
heightInput = document.getElementById('heightInput');
generateBtn = document.getElementById('generateBtn');
cellInput = document.getElementById('cellInput');
voidInput = document.getElementById('voidInput');
moveBtn = document.getElementById('moveBtn');

function makeArray(w, h, val) {
    var arr = [];
    for(var y=0; y<h; ++y) {
        arr[y] = (Array(w+1).join(val)).split('');
    }
    return arr;
}

function joinArray(arr) {
    var newarr = [];
	for(var i=0; i<arr.length; ++i) {
		newarr[i] = arr[i].join('');
    }
    return newarr.join('\n');
}

if (!String.prototype.trim) {
  String.prototype.trim = function () {
    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  };
}

movements = [
    {x:0, y:1},
    {x:0, y:-1},
    {x:1, y:0},
    {x:-1, y:0},
    {x:0, y:0}
]

function randomMovement() {
    return movements[Math.floor(Math.random() * movements.length)];
}

function moveCells(beforestr, cellChar, voidChar) {
    
    var before = beforestr.split('\n');
    var after = makeArray(before[0].length, before.length, voidChar);
    
    for(var y=0; y<before.length; ++y) {
        for(var x=0; x<before[y].length; ++x) {
            if(before[y][x] === cellChar) {
                do {
                    var movement = randomMovement();
                    var dest = {x: x+movement.x, y: y+movement.y};
                } while (after[dest.y] === undefined || after[dest.y][dest.x] === undefined || after[dest.y][dest.x] === cellChar);
                after[dest.y][dest.x] = cellChar;
            }
        }
    }
    
    return joinArray(after);
}

moveBtn.addEventListener('click', function(e) {
    var cellChar = cellInput.value[0] || 'O';
    var voidChar = voidInput.value[0] || '.';
    output.textContent = moveCells(input.value.trim(), cellChar, voidChar);
});

generateBtn.addEventListener('click',...