JSFiddle - React, Tailwind, and code Playground
by Gwyn Milcote
HTML
Griffin k/w/e calculator. For 'Shrine of the Griffin'. See how the black, white and exotic loci cause different colourings, and tortie markings in females.
<div class='container'>
<div id='mother' class='bg_mother'>Mother: <span id='parent_info_2'>Rainbow Tortie</span><br>
<div id='parent_coat_2' class='griffin_coat coat_adult'>Rendering...</div>
<select id='f_k1'>
<option value='K' selected>K</option>
<option value='k'>k</option>
</select>
<select id='f_k2'>
<option value='K'>K</option>
<option value='k' selected>k</option>
</select>
<select id='f_w1'>
<option value='W'>W</option>
<option value='w' selected>w</option>
</select>
<select id='f_w2'>
<option value='W'>W</option>
<option value='w' selected>w</option>
</select>
<select id='f_e1'>
<option value='E'>E</option>
<option value='e' selected>e</option>
</select>
<select id='f_e2'>
<option value='E'>E</option>
<option value='e' selected>e</option>
</select>
</div>
<div id='father' class='bg_father'>Father: <span id='parent_info_1'>Non-rainbow</span><br>
<div id='parent_coat_1' class='griffin_coat coat_adult'>Rendering...</div>
<select id='m_k1'>
<option value='K' selected>K</option>
<option value='k'>k</option>
</select>
<select id='m_w1'>
<option value='W' selected>W</option>
<option value='w'>w</option>
</select>
<select id='m_w2'>
<option value='W'>W</option>
<option value='w' selected>w</option>
</select>
<select id='m_e1'>
<option value='E'>E</option>
<option value='e' selected>e</option>
</select>
</div>
<br><button id='cross'>Cross</button><br>Here are the colours of potential offspring.<br>
<table id='result_table'></table>
</div>
CSS
.container {text-align:center;}
#mother, #father {border:1px solid black;padding:10px;margin:5px;border-radius:5px;display:inline-block;vertical-align:top;}
table {
width: 100%;
border-collapse: collapse;
margin: 20px auto;
}
table td {
border: 1px solid #ddd;
padding: 5px;
text-align: center;
}
table .empty {
border: none;
}
table .header {
font-weight: bold;
/*background-color: #ddd;*/
border: 1px solid #bbb;
}
.bg_father {
background-color: #bbe0f7;
}
.bg_mother {
background-color: #f2c7f3;
}
.bg_tortie {
background-image: url("https://a.deviantart.net/avatars-big/i/c/icestar142.png");
}
.griffin_coat {
position: relative;
}
.griffin_coat img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.coat_adult {
width: 400px;
height: 300px;
}
.coat_teen {
width: 400px;
height: 300px;
}
/* Same for all stages. */
.coat_bigthumb {
width: 200px;
height: 150px;
}
.coat_thumb {
width: 160px;
height: 120px;
}
.coat_small {
width: 120px;
height: 90px;
}
.coat_tiny {
width: 100px;
height: 75px;
}
.multiply {
mix-blend-mode: multiply;
}
.overlay {
mix-blend-mode: soft-light;
}
/*
Classes for each coat colour.
'f' means filters for black PNG images.
'c' means background colour for divs.
1-4 are shades: Base, Faded, Bright, Cream.
*/
/* Red, salmon, amaranth, pink */
.c_red_1 {background-color: #ffcc33;}
.c_red_2 {background-color: #ffcc33;}
.c_red_3 {background-color: #ffcc33;}
.c_red_4 {background-color: #ffcc33;}
.f_red_1 {filter: invert(13%) sepia(59%) saturate(5042%) hue-rotate(354deg) brightness(81%) contrast(90%);}
.f_red_2 {filter: invert(41%) sepia(14%) saturate(6118%) hue-rotate(337deg) brightness(92%) contrast(85%);}
.f_red_3 {filter: invert(58%) sepia(73%) saturate(483%) hue-rotate(308deg) brightness(100%) contrast(108%);}
.f_red_4 {filter: invert(86%) sepia(68%) saturate(1606%)...
JavaScript
const path = 'http://mythstable.epizy.com/ootg/images/';
// For assembling image HTML.
class Coat {
constructor(sex, stage, size = ""){
this.path = path + stage + "/";
if(stage > 3){ this.path += sex + "/"; }
if(size != ""){ this.path += size + "/"; }
this.startCoat();
}
startCoat(){
this.html = "<img src='" + this.path + "ground.png'>\n";
}
addImage(url){
this.html += "<img src='" + this.path + url + ".png'>\n";
}
addFilter(url, css){
this.html += "<img src='" + this.path + url + ".png' class='f_" + css + "'>\n";
}
endCoat(){
this.html += "<img src='" + this.path + "shade.png' class='multiply'>\n";
this.html += "<img src='" + this.path + "shade.png' class='overlay' style='opacity:0.3;'>\n";
this.html += "<img src='" + this.path + "line.png'>\n";
}
output(){
return this.html;
}
}
// Handle the Black/White/Exotic punnett square.
class KWECalc {
constructor(){
this.mother = {sex: 2, k1: "K", k2: "k", w1: "w", w2: "w", e1: "e", e2: "e"};
this.father = {sex: 1, k1: "k", w2: "W", w1: "W", e1: "E"};
this.updateParent(this.mother);
this.updateParent(this.father);
}
orderGenes(g){
if(g.sex == 2){
if(g.k1 == "k" && g.k2 == "K"){ g.k1 = "K"; g.k2 = "k"; }
if(g.e1 == "e" && g.e2 == "E"){ g.e1 = "E"; g.e2 = "e"; }
}
if(g.w1 == "w" && g.w2 == "W"){ g.w1 = "W"; g.w2 = "w"; }
return g;
}
updateMother(){
this.mother = {
sex: 2,
w1: $("#f_w1").val(),
w2: $("#f_w2").val(),
k1: $("#f_k1").val(),
k2: $("#f_k2").val(),
e1: $("#f_e1").val(),
e2: $("#f_e2").val()
};
this.updateParent(this.mother);
}
updateFather(){
this.father = {
sex: 1,
w1:...