JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<div class='dragonCanvas' id='dragonCanvas1' data-id='1' data-breed='1' data-sex='2' data-stage='4' data-genes='abc' data-mods='ggggg'></div>
<div class='dragonCanvas' id='dragonCanvas2' data-id='2' data-breed='1' data-sex='1' data-stage='3' data-genes='cdf' data-mods='fffff'></div>
<div class='dragonCanvas' id='dragonCanvas3' data-id='3' data-breed='1' data-sex='2' data-stage='4' data-genes='abc' data-mods='ggggg'></div>
<div class='dragonCanvas' id='dragonCanvas4' data-id='4' data-breed='1' data-sex='1' data-stage='3' data-genes='cdf' data-mods='fffff'></div>

<canvas id='dragon_canvas'></canvas>

<div id='show_sheets'></div>

CSS

/*
* Canvases will be generated inside these divs.
*/
div.dragonCanvas {
    background-color: lightblue;
    width: 250px;
    height: 200px;
    margin: 10px auto;
    display: inline-block;
}


#show_sheets img {
    max-width: 100%;
    height: auto;
}

JavaScript

const patchUrl = "http://mythstable.epizy.com/demo/sprite-patch.png",
      dragonUrl = "http://mythstable.epizy.com/demo/drag-sheet.png";

const imagePath = "http://mythstable.epizy.com/demo/";

// Note to self: use multiples of 2,
// so the 50% size version will scale down well.
const dragonMap = {
    line: {x: 0, y: 0, w: 250, h: 200},
    base: {x: 250, y: 0, w: 250, h: 200},
    shade: {x: 500, y: 0, w: 250, h: 200}
};

const patchMap = {
    // Smudgy patches
    tortie1: {x: 0, y: 0, w: 40, h: 30},
    tortie2: {x: 0, y: 0, w: 40, h: 30},
    tortie3: {x: 0, y: 0, w: 40, h: 30},
    tortie4: {x: 0, y: 0, w: 40, h: 30},
    tortie5: {x: 0, y: 0, w: 40, h: 30},
    // Solid patches
    pied1: {x: 0, y: 0, w: 40, h: 30},
    pied2: {x: 0, y: 0, w: 40, h: 30},
    pied3: {x: 0, y: 0, w: 40, h: 30},
    pied4: {x: 0, y: 0, w: 40, h: 30},
    pied5: {x: 0, y: 0, w: 40, h: 30},
    // Solid blobs
    blob1: {x: 0, y: 0, w: 40, h: 30},
    blob2: {x: 0, y: 0, w: 40, h: 30},
    blob3: {x: 0, y: 0, w: 40, h: 30},
    blob4: {x: 0, y: 0, w: 40, h: 30},
    blob5: {x: 0, y: 0, w: 40, h: 30},
    // Clusters of spots
    spots1: {x: 0, y: 0, w: 40, h: 30},
    spots2: {x: 0, y: 0, w: 40, h: 30},
    spots3: {x: 0, y: 0, w: 40, h: 30},
    spots4: {x: 0, y: 0, w: 40, h: 30},
    spots5: {x: 0, y: 0, w: 40, h: 30}
};






/*
* Class that handles all canvas vars and rendering.
* Pass it an array of image layers (urls, hex codes, opacity etc).
* And specify which .dragonCanvas div the final canvas will be appended to.
*
* Later, use toDataUrl() and just turn layers -> image, return that.
*/
class DragonRenderer {
    
    constructor(dragons = false){
        if(dragons != false){
            this.setDragons(dragons);
            this.preloadImages();
        }
    }
    
    // Store an array of dragon objects.
    // They should have had layers generated already.
    setDragons(array){
        this.dragons = array;
    }
    
    // Just bare naked dragons?
    // Or...