Difference between revisions of "MediaWiki:MobTaxonomy.js"
BrianFreud (talk | contribs) m |
BrianFreud (talk | contribs) m |
||
(58 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
/* Create the needed elements to hold the data. */ | /* 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> | ||
<br> | <br> | ||
− | <div id="taxonomyContainer"> | + | <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> | <canvas id="relatedMobs" width="800" height="600"></canvas> | ||
</div>`).before(` | </div>`).before(` | ||
+ | <br> | ||
+ | <br> | ||
<h2 id="notableNPCs" style="display:none;"> | <h2 id="notableNPCs" style="display:none;"> | ||
− | <span id="Notables">Notable NPCs</span> | + | <span id="Notables" class="translatable">Notable Related NPCs</span> |
</h2>`); | </h2>`); | ||
+ | |||
+ | $('#taxonomyGroupA, #taxonomyNote, #Notables').each(function () { | ||
+ | $(this).data('text', $(this).text()); | ||
+ | }); | ||
/* What mob are we dealing with? */ | /* What mob are we dealing with? */ | ||
Line 17: | Line 25: | ||
thisPage = document.location.search; | thisPage = document.location.search; | ||
if (!mobType) { | if (!mobType) { | ||
− | mobType = thisPage.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 27: | 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', | + | o.setFont('arial', 13, '#000', 'c'); |
− | o.setSize( | + | o.setSize(110, 35, 35, 25); |
o.setColor('#3388DD', '#DAA520'); | o.setColor('#3388DD', '#DAA520'); | ||
Line 90: | 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 ( | + | 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, ` | + | 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 104: | Line 117: | ||
o.drawChart('relatedMobs', 'c', true); | o.drawChart('relatedMobs', 'c', true); | ||
− | /* | + | /* Make the canvas draggable */ |
− | + | $('#taxonomyContainer').on({ | |
− | + | mousedown: function(click) { | |
− | + | origX = click.pageX + $(this).scrollLeft(); | |
− | + | $(this).on({ | |
− | if ( | + | 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. */ | /* Build the list of notable NPCs. */ | ||
if (Object.keys(stratics.data.NPCs).length > 0) { | if (Object.keys(stratics.data.NPCs).length > 0) { | ||
let $notables = $('<div style="margin-left:3%;">'); | let $notables = $('<div style="margin-left:3%;">'); | ||
− | for (let | + | let arr = []; |
− | if (stratics.data.NPCs.hasOwnProperty(x | + | 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>'); | ||
} | } | ||
Line 148: | Line 203: | ||
/* Update the table of contents */ | /* Update the table of contents */ | ||
$('.toclevel-2:last span:first').text('1.6'); | $('.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 NPCs</span></a></li>`); | + | $('.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'); | $('.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