Difference between revisions of "MediaWiki:MobTaxonomy.js"

m
m
 
(67 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
(function () {
 +
 
/* Create the needed elements to hold the data. */
 
/* Create the needed elements to hold the data. */
$('h2:contains("Taxonomy")').after('<br><br><h2 id="notableNPCs" style="display:none;"><span>Notable NPCs</span></h2>')
+
$('#Taxonomy').parent().after(`
    .after('<div id="taxonomyContainer"><canvas id="relatedMobs" width="800" height="600"></canvas></div>');
+
<span style="font-size: 150%;font-weight: 900;"><span id="taxonomyGroupA" class="translatable">Group</span>: <span id="taxonomyGroupB"></span></span>
 +
<br>
 +
<br>
 +
<span id="taxonomyNote" class="translatable">Click and drag left or right to scroll within the taxonomy tree.</span>
 +
<div id="taxonomyContainer" class="crispImages grabbable" style="overflow-x: auto;">
 +
    <canvas id="relatedMobs" width="800" height="600"></canvas>
 +
</div>`).before(`
 +
<br>
 +
<br>
 +
<h2 id="notableNPCs" style="display:none;">
 +
    <span id="Notables" class="translatable">Notable Related NPCs</span>
 +
</h2>`);
  
 +
$('#taxonomyGroupA, #taxonomyNote, #Notables').each(function () {
 +
    $(this).data('text', $(this).text());
 +
});
  
 
/* What mob are we dealing with? */
 
/* What mob are we dealing with? */
 
let mobs = stratics.data.mobs,
 
let mobs = stratics.data.mobs,
     mobType = $('#mobileName').text();
+
     mobType = $('#mobileName').text(),
 +
    thisPage = document.location.search;
 
if (!mobType) {
 
if (!mobType) {
     mobType = document.location.search.split(':')[1].replace(/ \((?:Centaur|creature|monster)\)/, '');
+
     mobType = thisPage.split(':')[1].replace(/ \((?:Centaur|creature|monster)\)/, '').replace(/_/g,' ');
 
}
 
}
 
let family = mobs[mobType].family;
 
let family = mobs[mobType].family;
 
+
$('#taxonomyGroupB').text(family);
  
 
/* Create the orgchart. */
 
/* Create the orgchart. */
Line 18: Line 35:
 
o.setColor('#111', '#FFFF99', '#000', '#1E90FF');
 
o.setColor('#111', '#FFFF99', '#000', '#1E90FF');
 
o.setNodeStyle(1, 10, 2);
 
o.setNodeStyle(1, 10, 2);
o.setFont('arial', 14, '#000', 'c');
+
o.setFont('arial', 13, '#000', 'c');
o.setSize(120, 40, 40, 30);
+
o.setSize(110, 35, 35, 25);
 
o.setColor('#3388DD', '#DAA520');
 
o.setColor('#3388DD', '#DAA520');
  
Line 30: Line 47:
 
};
 
};
  
let mobTreeData = {},
+
let matcher = new RegExp(`(?:,|^)${family}(?:,|$)`),
    NPCs = {},
+
    mobTreeData = stratics.data.mobTreeData = {},
    matcher = new RegExp(`(?:,|^)${family}(?:,|$)`);
+
    NPCs = stratics.data.NPCs = {};
  
 
let addMob = (name, info) => {
 
let addMob = (name, info) => {
Line 50: Line 67:
 
     if (mobs[x].family.match(matcher)) {
 
     if (mobs[x].family.match(matcher)) {
 
         if (parseInt(mobs[x].bluename, 10)) {
 
         if (parseInt(mobs[x].bluename, 10)) {
             NPCs[x] = mobs[x];
+
             if (!NPCs[mobs[x].parent]) {
 +
                NPCs[mobs[x].parent] = {};
 +
            }
 +
            NPCs[mobs[x].parent][x] = mobs[x];
 
         } else {
 
         } else {
 
             countMobs(x, mobs[x]);
 
             countMobs(x, mobs[x]);
Line 78: Line 98:
  
 
         // Tweaks to improve the look of the resulting trees.
 
         // Tweaks to improve the look of the resulting trees.
         if (['Red Solen', 'Gray Goblin', 'Gray Goblin Mage', 'Leather Wolf'].includes(x)) dir = 'r';
+
         if (['Red Solen','Savages','Virulent','Gray Goblin', 'Gray Goblin Mage', 'Leather Wolf','Rodentia','Rat','Rabbit','Caniformia'].includes(x)) dir = 'r';
         if (y.parent == 'Korpre') dir = 'u';
+
         if (['Drake','Vile Mage','Canidae','Amphibia'].includes(x)) dir = 'l';
 
+
        if ([ 'Korpre','Odobenidae'].includes(x)) dir = 'u';
 
         if (mobType === x) { // 'Highlight' if the current mob being handled is the same as the mob for this page
 
         if (mobType === x) { // 'Highlight' if the current mob being handled is the same as the mob for this page
 
             o.setColor('#3388DD', '#1E90FF');
 
             o.setColor('#3388DD', '#1E90FF');
 
         }
 
         }
         o.addNode(y.name, y.parent, dir, y.name, 0, `http://community.stratics.com/w/index.php?title=UO:${y.page}`);
+
         if (stratics.data.categoryMobs.includes(x)) { // Grey-out mob entries that only are categories, not actual mobs themselves.
 +
            o.setColor('#3388DD', '#D9D9D9');
 +
            o.addNode(y.name, y.parent, dir, y.name);
 +
        } else {
 +
            o.addNode(y.name, y.parent, dir, y.name, 0, `https://wiki.stratics.com/index.php?title=UO:${y.page}`);
 +
        }
 
         o.setColor('#3388DD', '#DAA520'); // Reset the colors
 
         o.setColor('#3388DD', '#DAA520'); // Reset the colors
 
     }
 
     }
Line 92: Line 117:
 
o.drawChart('relatedMobs', 'c', true);
 
o.drawChart('relatedMobs', 'c', true);
  
/* Scale the orgchart to fit the contents. */
+
/* Make the canvas draggable */
let tc = '#taxonomyContainer';
+
$('#taxonomyContainer').on({
let $tc = $(tc);
+
    mousedown: function(click) {
let $canvas = $(`${tc} canvas`);
+
        origX = click.pageX + $(this).scrollLeft();
let ratio = $(tc).width() / $canvas.width();
+
        $(this).on({
if (ratio < 1) {
+
            mousemove: function(e) {
    $tc.css({
+
                curX = e.pageX + $(this).scrollLeft();
         transform: `scale(${ratio})`,
+
                var diff = (origX - curX);
         'image-rendering': '-webkit-optimize-contrast',
+
                var newpos = $(this).scrollLeft() + diff;
         '-ms-interpolation-mode': 'nearest-neighbor'
+
                if (newpos > ($('canvas').width() - $(this).width())) {
     }).css({
+
                    newpos = ($('canvas').width() - $(this).width());
        'image-rendering': '-moz-crisp-edges'
+
                }
     }).css({
+
                if (newpos < 0) {
        'image-rendering': '-o-crisp-edges'
+
                    newpos = 0;
     }).css({
+
                }
        'image-rendering': 'optimize-contrast'
+
                $(this).scrollLeft(newpos);
    }).css({
+
            }
        'image-rendering': 'crisp-edges',
+
         });
         marginLeft: `${$tc.parent().offset().left - $tc.offset().left}px`
+
    },
     });
+
    mouseleave: function() {
 +
         $(this).off('mousemove');
 +
    },
 +
    mouseup: function() {
 +
        $(this).off('mousemove');
 +
    },
 +
    click: function() {
 +
         $(this).off('mousemove');
 +
     }
 +
});
 +
 
 +
/* Switch cursor depending if we're over the background or a node in the canvas.
 +
  Modified from http://stackoverflow.com/questions/6735470/get-pixel-color-from-canvas-on-mouseover */
 +
/* jshint ignore:start */
 +
$('#taxonomyContainer canvas').mousemove(function(e) {
 +
     var pos = findPos(this);
 +
    var x = e.pageX - pos.x + this.parentNode.scrollLeft;
 +
    var y = e.pageY - pos.y + this.parentNode.scrollTop;
 +
    var c = this.getContext('2d');
 +
     var p = c.getImageData(x, y, 1, 1).data;
 +
    $('#taxonomyContainer')[`${(!![...new Set(p)][0]) ? 'remove' : 'add'}Class`]('grabbable');
 +
});
 +
 
 +
function findPos(obj) {
 +
    var curleft = 0, curtop = 0;
 +
    if (obj.offsetParent) {
 +
         do {
 +
            curleft += obj.offsetLeft;
 +
            curtop += obj.offsetTop;
 +
        } while (obj = obj.offsetParent);
 +
        return { x: curleft, y: curtop };
 +
     }
 +
    return undefined;
 
}
 
}
 +
/* jshint ignore:end */
 +
 +
/* Build the list of notable NPCs. */
 +
if (Object.keys(stratics.data.NPCs).length > 0) {
 +
    let $notables = $('<div style="margin-left:3%;">');
 +
    let arr = [];
 +
    for (let b in stratics.data.NPCs)
 +
        if (stratics.data.NPCs.hasOwnProperty(b)) arr.push(b);
 +
    arr = arr.sort();
 +
    for (let x of arr) {
 +
        let $ul = $('<ul style="list-style-type:none;list-style-image:none;">');
 +
        let arrType = [];
 +
        for (let a in stratics.data.NPCs[x])
 +
            if (stratics.data.NPCs[x].hasOwnProperty(a)) arrType.push(a);
 +
        arrType = arrType.sort();
 +
        for (let y of arrType) {
 +
            let entry = stratics.data.NPCs[x][y];
 +
            let page = !!entry.page.length ? entry.page : y;
 +
            $ul.append(`<li><a href="${`https://wiki.stratics.com/index.php?title=UO:${page}`}">${y}</a></li>`);
 +
        }
 +
        if (x === 'Elf') x = 'Elve';
 +
        if (x === 'Dwarf') x = 'Dwarve';
 +
        if (x === 'Mouse') x = 'Mice';
 +
        x = x.replace(/(W|w)olf$/,'$1olves');
 +
        let s = (['Mice','Britannia Network News', 'Order of the Silver Serpent', 'Zog Cabal', 'Lord Blackthorn', 'Tyball'].indexOf(x) !== -1) ? '' : 's'; // Don't add an 's' to things where it wouldn't make sense
 +
        $notables.append(`<span style="font-size:140%;color:goldenrod;">${x}${s}:</span>`).append($ul).append('<br>');
 +
    }
 +
 +
    /* Add the list of notable NPCs. */
 +
    $('#notableNPCs').after($notables).show();
 +
 +
    /* Update the table of contents */
 +
    $('.toclevel-2:last span:first').text('1.6');
 +
    $('.toclevel-2:last').before(`<li class="toclevel-2"><a href="/w/index.php${thisPage}#Notables"><span class="tocnumber">1.5</span> <span class="toctext">Noteable Related NPCs</span></a></li>`);
 +
    $('.toclevel-1').parent().css('margin', '7px');
 +
}
 +
 +
}());
 +
//# sourceURL=MobTaxonomy.js

Latest revision as of 07:57, 8 January 2020

(function () {

/* Create the needed elements to hold the data. */
$('#Taxonomy').parent().after(`
<span style="font-size: 150%;font-weight: 900;"><span id="taxonomyGroupA" class="translatable">Group</span>: <span id="taxonomyGroupB"></span></span>
<br>
<br>
<span id="taxonomyNote" class="translatable">Click and drag left or right to scroll within the taxonomy tree.</span>
<div id="taxonomyContainer" class="crispImages grabbable" style="overflow-x: auto;">
    <canvas id="relatedMobs" width="800" height="600"></canvas>
</div>`).before(`
<br>
<br>
<h2 id="notableNPCs" style="display:none;">
    <span id="Notables" class="translatable">Notable Related NPCs</span>
</h2>`);

$('#taxonomyGroupA, #taxonomyNote, #Notables').each(function () {
    $(this).data('text', $(this).text());
});

/* What mob are we dealing with? */
let mobs = stratics.data.mobs,
    mobType = $('#mobileName').text(),
    thisPage = document.location.search;
if (!mobType) {
    mobType = thisPage.split(':')[1].replace(/ \((?:Centaur|creature|monster)\)/, '').replace(/_/g,' ');
}
let family = mobs[mobType].family;
$('#taxonomyGroupB').text(family);

/* Create the orgchart. */
let o = new orgChart();

o.setColor('#111', '#FFFF99', '#000', '#1E90FF');
o.setNodeStyle(1, 10, 2);
o.setFont('arial', 13, '#000', 'c');
o.setSize(110, 35, 35, 25);
o.setColor('#3388DD', '#DAA520');

/* Populate the orgchart. */
let countMobs = (name, info) => {
    if (!mobs[info.parent].kids) {
        mobs[info.parent].kids = 0;
    }
    mobs[info.parent].kids++;
};

let matcher = new RegExp(`(?:,|^)${family}(?:,|$)`),
    mobTreeData = stratics.data.mobTreeData = {},
    NPCs = stratics.data.NPCs = {};

let addMob = (name, info) => {
    if (!mobTreeData[name]) {
        mobTreeData[name] = {
            name,
            parent: info.parent,
            page: !!info.page.length ? info.page : name
        };
    }
    if (info.parent.length && name !== info.parent) { // Climb the family tree; stop if we're at the top.
        addMob(info.parent, mobs[info.parent]);
    }
};

for (let x in mobs) {
    if (mobs[x].family.match(matcher)) {
        if (parseInt(mobs[x].bluename, 10)) {
            if (!NPCs[mobs[x].parent]) {
                NPCs[mobs[x].parent] = {};
            }
            NPCs[mobs[x].parent][x] = mobs[x];
        } else {
            countMobs(x, mobs[x]);
        }
    }
}

for (let x in mobs) {
    if (mobs[x].family.match(matcher)) {
        if (!parseInt(mobs[x].bluename, 10)) {
            addMob(x, mobs[x]);
        }
    }
}

for (let x in mobTreeData) {
    if (mobTreeData.hasOwnProperty(x)) {
        let y = mobTreeData[x],
            dir = 'u';
        if (!!mobs[y.parent] && mobs[y.parent].kids > 1) {
            if (!mobs[y.parent].counter) {
                mobs[y.parent].counter = 0;
            }
            let counter = (mobs[y.parent].counter++ % 2);
            dir = !counter ? 'r' : 'l';
        }

        // Tweaks to improve the look of the resulting trees.
        if (['Red Solen','Savages','Virulent','Gray Goblin', 'Gray Goblin Mage', 'Leather Wolf','Rodentia','Rat','Rabbit','Caniformia'].includes(x)) dir = 'r';
        if (['Drake','Vile Mage','Canidae','Amphibia'].includes(x)) dir = 'l';
        if ([ 'Korpre','Odobenidae'].includes(x)) dir = 'u';
        if (mobType === x) { // 'Highlight' if the current mob being handled is the same as the mob for this page
            o.setColor('#3388DD', '#1E90FF');
        }
        if (stratics.data.categoryMobs.includes(x)) { // Grey-out mob entries that only are categories, not actual mobs themselves.
            o.setColor('#3388DD', '#D9D9D9');
            o.addNode(y.name, y.parent, dir, y.name);
        } else {
            o.addNode(y.name, y.parent, dir, y.name, 0, `https://wiki.stratics.com/index.php?title=UO:${y.page}`);
        }
        o.setColor('#3388DD', '#DAA520'); // Reset the colors
    }
}

/* Render the orgchart. */
o.drawChart('relatedMobs', 'c', true);

/* Make the canvas draggable */
$('#taxonomyContainer').on({
    mousedown: function(click) {
        origX = click.pageX + $(this).scrollLeft();
        $(this).on({
            mousemove: function(e) {
                curX = e.pageX + $(this).scrollLeft();
                var diff = (origX - curX);
                var newpos = $(this).scrollLeft() + diff;
                if (newpos > ($('canvas').width() - $(this).width())) {
                    newpos = ($('canvas').width() - $(this).width());
                }
                if (newpos < 0) {
                    newpos = 0;
                }
                $(this).scrollLeft(newpos);
            }
        });
    },
    mouseleave: function() {
        $(this).off('mousemove');
    },
    mouseup: function() {
        $(this).off('mousemove');
    },
    click: function() {
        $(this).off('mousemove');
    }
});

/* Switch cursor depending if we're over the background or a node in the canvas.
   Modified from http://stackoverflow.com/questions/6735470/get-pixel-color-from-canvas-on-mouseover */
/* jshint ignore:start */
$('#taxonomyContainer canvas').mousemove(function(e) {
    var pos = findPos(this);
    var x = e.pageX - pos.x + this.parentNode.scrollLeft;
    var y = e.pageY - pos.y + this.parentNode.scrollTop;
    var c = this.getContext('2d');
    var p = c.getImageData(x, y, 1, 1).data; 
    $('#taxonomyContainer')[`${(!![...new Set(p)][0]) ? 'remove' : 'add'}Class`]('grabbable');
});

function findPos(obj) {
    var curleft = 0, curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
    return undefined;
}
/* jshint ignore:end */

/* Build the list of notable NPCs. */
if (Object.keys(stratics.data.NPCs).length > 0) {
    let $notables = $('<div style="margin-left:3%;">');
    let arr = [];
    for (let b in stratics.data.NPCs)
        if (stratics.data.NPCs.hasOwnProperty(b)) arr.push(b);
    arr = arr.sort();
    for (let x of arr) {
        let $ul = $('<ul style="list-style-type:none;list-style-image:none;">');
        let arrType = [];
        for (let a in stratics.data.NPCs[x])
            if (stratics.data.NPCs[x].hasOwnProperty(a)) arrType.push(a);
        arrType = arrType.sort();
        for (let y of arrType) {
            let entry = stratics.data.NPCs[x][y];
            let page = !!entry.page.length ? entry.page : y;
            $ul.append(`<li><a href="${`https://wiki.stratics.com/index.php?title=UO:${page}`}">${y}</a></li>`);
        }
        if (x === 'Elf') x = 'Elve';
        if (x === 'Dwarf') x = 'Dwarve';
        if (x === 'Mouse') x = 'Mice';
        x = x.replace(/(W|w)olf$/,'$1olves');
        let s = (['Mice','Britannia Network News', 'Order of the Silver Serpent', 'Zog Cabal', 'Lord Blackthorn', 'Tyball'].indexOf(x) !== -1) ? '' : 's'; // Don't add an 's' to things where it wouldn't make sense
        $notables.append(`<span style="font-size:140%;color:goldenrod;">${x}${s}:</span>`).append($ul).append('<br>');
    }

    /* Add the list of notable NPCs. */
    $('#notableNPCs').after($notables).show();

    /* Update the table of contents */
    $('.toclevel-2:last span:first').text('1.6');
    $('.toclevel-2:last').before(`<li class="toclevel-2"><a href="/w/index.php${thisPage}#Notables"><span class="tocnumber">1.5</span> <span class="toctext">Noteable Related NPCs</span></a></li>`);
    $('.toclevel-1').parent().css('margin', '7px');
}

}());
//# sourceURL=MobTaxonomy.js