mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-24 07:28:11 +02:00
feat: Introduce EmojiRenderer service for canvas, enabling text rendering with Twemoji emojis, caching, and wrapping.
This commit is contained in:
1 parent
6be8bbf628
commit
ba618bfe79
2 files changed
+20
-7
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -1,5 +1,6 @@
|
|||||||
import { parse } from 'twemoji-parser';
|
import { parse } from 'twemoji-parser';
|
||||||
import { createCanvas, loadImage, CanvasRenderingContext2D } from 'canvas';
|
import { createCanvas, loadImage, CanvasRenderingContext2D } from 'canvas';
|
||||||
|
import sharp from 'sharp';
|
||||||
|
|
||||||
interface EmojiSegment {
|
interface EmojiSegment {
|
||||||
type: 'text' | 'emoji';
|
type: 'text' | 'emoji';
|
||||||
@@ -59,15 +60,27 @@ export class EmojiRenderer {
|
|||||||
/**
|
/**
|
||||||
* Download and cache emoji image
|
* Download and cache emoji image
|
||||||
*/
|
*/
|
||||||
private async getEmojiImage(url: string): Promise<Buffer> {
|
async getEmojiImage(url: string): Promise<Buffer> {
|
||||||
if (this.emojiCache.has(url)) {
|
if (this.emojiCache.has(url)) {
|
||||||
return this.emojiCache.get(url)!;
|
return this.emojiCache.get(url)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url);
|
try {
|
||||||
const buffer = Buffer.from(await response.arrayBuffer());
|
const response = await fetch(url);
|
||||||
this.emojiCache.set(url, buffer);
|
if (!response.ok) {
|
||||||
return buffer;
|
throw new Error(`Failed to fetch emoji: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
const buffer = Buffer.from(await response.arrayBuffer());
|
||||||
|
|
||||||
|
// Convert SVG to PNG using sharp because node-canvas struggles with SVGs lacking dimensions
|
||||||
|
const pngBuffer = await sharp(buffer).png().toBuffer();
|
||||||
|
|
||||||
|
this.emojiCache.set(url, pngBuffer);
|
||||||
|
return pngBuffer;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error downloading emoji from ${url}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,11 +123,11 @@ export class EmojiRenderer {
|
|||||||
try {
|
try {
|
||||||
const emojiBuffer = await this.getEmojiImage(segment.url);
|
const emojiBuffer = await this.getEmojiImage(segment.url);
|
||||||
const emojiImage = await loadImage(emojiBuffer);
|
const emojiImage = await loadImage(emojiBuffer);
|
||||||
|
|
||||||
// Draw emoji slightly above baseline to align with text
|
// Draw emoji slightly above baseline to align with text
|
||||||
const emojiSize = fontSize;
|
const emojiSize = fontSize;
|
||||||
const emojiY = y - fontSize * 0.8; // Adjust vertical position
|
const emojiY = y - fontSize * 0.8; // Adjust vertical position
|
||||||
|
|
||||||
ctx.drawImage(emojiImage, currentX, emojiY, emojiSize, emojiSize);
|
ctx.drawImage(emojiImage, currentX, emojiY, emojiSize, emojiSize);
|
||||||
currentX += emojiSize;
|
currentX += emojiSize;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in new issue
Block a user