,l

 

import React, { useState } from "react"; // 1. Helferfunktion: Generiert einen sauberen, URL-sicheren Dateinamen function generateFileName(text) { const clean = text.replace(/[^a-zA-Z0-9äöüÄÖÜß ]/g, "").trim(); return clean.substring(0, 50).replace(/\s+/g, "_") || "headline_image"; } // 2. Helferfunktion: Erstellt das Canvas und zeichnet den zentrierten Text function createImage(title) { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); // Quadratisches High-Res Format für Social Media / Web canvas.width = 1024; canvas.height = 1024; // Hintergrund: Moderner, edler Dunkelgrau-Verlauf const gradient = ctx.createLinearGradient(0, 0, 1024, 1024); gradient.addColorStop(0, "#1f2937"); // Tailwind gray-800 gradient.addColorStop(1, "#111827"); // Tailwind gray-900 ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); // Text-Einstellungen ctx.fillStyle = "#ffffff"; ctx.font = "bold 56px system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; // Text-Umbruch-Logik (bricht bei maximal 850 Pixeln Breite um) const words = title.split(" "); let lines = []; let line = ""; const maxWidth = 850; words.forEach((word) => { const testLine = line + word + " "; if (ctx.measureText(testLine).width > maxWidth) { lines.push(line.trim()); line = word + " "; } else { line = testLine; } }); lines.push(line.trim()); // Mathematisch exakte vertikale Zentrierung des gesamten Textblocks const lineHeight = 75; const totalHeight = lines.length * lineHeight; let startY = (canvas.height - totalHeight) / 2 + lineHeight / 2; lines.forEach((l, i) => { ctx.fillText(l, canvas.width / 2, startY + i * lineHeight); }); return canvas.toDataURL("image/png"); } // Hauptkomponente export default function HeadlineImageGenerator() { const [input, setInput] = useState(""); const [images, setImages] = useState([]); // Verarbeitet die Zeilen und generiert die Bilder const handleGenerate = () => { const titles = input .split("\n") .map((t) => t.trim()) .filter(Boolean); if (titles.length === 0) return; const generated = titles.map((title) => ({ title, fileName: generateFileName(title), image: createImage(title), })); setImages(generated); }; // Sicherer Download-Trigger für alle Browser const downloadImage = (img, name) => { const link = document.createElement("a"); link.href = img; link.download = `${name}.png`; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; // Massen-Download mit kleiner Verzögerung gegen Browser-Sperren const downloadAll = () => { images.forEach((item, i) => { setTimeout(() => { downloadImage(item.image, item.fileName); }, i * 350); }); }; return (
{/* EINGABE-BOX */}

Überschrift → Bild Generator

Gib pro Zeile eine Überschrift ein. Jede Zeile erzeugt automatisch ein eigenes Bild.