JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<b>Marking designer tool</b>
<br>No genes, just simple shape/colour/opacity. Each slot is 5 characters long, ideal for DB storage.<br>
As an example, try loading this:<br>cj2c1-dj4x5-aa9m1-di5x2-dd6m1-cd5m1-di1v2-dc6d3-db6x3-ce8x4-s1-c1<br>

<p>
Enter string: <input type='text' id='genome_string'> <button id='load_string'>Load</button> <button id='randomise'>Randomise!</button>
<br>
<button id='output_string'>Output current design?</button>
<br>
<span id='output_result'>...</span>
</p>

<div id='mark_tabs'>
    ...
</div>

<div id='design_mark' class='section'>
    
    <div id='base_options'>
        <b>Base colour:</b> <span id='base_description'></span>
    </div>
    <div id='eye_options' style='display:none;'>
        <b>Eye colour:</b> <span id='eye_description'></span>
    </div>
    
    <div id='mark_options' style='display:none;'>
        <b>Marking <span id='current_slot'>1</span>:</b> <span id='mark_description'>desc</span>
        <br><br>
        <button id='toggle_colour'>Toggle Palette?</button> 
    
        Area: <select id='mark_area'>
            <option value='a'>None</option>
            <option value='b'>Mask</option>
            <option value='c'>Underside</option>
            <option value='d'>Streak</option>
            <option value='e'>Flights</option>
            <option value='f'>Leopard</option>
        </select> 

        Effect: <select id='mark_effect'>
            <option value='a'>Solid</option>
            <option value='b'>Marbled</option>
            <option value='c'>Cascading</option>
            <option value='d'>Soft</option>
            <option value='e'>Filigree</option>
            <option value='f'>Dalmatian</option>
            <option value='g'>Tobiano</option>
            <option value='h'>Flecked</option>
            <option value='i'>Swirly</option>
            <option value='j'>Patchy</option>
        </select> 

        Strength: <input id='mark_opacity' type='range' min='0' max='9'>
    
    </div>
    
   ...

CSS

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

.section {
    border: 1px solid grey;
    padding: 10px;
    margin: 0px auto 10px auto;
}

#mark_tabs {
    display: flex;
    flex-flow: row wrap;
    position: relative;
    top: 1px;
}

#mark_tabs .tab {
    border: 1px solid grey;
    margin: 0px 3px;
    background-color: #ccc;
    transition: 0.2s;
    min-width: 60px;
    height: 40px;
    position: relative;
}

#mark_tabs .tab:hover {
    cursor: pointer;
    background-color: #eee;
    transition: 0.2s;
}

#mark_tabs .active_tab {
    border-color: red;
    background-color: #fff;
    border-bottom: 1px solid white;
}

#mark_tabs .tab_info {
    position: absolute;
    bottom: 0px;
    margin: 5px;
}

#mark_tabs .tab_bg {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 10px;
    background-color: green;
}



.center {
    text-align: center;
}

#colour_palette {
    display: flex;
    flex-flow: row wrap;
}

#colour_palette .swatch {
    display: inline-block;
    width: 10%;
    height: 20px;
}

.beast_coat {
    border: 1px dotted grey;
    width: 250px;
    height: 250px;
    position: relative;
    margin: auto;
}

.beast_coat img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}



#colour_palette table {
    width: 50%;
    /*height: 100%;*/
}

#colour_palette table td {
    height: 20px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3) inset;
    transition: 0.2s;
}

#colour_palette table td:hover {
    cursor: pointer;
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.3) inset;
    transition: 0.2s;
}

#colour_palette .active_colour {
    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.4) inset;
    transition: 0.2s;
}




.c_white { background-color: #FFFFFF; }
.f_white { filter: invert(100%); }

/* Red (r). a = bright, m = dull. */

.f_a1 { filter: invert(85%) sepia(10%) saturate(708%) hue-rotate(314deg) brightness(101%) contrast(91%); }
.f_a2 { filter: invert(66%) sepia(81%) saturate(1057%)...

JavaScript

const path = "http://mythstable.epizy.com/thing2/images/";


// Markings have an area (mask, belly, rump)...
// And an effect (solid, patchy, filigree, flecked)...
// In case more options are added later,
// one letter a-z is used, instead of a digit 0-9.

// Could convert letter to number, to get names from arrays.
// But using object key-value pairs is easier.

const markAreas = {a: "None", b: "Mask", c: "Underside", d: "Streak", e: "Flights", f: "Leopard"};

const markEffects = {a: "Solid", b: "Marbled", c: "Cascading", d: "Soft", e: "Filigree", f: "Dalmatian", g: "Tobiano", h: "Flecked", i: "Swirly", j: "Patchy"};

// a = no marking. The rest are a letter each.
const validAreas = "abcdef".split("");
// All letters are effects.
const validEffects = "abcdefghij".split("");

// Red, copper, amber, yellow... purple, magenta, silver.
// Used for colour wheel and calculations.
const validColours = "rcayogtbivpms".split("");

// a-m are bright, n-z are dull. Same 13 colours as above.
// Single letter is stored in DB and used for CSS class.
const validLetters = "abcdefghijklmnopqrstuvwxyz".split("");

/*
chocolate, toast, coffee, mocha, latte, tawny
brown, umber, almond, cinnamon, peanut, cedar
*/

// Look up proper colour names and hex codes here.
const colourInfo = {
    a: [ // Bright Red
        {name: "Powder Pink", hex: "F4CCCC"},
        {name: "Salmon", hex: "E48181"},
        {name: "Cherry", hex: "D52F2F"},
        {name: "Ruby", hex: "9B2020"},
        {name: "Cranberry", hex: "681515"}
    ],
    n: [ // Dull Red
        {name: "Misty Rose", hex: "E9D7D7"},
        {name: "Blush", hex: "C99999"},
        {name: "Russet", hex: "A75B5B"},
        {name: "Rose Vale", hex: "7A4040"},
        {name: "Mahogany", hex: "562C2C"}
    ],
    b:  [ // Bright Copper
        {name: "Shell", hex: "F2E6DF"},
        {name: "Peach", hex: "DAB8A5"},
        {name: "Chestnut", hex: "B97A57"},
        {name: "Copper", hex: "7C4E32"},
        {name: "Walnut", hex: "4B301F"}
...