Skip to content

Instantly share code, notes, and snippets.

@Shelob9
Created January 14, 2025 16:56
Show Gist options
  • Save Shelob9/fef02e462a3658903a974f338038c329 to your computer and use it in GitHub Desktop.
Save Shelob9/fef02e462a3658903a974f338038c329 to your computer and use it in GitHub Desktop.
import { useState } from "react";
import useCreateTextImage from "./useCreateTextImage";
function App() {
const [text, setText] = useState<string>('');
const imgRef = useCreateTextImage(text, 'black', 'white', { width: 400, height: 200 });
return (
<>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
/>
<img ref={imgRef} alt={text} />
</>
);
}
export default App
export interface TextImageOptions {
font?: string;
textAlign?: CanvasTextAlign;
width?: number;
height?: number;
}
function createTextImage(
text: string,
textColor: string,
backgroundColor: string | false,
options: TextImageOptions = {}
): HTMLImageElement {
const {
height,
width,
font,
textAlign
} = {
...{
font: '30px Arial',
textAlign:'center',
width: 400,
height:200
},
...options,
}
// Create a canvas element
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
if (!context) {
throw new Error('Failed to get canvas context');
}
// Set canvas dimensions
canvas.width = width;
canvas.height = height;
// Set background color
if (backgroundColor) {
context.fillStyle = backgroundColor;
context.fillRect(0, 0, width, height);
} else {
// Transparent background
context.clearRect(0, 0, width, height);
}
// Set text properties
context.fillStyle = textColor;
context.font = font;
context.textAlign = textAlign as CanvasTextAlign;
context.textBaseline = 'middle';
// Split text by \n and draw each line
const lines = text.split('\n');
const lineHeight = parseInt(font, 10) * 1.2; // Adjust line height as needed
lines.forEach((line, index) => {
context.fillText(line, width / 2, (height / 2) - ((lines.length - 1) * lineHeight / 2) + (index * lineHeight));
});
// Create an image element
const image = new Image();
image.src = canvas.toDataURL('image/png');
return image;
}
export default createTextImage;
import { useEffect,useRef } from "react";
import createTextImage, { TextImageOptions } from "./createTextImage";
export default function useCreateTextImage(
text: string,
textColor: string,
backgroundColor: string | false,
options: TextImageOptions = {}
) {
const imageRef = useRef<HTMLImageElement>(null);
useEffect(() => {
if (imageRef.current) {
const image = createTextImage(text, textColor, backgroundColor, options);
imageRef.current.src = image.src;
}
// Cleanup function to remove image ref
return () => {
if (imageRef.current) {
imageRef.current.src = '';
}
};
}, [text, textColor, backgroundColor, options]);
return imageRef;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment