Fix multi-line breaks in a few commands

This commit is contained in:
Dragon Fire
2024-05-03 10:46:51 -04:00
parent 30c098916b
commit 7916e61bdc
4 changed files with 36 additions and 10 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
const Command = require('../../framework/Command'); const Command = require('../../framework/Command');
const { createCanvas } = require('@napi-rs/canvas'); const { createCanvas } = require('@napi-rs/canvas');
const { wrapText, fillTextWithBreaks } = require('../../util/Canvas'); const { wrapText, fillTextWithBreaks, measureTextHeightWithBreaks } = require('../../util/Canvas');
module.exports = class FontCommand extends Command { module.exports = class FontCommand extends Command {
constructor(client) { constructor(client) {
@@ -38,7 +38,7 @@ module.exports = class FontCommand extends Command {
ctxPre.font = this.client.fonts.get(font.filename).toCanvasString(50); ctxPre.font = this.client.fonts.get(font.filename).toCanvasString(50);
const len = ctxPre.measureText(text); const len = ctxPre.measureText(text);
const lines = wrapText(ctxPre, text, 950); const lines = wrapText(ctxPre, text, 950);
const height = len.emHeightAscent + len.emHeightDescent; const height = measureTextHeightWithBreaks(ctx, text);
const canvas = createCanvas(Math.min(len.width + 50, 1000), 50 + height); const canvas = createCanvas(Math.min(len.width + 50, 1000), 50 + height);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.font = this.client.fonts.get(font.filename).toCanvasString(50); ctx.font = this.client.fonts.get(font.filename).toCanvasString(50);
@@ -2,7 +2,7 @@ const Command = require('../../framework/Command');
const { PermissionFlagsBits } = require('discord.js'); const { PermissionFlagsBits } = require('discord.js');
const { createCanvas, loadImage } = require('@napi-rs/canvas'); const { createCanvas, loadImage } = require('@napi-rs/canvas');
const path = require('path'); const path = require('path');
const { wrapText } = require('../../util/Canvas'); const { wrapText, measureTextHeightWithBreaks } = require('../../util/Canvas');
module.exports = class SpongebobTimeCardCommand extends Command { module.exports = class SpongebobTimeCardCommand extends Command {
constructor(client) { constructor(client) {
@@ -71,7 +71,8 @@ module.exports = class SpongebobTimeCardCommand extends Command {
ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize); ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize);
let lines = wrapText(ctx, text.toUpperCase(), 1800); let lines = wrapText(ctx, text.toUpperCase(), 1800);
let metrics = ctx.measureText(lines.join('\n')); let metrics = ctx.measureText(lines.join('\n'));
while (metrics.width > 1800 || (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent) > 1000) { let heightMetric = measureTextHeightWithBreaks(ctx, lines.join('\n'));
while (metrics.width > 1800 || heightMetric > 1000) {
fontSize -= 10; fontSize -= 10;
ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize); ctx.font = this.client.fonts.get('Spongeboytt1.ttf').toCanvasString(fontSize);
metrics = ctx.measureText(lines.join('\n')); metrics = ctx.measureText(lines.join('\n'));
+14 -4
View File
@@ -10,7 +10,7 @@ const request = require('node-superfetch');
const { readFile } = require('fs/promises'); const { readFile } = require('fs/promises');
const path = require('path'); const path = require('path');
const { formatNumberK, randomRange } = require('../../util/Util'); const { formatNumberK, randomRange } = require('../../util/Util');
const { wrapText, fillTextWithBreaks } = require('../../util/Canvas'); const { wrapText, fillTextWithBreaks, measureTextHeightWithBreaks } = require('../../util/Canvas');
module.exports = class TweetCommand extends Command { module.exports = class TweetCommand extends Command {
constructor(client) { constructor(client) {
@@ -68,8 +68,8 @@ module.exports = class TweetCommand extends Command {
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.font = this.client.fonts.get('ChirpRegular.ttf').toCanvasString(23); ctx.font = this.client.fonts.get('ChirpRegular.ttf').toCanvasString(23);
const lines = wrapText(ctx, text, 710, true); const lines = wrapText(ctx, text, 710, true);
const metrics = ctx.measureText(lines.join('\n')); const metrics = measureTextHeightWithBreaks(ctx, lines.join('\n'), true);
const linesLen = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + 15; const linesLen = metrics + 15;
canvas.height += linesLen; canvas.height += linesLen;
let imageHeight = 0; let imageHeight = 0;
ctx.fillStyle = 'black'; ctx.fillStyle = 'black';
@@ -224,13 +224,18 @@ module.exports = class TweetCommand extends Command {
const wrapped = wrapText(ctx, text, maxLineLen, true); const wrapped = wrapText(ctx, text, maxLineLen, true);
const emoji = text.match(emojiRegex()); const emoji = text.match(emojiRegex());
if (!emoji) { if (!emoji) {
fillTextWithBreaks(ctx, wrapped.join('\n'), x, y); fillTextWithBreaks(ctx, wrapped.join('\n'), x, y, true);
this.fillHashtags(ctx, wrapped, x, y, emojiSize); this.fillHashtags(ctx, wrapped, x, y, emojiSize);
return ctx; return ctx;
} }
let currentY = y; let currentY = y;
for (let currentLine = 0; currentLine < wrapped.length; currentLine++) { for (let currentLine = 0; currentLine < wrapped.length; currentLine++) {
const line = wrapped[currentLine]; const line = wrapped[currentLine];
if (line === '') {
const metrics = ctx.measureText('a');
currentY += metrics.emHeightAscent + metrics.emHeightDescent;
continue;
}
const lineEmoji = line.match(emojiRegex()); const lineEmoji = line.match(emojiRegex());
let currentX = x; let currentX = x;
const metrics = ctx.measureText(line); const metrics = ctx.measureText(line);
@@ -262,6 +267,11 @@ module.exports = class TweetCommand extends Command {
fillHashtags(ctx, wrappedText, x, y, emojiSize) { fillHashtags(ctx, wrappedText, x, y, emojiSize) {
let currentY = y; let currentY = y;
for (const line of wrappedText) { for (const line of wrappedText) {
if (line === '') {
const metrics = ctx.measureText('a');
currentY += metrics.emHeightAscent + metrics.emHeightDescent;
continue;
}
const words = line.split(' '); const words = line.split(' ');
for (let i = 0; i < words.length; i++) { for (let i = 0; i < words.length; i++) {
const word = words[i]; const word = words[i];
+17 -2
View File
@@ -197,11 +197,11 @@ module.exports = class CanvasUtil {
return ctx; return ctx;
} }
static fillTextWithBreaks(ctx, text, x, y, maxLen) { static fillTextWithBreaks(ctx, text, x, y, maxLen, drawMultiBreaks = false) {
const lines = text.split('\n'); const lines = text.split('\n');
let currentY = y; let currentY = y;
for (const line of lines) { for (const line of lines) {
if (line === '') { if (line === '' && drawMultiBreaks) {
const metrics = ctx.measureText('a'); const metrics = ctx.measureText('a');
currentY += metrics.emHeightAscent + metrics.emHeightDescent; currentY += metrics.emHeightAscent + metrics.emHeightDescent;
} else { } else {
@@ -213,6 +213,21 @@ module.exports = class CanvasUtil {
return ctx; return ctx;
} }
measureTextHeightWithBreaks(ctx, text, parseMultiBreaks = false) {
const lines = text.split('\n');
let result = 0;
for (const line of lines) {
if (line === '' && parseMultiBreaks) {
const metrics = ctx.measureText('a');
result += metrics.emHeightAscent + metrics.emHeightDescent;
} else {
const metrics = ctx.measureText(line);
result += metrics.emHeightAscent + metrics.emHeightDescent;
}
}
return result;
}
static shortenText(ctx, text, maxWidth) { static shortenText(ctx, text, maxWidth) {
let shorten = false; let shorten = false;
while (ctx.measureText(`${text}...`).width > maxWidth) { while (ctx.measureText(`${text}...`).width > maxWidth) {