Nethria Text Based Mini Game Frame
February 8, 2024 ยท View on GitHub
import { Request, Response } from "express"; import { createCanvas } from "canvas"; import GifEncoder from "gifencoder";
export async function generateImage(label: string): Promise
function wrapText( context: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number ): { lastX: number; lastY: number } { const lines = text.split("\n"); let lastY = y; let lastX = x;
lines.forEach((lineText, index) => {
const isLastLine = index === lines.length - 1;
let line = "";
if (lineText.trim().length === 0) {
if (!isLastLine) {
// Only increment Y for non-empty lines except the last
lastY += lineHeight;
}
return;
}
const words = lineText.split(" ");
words.forEach((word, n) => {
const testLine = line + word + " ";
const metrics = context.measureText(testLine);
const testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, lastY);
line = word + " ";
lastY += lineHeight;
lastX = x;
} else {
line = testLine;
lastX = x + testWidth;
}
});
context.fillText(line, x, lastY);
if (!isLastLine) {
lastY += lineHeight;
}
});
return { lastX, lastY };
}
return new Promise((resolve) => { function getCtx(cursorOn?: boolean): CanvasRenderingContext2D { ctx.fillStyle = "#2d2d2d"; ctx.fillRect(0, 0, width, height); ctx.font = "bold 28px Courier New"; ctx.fillStyle = "#03A062";
const maxWidth = width - 40;
const lineHeight = 34;
const x = 20;
const y = 50;
const { lastX, lastY } = wrapText(
ctx as any,
label,
x,
y,
maxWidth,
lineHeight
);
ctx.fillStyle = "#03A062";
const rectHeight = 30;
const rectWidth = 12;
if (cursorOn) {
ctx.fillRect(lastX, lastY - rectHeight + 3, rectWidth, rectHeight);
}
return ctx as any;
}
getCtx(true);
resolve(canvas.toBuffer());
// const encoder = new GifEncoder(width, height);
// const stream = encoder.createReadStream();
// const d: Buffer[] = [];
// stream.on("data", (data: Buffer) => {
// d.push(data);
// });
// stream.on("end", () => {
// resolve(Buffer.concat(d));
// });
// encoder.start();
// encoder.setRepeat(0);
// encoder.setDelay(500);
// encoder.setQuality(1);
// encoder.addFrame(getCtx() as any);
// encoder.addFrame(getCtx(true) as any);
// encoder.finish();
}); }
export async function nethriaFrameIndex(req: Request, res: Response) {
const image = await generateImage(
"Alert: Nethria, the rogue AI, has breached our defenses! Your mission: infiltrate her network and halt her advance before it's too late"
);
const base64 = data:image/gif;base64,${image.toString("base64")};
res.setHeader("Content-Type", "text/html");
res.status(200).send( <!DOCTYPE html> <html> <head> <meta property="og:title" content="Nethria Mini Game"> <meta property="og:image" content="${base64}"> <meta name="fc:frame" content="vNext"> <meta property="fc:frame:image" content="${base64}" /> <meta property="fc:frame:post_url" content="https://${req.host}/synthia/nethria?start=t"> <meta name="fc:frame:button:1" content="โ
Start"> </head> </html>);
}