🔍 About This Code Showcase
This curated code demonstration showcases how the Coloring Book Generator creates printable PDF coloring books using advanced AI technology and modern React architecture.
Full deployment configurations, API keys, and proprietary details are omitted for security. This showcase highlights the core creative generation algorithms and PDF compilation systems.
📚 Core Algorithm: Creative Book Generation Engine
The foundation of the Coloring Book Generator is its intelligent theme interpretation and sequential page creation system that transforms any concept into complete, printable coloring books:
import React, { useState, useCallback }
from 'react';
import { Page, AgeGroup, DrawingStyle }
from './types';
import { AGE_GROUPS, DRAWING_STYLES }
from './constants';
import { generatePageIdeas, generateImage }
from './services/geminiService';
import { generatePdf }
from './services/pdfService';
function App() {
const [theme, setTheme] = useState
('Sea animals adventure');
const [ageGroup, setAgeGroup] = useState(AGE_GROUPS[0]);
const [style, setStyle] = useState(DRAWING_STYLES[0]);
const [pages, setPages] = useState([]);
const [pageIdeas, setPageIdeas] = useState([]);
const [currentPageIndex, setCurrentPageIndex] = useState(0);
const generateSinglePage = useCallback(async (idea: string, id: string) => {
const base64Image = await generateImage(idea, ageGroup.prompt, style.prompt);
const generatedPage: Page = {
id: id,
title: idea,
imageData: base64Image,
};
setPages([generatedPage]);
}, [ageGroup, style]);
const handleGenerate = useCallback(async () => {
if (!theme) {
setError('Please enter a theme.');
return;
}
setIsLoading(true);
setError(null);
setPages([]);
setPageIdeas([]);
try {
const ideas = await generatePageIdeas(theme);
setPageIdeas(ideas);
setCurrentPageIndex(0);
if (ideas.length > 0) {
await generateSinglePage(ideas[0], `page-0`);
} else {
throw new Error("No ideas were generated for this theme.");
}
} catch (err) {
console.error(err);
setError('Failed to generate coloring page. Please try again.');
} finally {
setIsLoading(false);
}
}, [theme, generateSinglePage]);
const handleGenerateNext = useCallback(async () => {
if (isLoading || currentPageIndex >= pageIdeas.length - 1) {
return;
}
setIsLoading(true);
setError(null);
const nextIndex = currentPageIndex + 1;
try {
await generateSinglePage(pageIdeas[nextIndex], `page-${nextIndex}`);
setCurrentPageIndex(nextIndex);
} catch (err) {
console.error(err);
setError('Failed to generate next page. Please try again.');
} finally {
setIsLoading(false);
}
}, [isLoading, currentPageIndex, pageIdeas, generateSinglePage]);
const handleDownloadPdf = async () => {
if (pages.length === 0) return;
setIsLoading(true);
setError(null);
try {
await generatePdf(pages, theme);
} catch (err) {
console.error('PDF Generation Error:', err);
setError('Could not generate PDF. Please try again.');
} finally {
setIsLoading(false);
}
};
return (
"flex flex-col min-h-screen font-sans text-slate-800">
"flex-grow container mx-auto p-4 md:p-8">
"grid grid-cols-1 lg:grid-cols-12 gap-8">
"lg:col-span-4">
0}
/>
"lg:col-span-8">
0 && currentPageIndex < pageIdeas.length - 1}
/>
{pages.length >
0 && (
"print-container" className=
"hidden">
{pages.map((page) => (
"bg-white p-[20mm] w-[210mm] h-[297mm]">
"text-lg font-semibold mb-4">{page.title}
"flex-grow border-4 border-slate-400 rounded-lg">
))}
)}
);
}
🧠 AI Content Generation: Two-Stage Creative Pipeline
The AI generation system uses a sophisticated two-stage process: intelligent theme interpretation followed by visual creation, ensuring thematic consistency across all coloring pages:
import { GoogleGenAI, Type } from "@google/genai";
const API_KEY = process.env.API_KEY;
if (!API_KEY) {
throw new Error("API_KEY environment variable not set");
}
const ai = new GoogleGenAI({ apiKey: API_KEY });
export async function generatePageIdeas(theme: string): Promise {
try {
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: `Generate a list of 10 distinct, child-friendly subjects for coloring pages
with the theme "${theme}". The subjects should be single, simple concepts.
For example, for "sea animals", you could return ["A friendly dolphin",
"A curious sea turtle", "A starfish on the sand"].`,
config: {
responseMimeType: "application/json",
responseSchema: {
type: Type.OBJECT,
properties: {
ideas: {
type: Type.ARRAY,
items: {
type: Type.STRING,
description: 'A single coloring page subject or idea.',
},
},
},
required: ['ideas'],
},
},
});
const jsonText = response.text.trim();
const result = JSON.parse(jsonText);
if (result.ideas && Array.isArray(result.ideas) && result.ideas.length >= 10) {
return result.ideas.slice(0, 10);
} else {
throw new Error("Invalid or insufficient ideas generated.");
}
} catch (error) {
console.error("Error generating page ideas:", error);
throw new Error("Failed to get ideas from AI. Please check the theme and try again.");
}
}
export async function generateImage(
subject: string,
agePrompt: string,
stylePrompt: string
): Promise {
const prompt = `A black and white coloring book page for a child.
The style is ${stylePrompt} and ${agePrompt}.
The drawing is of: "${subject}".
It must have clean lines, no shading or color, on a pure white background.
The image should be centered and fill the space well.`;
try {
const response = await ai.models.generateImages({
model: 'imagen-4.0-generate-001',
prompt: prompt,
config: {
numberOfImages: 1,
outputMimeType: 'image/png',
aspectRatio: '1:1',
},
});
if (response.generatedImages && response.generatedImages.length > 0) {
return response.generatedImages[0].image.imageBytes;
} else {
throw new Error("No image was generated.");
}
} catch (error) {
console.error(`Error generating image for subject "${subject}":`, error);
throw new Error(`Failed to generate an image for "${subject}".`);
}
}
🎯 Age-Appropriate Design System
The application includes a sophisticated age group customization system that automatically adjusts complexity, line thickness, and detail levels for optimal developmental appropriateness:
import { AgeGroup, DrawingStyle } from './types';
export const AGE_GROUPS: AgeGroup[] = [
{
label: 'Toddler (3-5)',
prompt: 'very simple with thick, bold outlines'
},
{
label: 'Kid (6-9)',
prompt: 'simple with clear outlines'
},
{
label: 'Pre-teen (10-12)',
prompt: 'detailed and intricate with fine lines'
},
];
export const DRAWING_STYLES: DrawingStyle[] = [
{
label: 'Cartoonish',
prompt: 'in a fun, friendly cartoon style'
},
{
label: 'Doodle',
prompt: 'in a whimsical, hand-drawn doodle style'
},
{
label: 'Realistic',
prompt: 'in a more realistic, detailed line art style'
},
];
export interface Page {
id: string;
title: string;
imageData: string;
}
export interface AgeGroup {
label: string;
prompt: string;
}
export interface DrawingStyle {
label: string;
prompt: string;
}
📄 PDF Generation & Print Optimization
The application includes a sophisticated PDF generation system that creates professional-quality, printable coloring books with proper A4 formatting and print optimization:
export async function generatePdf(pages: Page[], theme: string): Promise {
try {
const { jsPDF } = await import('jspdf');
const html2canvas = (await import('html2canvas')).default;
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
for (let i = 0; i < pages.length; i++) {
const page = pages[i];
const element = document.getElementById(page.id);
if (element) {
const canvas = await html2canvas(element, {
scale: 2,
useCORS: true,
backgroundColor: '#ffffff',
width: 794,
height: 1123
});
const imageData = canvas.toDataURL('image/png');
if (i > 0) {
pdf.addPage();
}
pdf.addImage(imageData, 'PNG', 10, 10, 190, 277);
}
}
const filename = `${theme.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_coloring_book.pdf`;
pdf.save(filename);
} catch (error) {
console.error('PDF Generation Error:', error);
throw new Error('Failed to generate PDF. Please try again.');
}
}