JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

Map designer tool. Click tiles to change their terrain or furnishing layers. Click Regenerate to start afresh, or Export to save the JS code.<br>
Columns: <input type='number' class='size_y' min='10' max='50' value='20'> Rows: <input type='number' class='size_x' min='10' max='50' value='20'> <button class='map_regenerate'>Regenerate</button><br>
<div class='map_holder'></div><br>
X: <span class='selected_tile_x'></span> 
Y: <span class='selected_tile_y'></span> 
Movement: <span class='selected_tile_movement'></span>
Terrain: <span class='selected_tile_terrain'></span><br>
Furnishings: <span class='selected_tile_item_1'></span>, <span class='selected_tile_item_2'></span> 
Monster: <span class='selected_tile_monster'></span>
<br>
<button class='edit_option terrain_1' data-option="terrain" data-val="1">Grass</button>
<button class='edit_option terrain_2' data-option="terrain" data-val="2">Dirt</button>
<button class='edit_option terrain_3' data-option="terrain" data-val="3">Sand</button>
<button class='edit_option terrain_4' data-option="terrain" data-val="4">Water</button>
<button class='edit_option terrain_5' data-option="terrain" data-val="5">Ice</button>
<button class='edit_option terrain_6' data-option="terrain" data-val="6">Rock</button>
<button class='edit_option terrain_7' data-option="terrain" data-val="7">Lava</button>
<button class='edit_option terrain_8' data-option="terrain" data-val="8">Snow</button>
<button class='edit_option' data-option="item" data-val="0">No item</button>
<button class='edit_option' data-option="item" data-val="1">Item 1</button>
<button class='edit_option' data-option="item" data-val="2">Item 2</button>
<button class='edit_option' data-option="item" data-val="3">Item 3</button>
<button class='edit_option' data-option="item" data-val="4">Item 4</button>
<button class='edit_option' data-option="item" data-val="5">Item 5</button>
<button class='edit_option' data-option="monster" data-val="0">No monster</button>
<button...

CSS

div, img {
    box-sizing: border-box;
}

/* Stop <br> causing gap between rows. */
.map_holder {
    font-size: 0px;
}

.map_tile {
    cursor: pointer;
    background-color: green;
    width: 20px;
    height: 20px;
    font-size: 8px;
    display: inline-block;
    transition: 0.3s;
}

.map_tile:hover {
    background-color: brown;
    transition: 0.3s;
}

.selected_tile {
    opacity: 0.8;
    transition: 0.3s;
}

/* Div/textarea where data is exported or pasted in. */
.exported_map, .imported_map {
    border: 1px solid black;
    width: 100%;
    resize: none;
    padding: 10px;
    max-height: 200px;
    overflow: auto;
}

/* later use sprite sheet(s), gif tiles would be nice */

/* grass */
.terrain_1 {
    background-color: #44822B;
}

/* dirt */
.terrain_2{
    background-color: #7A3223;
}

/* sand */
.terrain_3 {
    background-color: #E3A976;
}

/* water */
.terrain_4 {
    background-color: #207DC9;
}

/* ice */
.terrain_5 {
    background-color: #A2CAEB;
}

/* rock */
.terrain_6 {
    background-color: #574845;
}

/* lava */
.terrain_7 {
    background-color: #EB330E;
}

/* snow */
.terrain_8 {
    background-color: #E6F0F2;
}

JavaScript

/* 
Example of what map will look like, after generating and while editing.
t is short for 'terrain', i = item
*/
var object_map = [
    [
        {t: 0, i: 1},
        {t: 1, i: 0},
        {t: 1, i: 0},
        {t: 0, i: 0},
        {t: 1, i: 0}
    ],[
        {t: 0, i: 0},
        {t: 0, i: 1},
        {t: 0, i: 0},
        {t: 1, i: 0},
        {t: 1, i: 0}
    ],[
        {t: 1, i: 0},
        {t: 1, i: 0},
        {t: 0, i: 1},
        {t: 0, i: 0},
        {t: 1, i: 0}
    ]
];

// Save the currently selected tile.
var selected_tile = {};

var current_y = 1;
var current_x = 1;

// (Re)generate empty map of plain tiles, to edit.
function generateEmptyMap(y, x){
    object_map = [];
    for(i = 0; i < y; i++){
        // Add empty array for row.
        object_map.push([]);
        // And get that row, ready to add tile objects
        var row = object_map[i];
        for(j = 0; j < x; j++){
            // Add plain tile.
            row.push( {t: 1, i: 0, m: 0} );
        }
    }
    // Re-render new map.
    renderMap();
}

generateEmptyMap(20,20);
renderMap();

// Needs no explanation.
$('.map_regenerate').click(function(){
    var y = Number( $('.size_y').val() );
    var x = Number( $('.size_x').val() );
    generateEmptyMap(y, x);
});


// EXPORTING
// After editing map, click a button.
// Code will appear in div, to be copied and saved by user.

$('.export_js').click(function(){
    $('.exported_map').html("JS code:<br>" + JSON.stringify(object_map) );
});

// Strip out all quotes and brackets.
// [{"t":1,"i":0},{"t":5,"i":8}],[{"t":4,"i":4},{"t":9,"i":9}]
// becomes... 1,0-5,8/4,4-9,9/
// May be easier when storing loads of maps in DB table?
$('.export_php').click(function(){
    var html = '';
    // Start looping down the rows, Y...
    for(i = 0; i < object_map.length; i++){
    
        var row = object_map[i];
        var row_html = [];
        // Start looping through tiles, X...
        for(j = 0; j < row.length; j++){
        
            //...