JSFiddle - React, Tailwind, and code Playground
by Gwyn Milcote
HTML
ootg tool.<br>Here you can preview exactly how any genetic combination would look, in both sexes and all stages of life. Or you can click the <b>Randomise!</b> button to generate a completely random griffin.<br>
Note that the <b>Black</b> and <b>Exotic</b> loci are sex-linked; females carry two alleles but males only one. In males, the second allele in each pair will be ignored. You'll see how some colourations such as Tortoiseshell and Sunny work very differently.
<br><br>
<div class='section'>
<div class='select_holder'>
<div class='select_div'>
Red: <select id='create_r1'>
<option value='R'>R</option>
<option value='r' selected>r</option>
</select>
<select id='create_r2'>
<option value='R'>R</option>
<option value='r' selected>r</option>
</select>
</div>
<div class='select_div'>
Green: <select id='create_g1'>
<option value='G'>G</option>
<option value='g' selected>g</option>
</select>
<select id='create_g2'>
<option value='G'>G</option>
<option value='g' selected>g</option>
</select>
</div>
<div class='select_div'>
Cream: <select id='create_cr1'>
<option value='Cr'>Cr</option>
<option value='cr' selected>cr</option>
</select>
<select id='create_cr2'>
<option value='Cr'>Cr</option>
<option value='cr' selected>cr</option>
</select>
</div>
<div class='select_div'>
Fade: <select id='create_f1'>
<option value='F'>F</option>
<option value='f' selected>f</option>
</select>
<select id='create_f2'>
<option value='F'>F</option>
<option value='f' selected>f</option>
</select>
</div>
<div class='select_div'>
...
CSS
* {box-sizing: border-box;}
.griffin_coat {
position: relative;
}
.griffin_coat img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.coat_adult, .coat_teen {
width: 400px;
height: 300px;
}
.coat_cub {
width: 150px;
height: 150px;
}
.coat_chick, .coat_egg {
width: 100px;
height: 100px;
}
.adult_holder {
width: 420px;
border: 1px solid #ddd;
padding: 10px;
margin: 5px;
border-radius: 5px;
display: inline-block;
vertical-align: top;
text-align: center;
}
div .info {
margin: 10px 0px;
}
.multiply {
mix-blend-mode: multiply;
}
.overlay {
mix-blend-mode: soft-light;
}
.select_holder {
display: flex;
flex-flow: row wrap;
}
.select_holder .select_div {
width: 50%;
padding: 2px;
}
/*
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 */
.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%) hue-rotate(289deg) brightness(121%) contrast(102%);}
/* Orange, tan, gold, cream */
.f_orange_1 {filter: invert(38%) sepia(72%) saturate(1254%) hue-rotate(358deg) brightness(87%) contrast(98%);}
.f_orange_2 {filter: invert(60%) sepia(44%) saturate(658%) hue-rotate(340deg) brightness(90%) contrast(78%);}
.f_orange_3 {filter: invert(77%) sepia(9%) saturate(2816%) hue-rotate(340deg) brightness(97%) contrast(89%);}
.f_orange_4 {filter: invert(89%) sepia(17%) saturate(824%) hue-rotate(330deg) brightness(97%) contrast(104%);}
/* Amber, khaki, chiffon, ivory */
.f_amber_1 {filter:...
JavaScript
const path = "http://mythstable.epizy.com/ootg/images/";
// Alleles in every locus, in order of dominance.
// Used when making random griffins, and ordering genotype.
const genome = {
r: ["R", "r"],
g: ["G", "g"],
k: ["K", "k"],
w: ["W", "w"],
e: ["E", "e"],
cr: ["Cr", "cr"],
// Below, genes I had to guess.
// Fade: inc-dominant?
f: ["F", "f"],
// Limiter: tiger, leopard. Co-dom.
lm: ["Lm^t", "Lm^l", "lm"],
// Agelaius (dusky): dominant?
ag: ["Ag", "ag"],
// Mask: recessive? Activated by heating egg?
m: ["M", "m"],
// Paint: boots, dip (inc-dom), splash.
p: ["P^b", "P^d", "P^s", "p"],
// Sunny: dominant?
s: ["S", "s"],
// Fairbelly: dominant?
fb: ["Fb", "fb"],
// Niviculous (snowy): dominant? Activated by cooling egg?
nv: ["Nv", "nv"]
};
// Names, useful for looping through genos.
const loci = ["r", "g", "k", "w", "e", "cr", "f", "lm", "ag", "m", "p", "s", "fb", "nv"];
// Oily and Black are not meant to have Bright shades.
// Including them just for fun, beauty and simpler code.
const colourNames = [
["Red", "Salmon", "Amaranth", "Pink"],
["Orange", "Tan", "Gold", "Cream"],
["Amber", "Khaki", "Chiffon", "Ivory"],
["Green", "Olive", "Lime", "Celadon"],
["Teal", "Stormy Seas", "Cyan", "Seafoam"],
["Cobalt Blue", "Steel Blue", "Sky Blue", "Baby Blue"],
["Purple", "Violet", "Amethyst", "Lavender"],
["Bronze", "Mocha", "Copper", "Sandy"],
["Oil Spill", "Opal", "Titanium", "Pearl"],
["Black", "Grey", "Smoke", "Silver"]
];
const shadeNames = ["Normal", "Faded", "Bright", "Cream"];
const markNames = {
"dusky_tigard": "Dusky Tigard",
"dusky_tiger": "Dusky Tiger",
"dusky_leopard": "Dusky Leopard",
"dusky": "Dusky",
"tiger": "Tiger",
"leopard": "Leopard",
"tigard": "Tigard"
};
function randomNumber(n1, n2){
if(n1 == n2){ return n1; }
var min = n1; var max = n2;
if(n1 > n2){ min = n2; max = n1; }
...