v25.8.5@uwuzu1.6.4
This commit is contained in:
+134
@@ -0,0 +1,134 @@
|
||||
import { createCanvas, loadImage, registerFont } from "canvas";
|
||||
import { writeFileSync } from "fs";
|
||||
import sharp from "sharp";
|
||||
import { MiQOptions } from "./miq";
|
||||
|
||||
function textReplace(
|
||||
text: string
|
||||
) {
|
||||
let result = "";
|
||||
|
||||
// 改行削除
|
||||
text = text.replaceAll("\n", "");
|
||||
|
||||
// 10文字/1回で改行を追加
|
||||
let maxLength = 10;
|
||||
if (text.length > maxLength) {
|
||||
for (let i = 0; i < text.length; i += maxLength) {
|
||||
result += text.substring(i, i + maxLength) + "\n";
|
||||
}
|
||||
result = result.trimEnd();
|
||||
}
|
||||
|
||||
// 80文字以上は「...」で省略
|
||||
maxLength = 80;
|
||||
if (result.length > maxLength) {
|
||||
result = result.substring(0, maxLength)
|
||||
+ "...";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async function iconReplace(
|
||||
color: boolean,
|
||||
iconURL: string,
|
||||
) {
|
||||
let result = "";
|
||||
|
||||
const buffer = await(await fetch(iconURL, {
|
||||
method: "GET",
|
||||
cache: "no-store",
|
||||
})).arrayBuffer();
|
||||
|
||||
if (color) {
|
||||
const img = await sharp(Buffer.from(buffer))
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
result = `data:image/png;base64,${img.toString("base64")}`;
|
||||
} else {
|
||||
const img = await sharp(Buffer.from(buffer))
|
||||
.png()
|
||||
.grayscale()
|
||||
.toBuffer();
|
||||
|
||||
result = `data:image/png;base64,${img.toString("base64")}`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to generate
|
||||
* Make it a quote on Node.js.
|
||||
*/
|
||||
export default async function MiQ({
|
||||
type,
|
||||
color,
|
||||
text,
|
||||
iconURL,
|
||||
userName,
|
||||
userID,
|
||||
}: MiQOptions) {
|
||||
// フォント読み込み
|
||||
registerFont("miq/fonts/NotoSansJP.ttf", { family: "Noto Sans JP" });
|
||||
|
||||
// 初期化
|
||||
const canvas = createCanvas(1200, 630);
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// 背景描画
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// アイコン描画
|
||||
const iconImg = await loadImage(await iconReplace(
|
||||
color,
|
||||
iconURL,
|
||||
));
|
||||
const iconSize = canvas.height;
|
||||
ctx.drawImage(iconImg, 0, 0, iconSize, iconSize);
|
||||
|
||||
// ユーザー名描画
|
||||
ctx.font = "38px Noto Sans JP";
|
||||
ctx.fillStyle = "white";
|
||||
ctx.textAlign = "left";
|
||||
ctx.textBaseline = "middle";
|
||||
let x = 670;
|
||||
let y = 480;
|
||||
ctx.fillText("-", x, y);
|
||||
ctx.fillText(userName, x+40, y, canvas.width-(x+40));
|
||||
|
||||
// ユーザーID描画
|
||||
ctx.font = "28px Noto Sans JP";
|
||||
ctx.fillStyle = "#3c3c3c";
|
||||
ctx.fillText(`@${userID}`, x+120, y+50, canvas.width-(x+120));
|
||||
|
||||
// 本文描画
|
||||
ctx.font = "48px Noto Sans JP";
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillStyle = "white";
|
||||
text = textReplace(text);
|
||||
x = 870;
|
||||
y = 30;
|
||||
ctx.fillText(text, x, y+50);
|
||||
|
||||
// フェード描画
|
||||
const fadeColor = "black";
|
||||
const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
|
||||
gradient.addColorStop(0, "rgba(0, 0, 0, 0)");
|
||||
gradient.addColorStop(0.5, fadeColor);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, iconSize, canvas.height);
|
||||
|
||||
// 返答
|
||||
if (type === "Buffer") {
|
||||
return canvas.toBuffer();
|
||||
} else if (type === "Base64") {
|
||||
return canvas.toDataURL();
|
||||
} else {
|
||||
return "Error: The type property is invalid.";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user