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"}
...