Created
April 25, 2026 14:10
-
-
Save ayashiiiyo/48e09cad5d4819e7597e279188b757b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Canvas, loadImage, FontLibrary } from 'skia-canvas' | |
| import fs from 'fs' | |
| async function ensureFile(url, path) { | |
| if (!fs.existsSync(path)) { | |
| const res = await fetch(url) | |
| const buf = Buffer.from(await res.arrayBuffer()) | |
| fs.writeFileSync(path, buf) | |
| } | |
| } | |
| async function generate(pp, name, text) { | |
| if (!fs.existsSync('./font')) fs.mkdirSync('./font') | |
| await ensureFile('https://raw.githubusercontent.com/uploader762/dat2/main/uploads/957068-1777109622178.ttf', './font/Nuninto-SemiBold.ttf') | |
| await ensureFile('https://raw.githubusercontent.com/uploader762/dat1/main/uploads/5206ca-1777112931358.otf', './font/Cooper-black.ttf') | |
| await ensureFile('https://raw.githubusercontent.com/uploader762/dat4/main/uploads/036484-1777108103055.jpg', './bg-fakeigstory.jpg') | |
| FontLibrary.use('Nuninto-SemiBold', ['./font/Nuninto-SemiBold.ttf']) | |
| FontLibrary.use('Cooper-Black', ['./font/Cooper-black.ttf']) | |
| let p = { | |
| t: { x: 126, y: 239 }, | |
| b: { x: 144, y: 359 }, | |
| l: { x: 72, y: 299 }, | |
| r: { x: 191, y: 293 } | |
| } | |
| let left = 120, right = 1196, topY = 428, bottomY = 1549 | |
| let boxX = (left + right) / 2 | |
| let boxY = (topY + bottomY) / 2 | |
| let bg = await loadImage('./bg-fakeigstory.jpg') | |
| let avatar = await loadImage(pp) | |
| let canvas = new Canvas(bg.width, bg.height) | |
| let ctx = canvas.getContext('2d') | |
| ctx.imageSmoothingEnabled = true | |
| ctx.imageSmoothingQuality = 'high' | |
| ctx.drawImage(bg, 0, 0) | |
| let cx = (p.l.x + p.r.x) / 2 + 2 | |
| let cy = (p.t.y + p.b.y) / 2 | |
| let r = (p.r.x - p.l.x) / 2 | |
| let s = Math.min(avatar.width, avatar.height) | |
| let sx = (avatar.width - s) / 2 | |
| let sy = (avatar.height - s) / 2 | |
| ctx.save() | |
| ctx.beginPath() | |
| ctx.arc(cx, cy, r, 0, Math.PI * 2) | |
| ctx.closePath() | |
| ctx.clip() | |
| ctx.drawImage(avatar, sx, sy, s, s, cx - r, cy - r, r * 2, r * 2) | |
| ctx.restore() | |
| ctx.font = 'bold 48px "Nuninto-SemiBold"' | |
| ctx.fillStyle = '#ffffff' | |
| ctx.textBaseline = 'middle' | |
| ctx.textAlign = 'left' | |
| ctx.fillText(name, cx + r + 19, cy) | |
| function wrap(ctx, text, maxW) { | |
| let w = text.split(' '), line = '', lines = [] | |
| for (let i = 0; i < w.length; i++) { | |
| let t = line + w[i] + ' ' | |
| if (ctx.measureText(t).width > maxW && i > 0) { | |
| lines.push(line) | |
| line = w[i] + ' ' | |
| } else line = t | |
| } | |
| lines.push(line) | |
| return lines | |
| } | |
| function autoText(ctx, text) { | |
| let maxW = right - left | |
| let maxH = bottomY - topY | |
| let fsz = 74, lines, lh, th | |
| do { | |
| ctx.font = `bold ${fsz}px "Cooper-Black"` | |
| lines = wrap(ctx, text, maxW) | |
| lh = fsz * 1.1 | |
| th = lines.length * lh | |
| fsz -= 2 | |
| } while ((th > maxH || Math.max(...lines.map(l => ctx.measureText(l).width)) > maxW) && fsz > 20) | |
| ctx.font = `bold ${fsz}px "Cooper-Black"` | |
| ctx.fillStyle = '#ffffff' | |
| ctx.textAlign = 'center' | |
| ctx.textBaseline = 'middle' | |
| let startY = boxY - (lines.length * lh / 2) + (lh / 2) | |
| lines.forEach((l, i) => ctx.fillText(l, boxX, startY + (i * lh))) | |
| } | |
| autoText(ctx, text) | |
| return await canvas.toBuffer('png') | |
| } | |
| let handler = async (m, { conn, args, command }) => { | |
| try { | |
| if (!args[0]) return m.reply(`Example : .${command} Halo Dunia`) | |
| m.reply(global.wait) | |
| let pp = await conn.profilePictureUrl(m.sender, 'image').catch(_ => 'https://raw.githubusercontent.com/uploader762/dat4/main/uploads/e0f993-1777126212302.jpg') | |
| let res = await generate(pp, m.pushName || 'User', args.join(' ')) | |
| await conn.sendMessage(m.chat, { image: res }, { quoted: m }) | |
| } catch (e) { | |
| m.reply(e.message) | |
| } | |
| } | |
| handler.help = ['igstory <text>'] | |
| handler.command = ['igstory'] | |
| handler.tags = ['maker'] | |
| export default handler |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment