JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/umbrella.min.js"></script>
<div id='container'>
<div class='page'>
    <div id='palette'>...</div>

    Render method: <select id='render_choice'>
        <option value='css'>CSS</option>
        <option value='canvas' selected>Canvas</option>
    </select> <button id='test_btn'>Generate</button>
    <p>Canvas allows you to download images, but it's a bit unreliable. Choose CSS as a backup, that always works.</p>
    
    <div id='test'></div>

    <div class='flex'>
    <div class='half center'>
        <div id='coat_adult_male' class='griffin_coat coat_adult'></div>
    </div> 
    <div class='half center'>
        <div id='coat_adult_female' class='griffin_coat coat_adult'></div>
    </div>
</div>

<div class='flex'>
    <div class='half center'> 
        <p><div id='description_male' class='info'></div></p>
        <div id='genotype_male' class='info'></div>
    </div>
    <div class='half center'> 
        <p><div id='description_female' class='info'></div></p>
        <div id='genotype_female' class='info'></div>
    </div>
</div>

<p>

<div class='flex'>
    <div>
        <div id='coat_teen_male' class='griffin_coat coat_teen'>male teen</div>
    </div>
    
    <div id='prev_babies'>
        <div id='coat_egg_male' class='griffin_coat coat_baby'>male egg</div>
        <div id='coat_cub_male' class='griffin_coat coat_baby'>male cub</div>
        
        <div id='coat_egg_female' class='griffin_coat coat_baby'>female egg</div>
        <div id='coat_cub_female' class='griffin_coat coat_baby'>female cub</div>
    
        <div id='coat_chick' class='griffin_coat coat_baby'>chick</div>
    </div>
    
    <div>
        <div id='coat_teen_female' class='griffin_coat coat_teen'>female teen</div>
    </div>
</div>

</p>

<button id='merge_btn'>Merge into Sheet</button>
<div id='merge_container'>...</div>


</div>
</div>

CSS

.palette {
    display: flex;
    flex-flow: row;
    justify-content: space-between;
    width: 80%;
    margin: 0px auto 5px auto;
}

.palette .swatch {
    width: calc(9% - 5px);
    height: 30px;
    border-radius: 5px;
}

/* COLOURS, minified */

.c_red_1{background-color:#fc3}.c_red_2{background-color:#fc3}.c_red_3{background-color:#fc3}.c_red_4{background-color:#fc3}.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%)}.c_orange_1{background-color:#fc3}.c_orange_2{background-color:#fc3}.c_orange_3{background-color:#fc3}.c_orange_4{background-color:#fc3}.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%)}.c_amber_1{background-color:#fc3}.c_amber_2{background-color:#fc3}.c_amber_3{background-color:#fc3}.c_amber_4{background-color:#fc3}.f_amber_1{filter:invert(70%) sepia(95%) saturate(586%) hue-rotate(335deg) brightness(100%) contrast(94%)}.f_amber_2{filter:invert(85%) sepia(34%) saturate(494%) hue-rotate(323deg) brightness(93%) contrast(88%)}.f_amber_3{filter:invert(99%) sepia(97%) saturate(1026%) hue-rotate(314deg) brightness(102%) contrast(98%)}.f_amber_4{filter:invert(88%) sepia(90%) saturate(286%) hue-rotate(312deg) brightness(102%)...

JavaScript

/*
* JS for 'Order of the Griffin' fansite, by Gwyn Milcote.
* The original game was created by Jennifer Hoffman.
* http://www.jenniferhoffman.net/image.php?img=83
*
* Griffin designs, genetic system and terminology belong to her.
* This is only a partial re-creation, for fans' nostalgia.
*/

const imagePath = "http://milcote.net/images/shrine/";

/*
* Some extra functions added to UmbrellaJS.
* Use them just like in jQuery.
* u("#some_id, .some_class").fadeOut();
* u(".class").css({"color": "#ffcc33", "font-size": "20px"});
*/
u.prototype.fadeIn = function(){
  return this.each(function(node){
    node.classList.add('show','fade');
    node.classList.remove('hide');
  });
};
u.prototype.fadeOut = function(){
  return this.each(function(node){
    node.classList.add('hide','fade');
    node.classList.remove('show');
  });
};
u.prototype.show = function(){
  return this.each(function(node){
    node.classList.add('show');
    node.classList.remove('hide','fade');
  });
};
u.prototype.hide = function(){
  return this.each(function(node){
    node.classList.add('hide');
    node.classList.remove('show','fade');
  });
};
u.prototype.css = function(name, value){
  return this.pairs(name, value, function(node, name){
    return node.style[name];
  }, function(node, name, value){
    node.style[name] = value;
  });
};

/*
* Utility stuff.
*/
function randomNumber(n1, n2){
    if(n1 == n2){ return n1; }
    let min = n1; let max = n2;
    if(n1 > n2){ min = n2; max = n1; }
    return Math.floor(Math.random()*(max-min+1)+min);
}

function randomArray(array){
    return array[Math.floor(Math.random() * array.length)];
}

u(".tab_button").on("click", function(){
    let tab = u(this).data("tab");
    u(".tab_content").hide();
    u(".tab_" + tab).show();
    u(".tab_button").removeClass("active_tab");
    u(this).addClass("active_tab");
});

function popupError(message){
    u("#error_message").html(message);
    u("#error_holder").fadeIn();
}
u("#error_close").on("click",...