New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

xiv-character-cards

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xiv-character-cards - npm Package Compare versions

Comparing version

to
1.1.0

diskcache/cache_62accb92-7bd2-4c42-8e0b-a50b277fd995_image.bin

457

create-card.js
const fetch = require("node-fetch");
const fs = require("fs");
const path = require("path");
const { createCanvas, loadImage, registerFont } = require("canvas");
registerFont('SourceSansPro-Regular.ttf', { family: 'Source Sans Pro', style: 'Regular' });
registerFont('SourceSansPro-SemiBold.ttf', { family: 'Source Sans Pro', style: 'SemiBold' });
function absolute(relativePath) {
return path.join(__dirname, relativePath);
}
registerFont(absolute('SourceSansPro-Regular.ttf'), { family: 'Source Sans Pro', style: 'Regular' });
registerFont(absolute('SourceSansPro-SemiBold.ttf'), { family: 'Source Sans Pro', style: 'SemiBold' });
const primary = "rgba(178, 214, 249, 1)";

@@ -17,16 +22,60 @@ const white = "rgba(255, 255, 255,1)";

const jobsRowStart = 495;
const jobsRowTextStartX = 495;
const jobsRowTextSize = 30;
const jobsRowTextSpacer = jobsRowTextSize * 2;
const deityIconCol = 252;
const deityIconRow = 805;
const rectHeightRow1 = 120; // Title, Name, World
const rectHeightRow2 = 40; // Mounts, Minions
const rectHeightRow3 = 210; // Info
const rectHeightRow4 = 175; // Jobs
const gcRankIconCol = 293;
const gcRankIconRow = 799;
const rectSpacing = 8;
const rectHalfWidthSpacing = 10;
const rectFullWidth = 400;
const rectHalfWidth = (rectFullWidth / 2) - (rectHalfWidthSpacing / 2);
const rectStartX = 464;
const rectStartXHalf = rectStartX + rectHalfWidth + rectHalfWidthSpacing;
const rectStartRow1Y = 15;
const rectStartRow2Y = rectStartRow1Y + rectHeightRow1 + rectSpacing;
const rectStartRow3Y = rectStartRow2Y + rectHeightRow2 + rectSpacing;
const rectStartRow4Y = rectStartRow3Y + rectHeightRow3 + rectSpacing;
const jobsStartSpacing = 10;
const jobsRowSpacing = 8;
const jobsRowIcon1Y = rectStartRow4Y + jobsStartSpacing;
const jobsRowText1Y = jobsRowIcon1Y + 45;
const jobsRowIcon2Y = jobsRowText1Y + jobsRowSpacing;
const jobsRowText2Y = jobsRowIcon2Y + 45;
const jobsRowIcon3Y = jobsRowText2Y + jobsRowSpacing;
const jobsRowText3Y = jobsRowIcon3Y + 45;
const textTitleY = rectStartRow1Y + 34;
const textServerY = rectStartRow1Y + 104;
const textNameNoTitleY = rectStartRow1Y + 59;
const textNameTitleY = rectStartRow1Y + 79;
const textMountMinionY = rectStartRow2Y + 28;
const iconMountMinionY = rectStartRow2Y + 5;
const deityIconY = rectStartRow3Y + 69;
const deityIconX = 805;
const gcRankIconY = rectStartRow3Y + 110;
const gcRankIconX = 799;
const fcCrestScale = 38;
const fcCrestCol = 345;
const fcCrestRow = 800;
const fcCrestY = rectStartRow3Y + 162;
const fcCrestX = 800;
const infoTextStartSpacing = 22;
const infoTextSmallStartY = rectStartRow3Y + infoTextStartSpacing;
const infoTextBigStartY = infoTextSmallStartY + 25;
const infoTextSpacing = 50;
class CardCreator {

@@ -47,43 +96,45 @@ constructor() {

async init() {
this.bgImage = await loadImage("./chara_n.png");
this.bgImage = await loadImage(absolute("./chara.png"));
this.imgMinion = await loadImage("./minion.png");
this.imgMount = await loadImage("./mount.png");
this.imgMinion = await loadImage(absolute("./minion.png"));
this.imgMount = await loadImage(absolute("./mount.png"));
this.imgIlvl = await loadImage(absolute("./ilvl_n.png"));
this.imgShadow = await loadImage(absolute("./shadow.png"));
this.imgAlchemist = await loadImage("./cj/1/alchemist.png");
this.imgArmorer = await loadImage("./cj/1/armorer.png");
this.imgBlacksmith = await loadImage("./cj/1/blacksmith.png");
this.imgCarpenter = await loadImage("./cj/1/carpenter.png");
this.imgCulinarian = await loadImage("./cj/1/culinarian.png");
this.imgGoldsmith = await loadImage("./cj/1/goldsmith.png");
this.imgLeatherworker = await loadImage("./cj/1/leatherworker.png");
this.imgWeaver = await loadImage("./cj/1/weaver.png");
this.imgAlchemist = await loadImage(absolute("./cj/1/alchemist.png"));
this.imgArmorer = await loadImage(absolute("./cj/1/armorer.png"));
this.imgBlacksmith = await loadImage(absolute("./cj/1/blacksmith.png"));
this.imgCarpenter = await loadImage(absolute("./cj/1/carpenter.png"));
this.imgCulinarian = await loadImage(absolute("./cj/1/culinarian.png"));
this.imgGoldsmith = await loadImage(absolute("./cj/1/goldsmith.png"));
this.imgLeatherworker = await loadImage(absolute("./cj/1/leatherworker.png"));
this.imgWeaver = await loadImage(absolute("./cj/1/weaver.png"));
this.imgBotanist = await loadImage("./cj/1/botanist.png");
this.imgFisher = await loadImage("./cj/1/fisher.png");
this.imgMiner = await loadImage("./cj/1/miner.png");
this.imgBotanist = await loadImage(absolute("./cj/1/botanist.png"));
this.imgFisher = await loadImage(absolute("./cj/1/fisher.png"));
this.imgMiner = await loadImage(absolute("./cj/1/miner.png"));
this.imgPaladin = await loadImage("./cj/1/paladin.png");
this.imgWarrior = await loadImage("./cj/1/warrior.png");
this.imgDarkKnight = await loadImage("./cj/1/darkknight.png");
this.imgGunbreaker = await loadImage("./cj/1/gunbreaker.png");
this.imgPaladin = await loadImage(absolute("./cj/1/paladin.png"));
this.imgWarrior = await loadImage(absolute("./cj/1/warrior.png"));
this.imgDarkKnight = await loadImage(absolute("./cj/1/darkknight.png"));
this.imgGunbreaker = await loadImage(absolute("./cj/1/gunbreaker.png"));
this.imgWhitemage = await loadImage("./cj/1/whitemage.png");
this.imgScholar = await loadImage("./cj/1/scholar.png");
this.imgAstrologian = await loadImage("./cj/1/astrologian.png");
this.imgWhitemage = await loadImage(absolute("./cj/1/whitemage.png"));
this.imgScholar = await loadImage(absolute("./cj/1/scholar.png"));
this.imgAstrologian = await loadImage(absolute("./cj/1/astrologian.png"));
this.imgBard = await loadImage("./cj/1/bard.png");
this.imgMachinist = await loadImage("./cj/1/machinist.png");
this.imgDancer = await loadImage("./cj/1/dancer.png");
this.imgBard = await loadImage(absolute("./cj/1/bard.png"));
this.imgMachinist = await loadImage(absolute("./cj/1/machinist.png"));
this.imgDancer = await loadImage(absolute("./cj/1/dancer.png"));
this.imgDragoon = await loadImage("./cj/1/dragoon.png");
this.imgMonk = await loadImage("./cj/1/monk.png");
this.imgNinja = await loadImage("./cj/1/ninja.png");
this.imgSamurai = await loadImage("./cj/1/samurai.png");
this.imgDragoon = await loadImage(absolute("./cj/1/dragoon.png"));
this.imgMonk = await loadImage(absolute("./cj/1/monk.png"));
this.imgNinja = await loadImage(absolute("./cj/1/ninja.png"));
this.imgSamurai = await loadImage(absolute("./cj/1/samurai.png"));
this.imgBlackmage = await loadImage("./cj/1/blackmage.png");
this.imgSummoner = await loadImage("./cj/1/summoner.png");
this.imgRedmage = await loadImage("./cj/1/redmage.png");
this.imgBlackmage = await loadImage(absolute("./cj/1/blackmage.png"));
this.imgSummoner = await loadImage(absolute("./cj/1/summoner.png"));
this.imgRedmage = await loadImage(absolute("./cj/1/redmage.png"));
this.imgBluemage = await loadImage('./cj/1/bluemage.png');
this.imgBluemage = await loadImage(absolute('./cj/1/bluemage.png'));

@@ -108,15 +159,14 @@ await this.countMountsMinions();

async createCrest(crestAry) {
const canvas = createCanvas(fcCrestScale, fcCrestScale);
const canvas = createCanvas(128, 128);
const ctx = canvas.getContext("2d");
var crestLayer2 = await loadImage(crestAry[0]);
ctx.drawImage(crestLayer2, 0, 0, fcCrestScale, fcCrestScale);
if (crestAry.length == 0)
return null;
var crestLayer1 = await loadImage(crestAry[1]);
ctx.drawImage(crestLayer1, 0, 0, fcCrestScale, fcCrestScale);
for (var i = 0; i < crestAry.length; i++) {
var crestLayer = await loadImage(crestAry[i]);
ctx.drawImage(crestLayer, 0, 0, 128, 128);
}
var crestLayer0 = await loadImage(crestAry[2]);
ctx.drawImage(crestLayer0, 0, 0, fcCrestScale, fcCrestScale);
var imgd = ctx.getImageData(0, 0, 135, 135),
var imgd = ctx.getImageData(0, 0, 128, 128),
pix = imgd.data,

@@ -145,2 +195,41 @@ newColor = { r: 0, g: 0, b: 0, a: 0 };

getItemLevel(gearset) {
var ilvl = 0;
var cnt = 0;
var mainHandLvl = 0;
var hasOffHand = false;
for (var key in gearset) {
var piece = gearset[key];
if (key == 'SoulCrystal')
continue;
if (key == 'MainHand')
mainHandLvl = piece.Item.LevelItem;
if (key == 'OffHand')
hasOffHand = true;
ilvl += piece.Item.LevelItem;
cnt++;
}
if (!hasOffHand) {
ilvl += mainHandLvl;
cnt++;
}
if (cnt == 0)
return 0;
return this.pad(Math.floor(ilvl / cnt), 4);
}
pad(num, size) {
num = num.toString();
while (num.length < size) num = "0" + num;
return num;
}
async createCard(charaId) {

@@ -155,3 +244,3 @@ var response = await fetch(`https://xivapi.com/character/${charaId}?extended=1&data=FC,mimo`);

ctx.drawImage(this.bgImage, 441, 0, 900, 600);
ctx.drawImage(this.bgImage, -10, 0, 900, 600);

@@ -163,16 +252,17 @@ ctx.drawImage(portrait, 0, 0, 441, 600);

ctx.beginPath();
ctx.fillRect(464, 7, 400, 120);
ctx.fillRect(rectStartX, rectStartRow1Y, rectFullWidth, rectHeightRow1);
ctx.fillRect(464, 135, 195, 40);
ctx.fillRect(669, 135, 195, 40);
ctx.fillRect(rectStartX, rectStartRow2Y, rectHalfWidth, rectHeightRow2);
ctx.fillRect(rectStartXHalf, rectStartRow2Y, rectHalfWidth, rectHeightRow2);
ctx.fillRect(464, 183, 400, 210);
ctx.fillRect(464, 405, 400, 175);
ctx.fillRect(rectStartX, rectStartRow3Y, rectFullWidth, rectHeightRow3);
ctx.fillRect(rectStartX, rectStartRow4Y, rectFullWidth, rectHeightRow4);
ctx.stroke();
ctx.textAlign = "center";
ctx.font = med;
ctx.fillStyle = primary;
ctx.fillText(data.Character.Title.Name, 665, 45);
ctx.fillText(data.Character.Title.Name, 665, textTitleY);
ctx.font = small;
ctx.fillText(`${data.Character.Server} (${data.Character.DC})`, 665, 115);
ctx.fillText(`${data.Character.Server} (${data.Character.DC})`, 665, textServerY);

@@ -183,18 +273,28 @@

ctx.textAlign = "left";
ctx.fillText("Race & Clan", 480, 205);
ctx.fillText("Guardian", 480, 255);
ctx.fillText("Race & Clan", 480, infoTextSmallStartY);
ctx.fillText("Guardian", 480, infoTextSmallStartY + infoTextSpacing);
if (data.Character.GrandCompany.Company != null) {
ctx.fillText("Grand Company", 480, 305);
ctx.fillText("Grand Company", 480, infoTextSmallStartY + infoTextSpacing * 2);
}
if (data.Character.FreeCompanyName != null) {
ctx.fillText("Free Company", 480, 355);
ctx.fillText("Free Company", 480, infoTextSmallStartY + infoTextSpacing * 3);
}
ctx.fillStyle = grey;
ctx.font = smed;
var ilvl = this.getItemLevel(data.Character.GearSet.Gear);
ctx.drawImage(this.imgShadow, 441 - 143, -15, 170, 90);
ctx.drawImage(this.imgIlvl, 441 - 92, 12, 24, 27);
ctx.fillText(ilvl, 441 - 65, 35);
ctx.fillStyle = white;
ctx.font = large;
ctx.textAlign = "center";
// Chara Name
if (data.Character.Title.Name == null || data.Character.Title.Name == "") {
ctx.fillText(data.Character.Name, 665, 70);
ctx.fillText(data.Character.Name, 665, textNameNoTitleY);
} else {
ctx.fillText(data.Character.Name, 665, 90);
ctx.fillText(data.Character.Name, 665, textNameTitleY);
}

@@ -204,24 +304,43 @@ // Race, Clan, Guardian, GC, FC Info

ctx.textAlign = "left";
ctx.fillText(`${data.Character.Race.Name}, ${data.Character.Tribe.Name}`, 480, 230);
ctx.fillText(`${data.Character.Race.Name}, ${data.Character.Tribe.Name}`, 480, infoTextBigStartY);
ctx.fillText(data.Character.GuardianDeity.Name, 480, 280);
ctx.fillText(data.Character.GuardianDeity.Name, 480, infoTextBigStartY + infoTextSpacing);
var deityIcon = await loadImage('https://xivapi.com/' + data.Character.GuardianDeity.Icon);
ctx.drawImage(deityIcon, deityIconRow, deityIconCol, 28, 28);
ctx.drawImage(deityIcon, deityIconX, deityIconY, 28, 28);
if (data.Character.GrandCompany.Company != null) {
ctx.fillText(data.Character.GrandCompany.Company.Name, 480, 330);
ctx.fillText(data.Character.GrandCompany.Company.Name, 480, infoTextBigStartY + infoTextSpacing * 2);
var gcRankIcon = await loadImage('https://xivapi.com/' + data.Character.GrandCompany.Rank.Icon);
ctx.drawImage(gcRankIcon, gcRankIconRow, gcRankIconCol, 40, 40);
ctx.drawImage(gcRankIcon, gcRankIconX, gcRankIconY, 40, 40);
}
if (data.Character.FreeCompanyName != null) {
var crestImage = await this.createCrest(data.FreeCompany.Crest);
ctx.drawImage(crestImage, fcCrestRow, fcCrestCol, fcCrestScale, fcCrestScale);
ctx.fillText(data.Character.FreeCompanyName, 480, 380);
if (crestImage !== null)
ctx.drawImage(crestImage, fcCrestX, fcCrestY, fcCrestScale, fcCrestScale);
const fcMeasure = ctx.measureText(data.Character.FreeCompanyName);
ctx.fillText(data.Character.FreeCompanyName, 480, infoTextBigStartY + infoTextSpacing * 3);
ctx.fillStyle = grey;
ctx.font = small;
ctx.fillText(`«${data.FreeCompany.Tag}»`, 480 + fcMeasure.width + 10, infoTextBigStartY + infoTextSpacing * 3);
}
ctx.font = smed;
ctx.fillStyle = white;
// Minion & Mount percentages
const mountsPct = Math.ceil((data.Mounts.length / this.countMount) * 100);
const minionsPct = Math.ceil((data.Minions.length / this.countMinion) * 100);
var mountsPct = '??';
if (data.Mounts !== null) {
mountsPct = Math.ceil((data.Mounts.length / this.countMount) * 100);
}
var minionsPct = '??';
if (data.Minions !== null) {
minionsPct = Math.ceil((data.Minions.length / this.countMinion) * 100);
}

@@ -231,4 +350,4 @@ const mountsMeasure = ctx.measureText(`${mountsPct}%`);

ctx.fillText(`${mountsPct}%`, 480, 163);
ctx.fillText(`${minionsPct}%`, 685, 163);
ctx.fillText(`${mountsPct}%`, 480, textMountMinionY);
ctx.fillText(`${minionsPct}%`, 685, textMountMinionY);

@@ -238,7 +357,7 @@ ctx.fillStyle = grey;

ctx.fillText("Mounts", 480 + mountsMeasure.width + 5, 163);
ctx.fillText("Minions", 685 + minionsMeasure.width + 5, 163);
ctx.fillText("Mounts", 480 + mountsMeasure.width + 5, textMountMinionY);
ctx.fillText("Minions", 685 + minionsMeasure.width + 5, textMountMinionY);
ctx.drawImage(this.imgMount, 620, 140, 32, 32);
ctx.drawImage(this.imgMinion, 834, 140, 19, 32);
ctx.drawImage(this.imgMount, 620, iconMountMinionY, 32, 32);
ctx.drawImage(this.imgMinion, 834, iconMountMinionY, 19, 32);

@@ -252,129 +371,129 @@ ctx.fillStyle = white;

var cJobsRowX = jobsRowStart;
ctx.drawImage(this.imgAlchemist, 480, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[24].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
var cJobsRowTextX = jobsRowTextStartX;
ctx.drawImage(this.imgAlchemist, 480, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[24].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgArmorer, 510, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[20].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgArmorer, 510, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[20].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgBlacksmith, 540, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[19].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgBlacksmith, 540, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[19].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgCarpenter, 570, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[18].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgCarpenter, 570, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[18].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgCulinarian, 600, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[25].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgCulinarian, 600, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[25].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgGoldsmith, 630, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[21].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgGoldsmith, 630, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[21].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgLeatherworker, 660, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[22].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgLeatherworker, 660, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[22].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgWeaver, 690, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[23].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSpacer;
ctx.drawImage(this.imgWeaver, 690, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[23].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSpacer;
// Gathering
ctx.drawImage(this.imgBotanist, 750, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[27].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgBotanist, 750, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[27].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgFisher, 780, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[28].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgFisher, 780, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[28].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgMiner, 810, 520, 30, 30);
ctx.fillText(data.Character.ClassJobs[26].Level, cJobsRowX, 565);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgMiner, 810, jobsRowIcon3Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[26].Level, cJobsRowTextX, jobsRowText3Y);
cJobsRowTextX += jobsRowTextSize;
// Tanks
cJobsRowX = jobsRowStart;
cJobsRowTextX = jobsRowTextStartX;
ctx.drawImage(this.imgPaladin, 480, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[0].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgPaladin, 480, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[0].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgWarrior, 510, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[1].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgWarrior, 510, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[1].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgDarkKnight, 540, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[2].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgDarkKnight, 540, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[2].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgGunbreaker, 570, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[3].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSpacer;
ctx.drawImage(this.imgGunbreaker, 570, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[3].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSpacer;
// Healers
ctx.drawImage(this.imgWhitemage, 630, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[8].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgWhitemage, 630, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[8].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgScholar, 660, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[9].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgScholar, 660, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[9].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgAstrologian, 690, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[10].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSpacer;
ctx.drawImage(this.imgAstrologian, 690, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[10].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSpacer;
// DPS
// Ranged
ctx.drawImage(this.imgBard, 750, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[11].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgBard, 750, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[11].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgMachinist, 780, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[12].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgMachinist, 780, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[12].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgDancer, 810, 415, 30, 30);
ctx.fillText(data.Character.ClassJobs[13].Level, cJobsRowX, 460);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgDancer, 810, jobsRowIcon1Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[13].Level, cJobsRowTextX, jobsRowText1Y);
cJobsRowTextX += jobsRowTextSize;
// Melee
cJobsRowX = jobsRowStart;
cJobsRowTextX = jobsRowTextStartX;
ctx.drawImage(this.imgDragoon, 480, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[5].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgDragoon, 480, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[5].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgMonk, 510, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[4].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgMonk, 510, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[4].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgNinja, 540, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[6].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgNinja, 540, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[6].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgSamurai, 570, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[7].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSpacer;
ctx.drawImage(this.imgSamurai, 570, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[7].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSpacer;
// Caster
ctx.drawImage(this.imgBlackmage, 630, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[14].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgBlackmage, 630, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[14].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgSummoner, 660, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[15].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgSummoner, 660, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[15].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
ctx.drawImage(this.imgRedmage, 690, 465, 30, 30);
ctx.fillText(data.Character.ClassJobs[16].Level, cJobsRowX, 515);
cJobsRowX += jobsRowTextSize;
ctx.drawImage(this.imgRedmage, 690, jobsRowIcon2Y, 30, 30);
ctx.fillText(data.Character.ClassJobs[16].Level, cJobsRowTextX, jobsRowText2Y);
cJobsRowTextX += jobsRowTextSize;
// Limited
ctx.drawImage(this.imgBluemage, 780, 465, 33, 33);
ctx.fillText(data.Character.ClassJobs[17].Level, 796, 515);
ctx.drawImage(this.imgBluemage, 780, jobsRowIcon2Y, 33, 33);
ctx.fillText(data.Character.ClassJobs[17].Level, 796, jobsRowText2Y);

@@ -385,2 +504,2 @@ return canvas.toBuffer();

exports.CardCreator = CardCreator;
exports.CardCreator = CardCreator;
{
"name": "xiv-character-cards",
"version": "1.0.0",
"version": "1.1.0",
"main": "create-card.js",

@@ -5,0 +5,0 @@ "license": "MIT",

Sorry, the diff of this file is not supported yet