diff --git a/.eslintrc.yml b/.eslintrc.yml index 218f9f6..0eae871 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,9 +1,12 @@ extends: "@wfcd/eslint-config/typescript" parser: "@typescript-eslint/parser" parserOptions: - project: "." + project: "./tsconfig.json" babelOptions: plugins: - "@typescript-eslint/eslint-plugin" - "@babel/plugin-transform-class-properties" - - "@babel/plugin-transform-private-methods" \ No newline at end of file + - "@babel/plugin-transform-private-methods" +rules: + # conflicts w/ prettier, should probably upstream this + '@typescript-eslint/comma-dangle': 'off' \ No newline at end of file diff --git a/src/drawers.ts b/src/drawers.ts index 024bef5..c58e6d5 100644 --- a/src/drawers.ts +++ b/src/drawers.ts @@ -1,4 +1,5 @@ import { CanvasRenderingContext2D, createCanvas, loadImage } from 'canvas'; + import { flip, getBackground, getFrame, wrapText } from './utils.js'; const drawCommonFrame = async (tier: string, width: number, height: number) => { @@ -11,7 +12,7 @@ const drawCommonFrame = async (tier: string, width: number, height: number) => { // side lights context.drawImage(frame.sideLights, 238, 120); - let flipped = await flip(frame.sideLights, 16, 256); + const flipped = flip(frame.sideLights, 16, 256); context.drawImage(await loadImage(flipped), 2, 120); return { context, frame, canvas }; }; @@ -21,7 +22,7 @@ export const drawLegendaryFrame = async (tier: string, width: number, height: nu // corner lights context.drawImage(frame.cornerLights, 200, 380); - const flipped = await flip(frame.cornerLights, 64, 64); + const flipped = flip(frame.cornerLights, 64, 64); context.drawImage(await loadImage(flipped), -5, 380); return canvas.toBuffer(); @@ -32,7 +33,7 @@ export const drawFrame = async (tier: string, width: number, height: number): Pr // corner lights context.drawImage(frame.cornerLights, 200, 375); - const flipped = await flip(frame.cornerLights, 16, 256); + const flipped = flip(frame.cornerLights, 16, 256); context.drawImage(await loadImage(flipped), -5, 375); return canvas.toBuffer(); @@ -46,24 +47,6 @@ export interface DrawBackground { compatName: string | undefined; } -export const drawBackground = async (toDraw: DrawBackground, width: number, height: number): Promise => { - const canvas = createCanvas(width, height); - const context = canvas.getContext('2d'); - const surface = await getBackground(toDraw.tier); - - context.drawImage(surface.background, 0, 0); - context.drawImage(surface.lowerTab, 23, 390); - if (toDraw.thumbnail) { - const thumb = `https://cdn.warframestat.us/img/${toDraw.thumbnail}`; - context.drawImage(await loadImage(thumb), 10, 90, 239, 200); - } - - context.drawImage(surface.backer, 205, 95); - drawText(context, toDraw.name, toDraw.description, toDraw.compatName); - - return canvas.toBuffer(); -}; - export const drawText = ( context: CanvasRenderingContext2D, name: string, @@ -81,15 +64,15 @@ export const drawText = ( context.font = '12px Arial'; if (description) { let start = 335; - let lines = description.split('\n'); + const lines = description.split('\n'); - for (const line of lines) { + lines.forEach((line) => { const texts = wrapText(context, line, 230); - for (const text of texts) { + texts.forEach((text) => { context.fillText(text, x, start); start += 20; - } - } + }); + }); } if (compatName) { @@ -97,3 +80,21 @@ export const drawText = ( context.fillText(compatName, 125, 404); } }; + +export const drawBackground = async (toDraw: DrawBackground, width: number, height: number): Promise => { + const canvas = createCanvas(width, height); + const context = canvas.getContext('2d'); + const surface = await getBackground(toDraw.tier); + + context.drawImage(surface.background, 0, 0); + context.drawImage(surface.lowerTab, 23, 390); + if (toDraw.thumbnail) { + const thumb = `https://cdn.warframestat.us/img/${toDraw.thumbnail}`; + context.drawImage(await loadImage(thumb), 10, 90, 239, 200); + } + + context.drawImage(surface.backer, 205, 95); + drawText(context, toDraw.name, toDraw.description, toDraw.compatName); + + return canvas.toBuffer(); +}; diff --git a/src/generator.ts b/src/generator.ts index 7318a12..ae4b04b 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -1,5 +1,6 @@ import { createCanvas, loadImage } from 'canvas'; import { Mod, RivenMod } from 'warframe-items'; + import { drawBackground, drawFrame, drawLegendaryFrame } from './drawers.js'; import { flip, getBackground, getFrame, modDescription, modRarityMap } from './utils.js'; @@ -40,8 +41,8 @@ export const generateBasicMod = async (mod: Mod, rank: number): Promise export const generateRivenMod = async (riven: RivenMod): Promise => { const canvas = createCanvas(282, 512); - const context = canvas.getContext('2d')!; - const tier = modRarityMap['riven']; + const context = canvas.getContext('2d'); + const tier = modRarityMap.riven; const magicCenter = 12; @@ -71,12 +72,12 @@ export const generateRivenMod = async (riven: RivenMod): Promise => { context.drawImage(frame.top, magicCenter - 10, 70); context.drawImage(frame.sideLights, 249, 120); - let flipped = await flip(frame.sideLights, 16 + magicCenter, 256); + let flipped = flip(frame.sideLights, 16 + magicCenter, 256); context.drawImage(await loadImage(flipped), 2, 120); context.drawImage(frame.bottom, 8 - magicCenter, 340); context.drawImage(frame.cornerLights, 205 + magicCenter, 380); - flipped = await flip(frame.cornerLights, 64, 64); + flipped = flip(frame.cornerLights, 64, 64); context.drawImage(await loadImage(flipped), 0, 380); return canvas.toBuffer(); diff --git a/src/utils.ts b/src/utils.ts index b8c3bd4..41134b8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,6 @@ -import { CanvasRenderingContext2D, createCanvas, Image, loadImage } from 'canvas'; import * as path from 'path'; + +import { CanvasRenderingContext2D, createCanvas, Image, loadImage } from 'canvas'; import { LevelStat } from 'warframe-items'; const assetPath = path.join('.', 'assets', 'modFrames'); @@ -16,9 +17,9 @@ export const modRarityMap: RarityType = { riven: 'Omega', }; -export const flip = async (frame: Image, width: number, height: number): Promise => { +export const flip = (frame: Image, width: number, height: number): Buffer => { const canvas = createCanvas(width, height); - const context = canvas.getContext('2d')!; + const context = canvas.getContext('2d'); context.translate(width, 0); context.scale(-1, 1); @@ -55,11 +56,11 @@ export const getBackground = async (tier: string): Promise => { const isRiven = tier === 'Omega'; const background = isRiven - ? path.join(assetPath, `LegendaryBackground.png`) + ? path.join(assetPath, 'LegendaryBackground.png') : path.join(assetPath, `${tier}Background.png`); const backer = isRiven - ? path.join(assetPath, `RivenTopRightBacker.png`) + ? path.join(assetPath, 'RivenTopRightBacker.png') : path.join(assetPath, `${tier}TopRightBacker.png`); const lowerTab = isRiven ? path.join(assetPath, 'RivenLowerTab.png') : path.join(assetPath, `${tier}LowerTab.png`); @@ -79,10 +80,10 @@ export const modDescription = ( if (description && description.length !== 0) return description; if (levelStats) { - const stats = levelStats[rank].stats; + const { stats } = levelStats[rank]; let desc = ''; - for (let i = 0; i < stats.length; i++) { + for (let i = 0; i < stats.length; i += 1) { desc = desc.concat(`${stats[i]} \n`); } @@ -95,8 +96,8 @@ export const wrapText = (context: CanvasRenderingContext2D, text: string, maxWid let currentLine = ''; const lines = []; - for (const word of words) { - const testLine = currentLine + ' ' + word; + words.forEach((word) => { + const testLine = `${currentLine} ${word}`; const testLineWidth = context.measureText(testLine).width; if (testLineWidth > maxWidth) { @@ -105,7 +106,7 @@ export const wrapText = (context: CanvasRenderingContext2D, text: string, maxWid } else { currentLine = testLine; } - } + }); lines.push(currentLine); return lines; diff --git a/tests/generator.spec.ts b/tests/generator.spec.ts index c5ede75..164e26b 100644 --- a/tests/generator.spec.ts +++ b/tests/generator.spec.ts @@ -1,36 +1,33 @@ -import { writeFileSync, readdirSync } from "node:fs"; -import { describe, test } from "mocha"; -import { join } from "node:path"; -import { RivenMod, Mod } from "warframe-items"; -import { find } from "warframe-items/utilities"; -import { generateBasicMod, generateRivenMod } from "../src/generator.js"; -import * as assert from "node:assert"; +import { writeFileSync, readdirSync } from 'node:fs'; +import { join } from 'node:path'; +import * as assert from 'node:assert'; -describe("Generate a mod", () => { - test("run test", async () => { +import { describe, test } from 'mocha'; +import { RivenMod, Mod } from 'warframe-items'; +import { find } from 'warframe-items/utilities'; + +import { generateBasicMod, generateRivenMod } from '../src/generator.js'; + +describe('Generate a mod', () => { + test('run test', async () => { const mods = [ - "/Lotus/Upgrades/Mods/Warframe/Kahl/KahlAvatarAbilityStrengthMod", - "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityEfficiencyMod", - "/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod", - "/Lotus/Upgrades/Mods/Aura/PlayerMeleeAuraMod", - "/Lotus/Upgrades/Mods/Randomized/LotusArchgunRandomModRare", + '/Lotus/Upgrades/Mods/Warframe/Kahl/KahlAvatarAbilityStrengthMod', + '/Lotus/Upgrades/Mods/Warframe/AvatarAbilityEfficiencyMod', + '/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod', + '/Lotus/Upgrades/Mods/Aura/PlayerMeleeAuraMod', + '/Lotus/Upgrades/Mods/Randomized/LotusArchgunRandomModRare', ]; - for (let i = 0; i < mods.length; i++) { + for (let i = 0; i < mods.length; i += 1) { const mod = find.findItem(mods[i]); if (!mod) continue; - const isRiven = mod.name?.includes("Riven"); - const modCanvas = isRiven - ? await generateRivenMod(mod as RivenMod) - : await generateBasicMod(mod as Mod, 1); - if (!modCanvas) console.log("failed"); + const isRiven = mod.name?.includes('Riven'); + const modCanvas = isRiven ? await generateRivenMod(mod as RivenMod) : await generateBasicMod(mod as Mod, 1); + if (!modCanvas) assert.equal(true, false, 'Failed to generate mod'); - writeFileSync( - join(".", "assets/tests", `${mod.name}.png`), - modCanvas, - ); + writeFileSync(join('.', 'assets/tests', `${mod.name}.png`), modCanvas); } - const testFiles = readdirSync(join(".", "assets/tests")); + const testFiles = readdirSync(join('.', 'assets/tests')); assert.equal(testFiles.length, mods.length); }); });