From 3db61411d78c82618300f694999119bcac5e93dd Mon Sep 17 00:00:00 2001 From: Daniel Odendahl Jr Date: Wed, 12 Sep 2018 02:43:28 +0000 Subject: [PATCH] Character Count, Nike Ad --- README.md | 4 +- assets/images/nike-ad.png | Bin 0 -> 12704 bytes commands/image-edit/nike-ad.js | 71 ++++++++++++++++++++++++ commands/number-edit/character-count.js | 24 ++++++++ package.json | 2 +- util/Canvas.js | 28 ++++++++++ 6 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 assets/images/nike-ad.png create mode 100644 commands/image-edit/nike-ad.js create mode 100644 commands/number-edit/character-count.js diff --git a/README.md b/README.md index a0d3c6de..924166af 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Xiao is a Discord bot coded in JavaScript with The bot is no longer available for invite. You can self-host the bot, or use her on the [home server](https://discord.gg/sbMe32W). -## Commands (304) +## Commands (306) ### Utility: * **eval:** Executes JavaScript code. @@ -244,6 +244,7 @@ on the [home server](https://discord.gg/sbMe32W). * **illegal:** Makes President Trump make your text illegal. * **invert:** Draws an image or a user's avatar but inverted. * **minecraft-skin:** Sends the Minecraft skin for a user. +* **nike-ad:** Sends a "Believe in Something" Nike Ad meme with the text of your choice. * **needs-more-jpeg:** Draws an image or a user's avatar as a low quality JPEG. * **osu-signature:** Creates a card based on an osu! user's stats. * **pixelize:** Draws an image or a user's avatar pixelized. @@ -332,6 +333,7 @@ on the [home server](https://discord.gg/sbMe32W). ### Number Manipulation: +* **character-count:** Responds with the character count of text. * **currency:** Converts money from one currency to another. * **final-grade-calculator:** Determines the grade you need to make on your final to get your desired course grade. * **gravity:** Determines weight on another planet. diff --git a/assets/images/nike-ad.png b/assets/images/nike-ad.png new file mode 100644 index 0000000000000000000000000000000000000000..29311b5b8fbfbce0c094e1e6d5576427f4461c67 GIT binary patch literal 12704 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 something.toLowerCase() + }, + { + key: 'sacrifice', + prompt: 'What should believing result in (e.g. sacrificing everything)?', + type: 'string', + max: 50, + parse: sacrifice => sacrifice.toLowerCase() + }, + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 2048 }) + } + ] + }); + } + + async run(msg, { image, something, sacrifice }) { + try { + const base = await loadImage(path.join(__dirname, '..', '..', 'assets', 'images', 'nike-ad.png')); + const { body } = await request.get(image); + const data = await loadImage(body); + const canvas = createCanvas(data.width, data.height); + const ctx = canvas.getContext('2d'); + drawImageWithTint(ctx, data, 'black', 0, 0, data.width, data.height); + greyscale(ctx, 0, 0, data.width, data.height); + ctx.drawImage(base, data.width / 2 - base.width / 2, base.height - data.height); + ctx.font = `${Math.round(data.height / 25)}px Noto`; + ctx.fillStyle = 'white'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + const text = wrapText(ctx, `Believe in ${something}. Even if it means ${sacrifice}.`, data.width); + ctx.fillText(text.join('\n'), data.width / 2, data.height / 2); + const attachment = canvas.toBuffer(); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'nike-ad.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } +}; diff --git a/commands/number-edit/character-count.js b/commands/number-edit/character-count.js new file mode 100644 index 00000000..45e94519 --- /dev/null +++ b/commands/number-edit/character-count.js @@ -0,0 +1,24 @@ +const Command = require('../../structures/Command'); + +module.exports = class CharacterCountCommand extends Command { + constructor(client) { + super(client, { + name: 'character-count', + aliases: ['characters', 'chars', 'length'], + group: 'number-edit', + memberName: 'character-count', + description: 'Responds with the character count of text.', + args: [ + { + key: 'text', + prompt: 'What text would you like to get the character count of?', + type: 'string' + } + ] + }); + } + + run(msg, { text }) { + return msg.reply(text.length); + } +}; diff --git a/package.json b/package.json index 4169251e..49444016 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "91.0.3", + "version": "91.1.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { diff --git a/util/Canvas.js b/util/Canvas.js index ce33ea3b..3a1ead53 100644 --- a/util/Canvas.js +++ b/util/Canvas.js @@ -95,4 +95,32 @@ module.exports = class CanvasUtil { } return shorten ? `${text}...` : text; } + + static wrapText(ctx, text, maxWidth) { + if (ctx.measureText(text).width < maxWidth) return [text]; + const words = text.split(' '); + const lines = []; + let line = ''; + while (words.length > 0) { + let split = false; + while (ctx.measureText(words[0]).width >= maxWidth) { + const temp = words[0]; + words[0] = temp.slice(0, -1); + if (split) { + words[1] = `${temp.slice(-1)}${words[1]}`; + } else { + split = true; + words.splice(1, 0, temp.slice(-1)); + } + } + if (ctx.measureText(`${line}${words[0]}`).width < maxWidth) { + line += `${words.shift()} `; + } else { + lines.push(line.trim()); + line = ''; + } + if (words.length === 0) lines.push(line.trim()); + } + return lines; + } };