| import { FontName, actionman, komika, vtc } from "@/lib/fonts" |
| import { pick } from "@/lib/pick" |
| import { NextFontWithVariable } from "next/dist/compiled/@next/font" |
|
|
| export type ComicFamily = |
| | "american" |
| | "asian" |
| | "european" |
|
|
| export type ComicColor = |
| | "color" |
| | "grayscale" |
| | "monochrome" |
|
|
| export interface Preset { |
| id: string |
| label: string |
| family: ComicFamily |
| color: ComicColor |
| font: FontName |
| llmPrompt: string |
| imagePrompt: (prompt: string) => string[] |
| negativePrompt: (prompt: string) => string[] |
| } |
|
|
| |
|
|
| export const presets: Record<string, Preset> = { |
| random: { |
| id: "random", |
| label: "Random style", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "", |
| imagePrompt: (prompt: string) => [], |
| negativePrompt: () => [], |
| }, |
| japanese_manga: { |
| id: "japanese_manga", |
| label: "Japanese", |
| family: "asian", |
| color: "grayscale", |
| font: "actionman", |
| llmPrompt: "japanese manga", |
| imagePrompt: (prompt: string) => [ |
| `grayscale`, |
| `intricate details`, |
| `japanese manga about ${prompt}`, |
| "single panel", |
| "manga", |
| "japanese", |
| "intricate", |
| "detailed", |
| |
| ], |
| negativePrompt: () => [ |
| "franco-belgian comic", |
| "color album", |
| "color", |
| "american comic", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| nihonga: { |
| id: "nihonga", |
| label: "Nihonga", |
| family: "asian", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "japanese manga", |
| imagePrompt: (prompt: string) => [ |
| `japanese nihonga painting about ${prompt}`, |
| "Nihonga", |
| "ancient japanese painting", |
| "intricate", |
| "detailed", |
| |
| ], |
| negativePrompt: () => [ |
| "franco-belgian comic", |
| "color album", |
| "color", |
| "manga", |
| "comic", |
| "american comic", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| franco_belgian: { |
| id: "franco_belgian", |
| label: "Franco-Belgian", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "Franco-Belgian comic (a \"bande dessinée\"), in the style of Franquin, Moebius etc", |
| imagePrompt: (prompt: string) => [ |
| "bande dessinée", |
| "franco-belgian comic", |
| `franco-belgian color comic about ${prompt}`, |
| "comic album", |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| american_comic_90: { |
| id: "american_comic_90", |
| label: "American (modern)", |
| family: "american", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "american comic", |
| imagePrompt: (prompt: string) => [ |
| "digital color comicbook style", |
| `modern american comic about ${prompt}`, |
| |
| |
| |
| |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "action", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| american_comic_50: { |
| id: "american_comic_50", |
| label: "American (1950)", |
| family: "american", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "american comic", |
| imagePrompt: (prompt: string) => [ |
| "1950", |
| "50s", |
| `vintage american color comic about ${prompt}`, |
| |
| |
| |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "action", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| flying_saucer: { |
| id: "flying_saucer", |
| label: "Flying saucer", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "new pulp science fiction", |
| imagePrompt: (prompt: string) => [ |
| `vintage color pulp comic panel`, |
| "40s", |
| "1940", |
| "vintage science fiction", |
| `${prompt}`, |
| |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| |
| humanoid: { |
| id: "humanoid", |
| label: "Humanoid", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "comic books by Moebius", |
| imagePrompt: (prompt: string) => [ |
| `color comic panel`, |
| "style of Moebius", |
| `${prompt}`, |
| "by Moebius", |
| "french comic panel", |
| "franco-belgian style", |
| "bande dessinée", |
| "single panel", |
| "intricate" |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| haddock: { |
| id: "haddock", |
| label: "Haddock", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "writing Tintin comic books", |
| imagePrompt: (prompt: string) => [ |
| `color comic panel`, |
| "style of Hergé", |
| "tintin style", |
| `${prompt}`, |
| "by Hergé", |
| "french comic panel", |
| "franco-belgian style", |
| |
| |
| |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| armorican: { |
| id: "armorican", |
| label: "Armorican", |
| family: "european", |
| color: "monochrome", |
| font: "actionman", |
| llmPrompt: "french style comic books set in ancient Rome and Gaul", |
| imagePrompt: (prompt: string) => [ |
| `color comic panel`, |
| "romans", |
| "gauls", |
| "french comic panel", |
| "franco-belgian style", |
| `about ${prompt}`, |
| "bande dessinée", |
| "single panel", |
| |
| |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "photo", |
| "painting", |
| "3D render" |
| ], |
| }, |
| render: { |
| id: "render", |
| label: "3D Render", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "new movie", |
| imagePrompt: (prompt: string) => [ |
| `3D render`, |
| `Blender`, |
| `3D animation`, |
| `Unreal engine`, |
| `${prompt}`, |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "painting" |
| ], |
| }, |
| klimt: { |
| id: "klimt", |
| label: "Klimt", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "Gustav Klimt art pieces.", |
| imagePrompt: (prompt: string) => [ |
| `golden`, |
| `patchwork`, |
| `style of Gustav Klimt`, |
| `Gustav Klimt painting`, |
| `intricate details`, |
| `${prompt}`, |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "painting" |
| ], |
| }, |
| medieval: { |
| id: "medieval", |
| label: "Medieval", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "medieval story (write in this style)", |
| imagePrompt: (prompt: string) => [ |
| `medieval illuminated manuscript`, |
| `illuminated manuscript of`, |
| `medieval`, |
| `intricate details`, |
| |
| `${prompt}`, |
| |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "painting" |
| ], |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| egyptian: { |
| id: "egyptian", |
| label: "Egyptian", |
| family: "european", |
| color: "color", |
| font: "actionman", |
| llmPrompt: "ancient egyptian stories.", |
| imagePrompt: (prompt: string) => [ |
| `ancient egyptian wall painting`, |
| `ancient egypt`, |
| |
| `${prompt}`, |
| ], |
| negativePrompt: () => [ |
| "manga", |
| "anime", |
| "american comic", |
| "grayscale", |
| "monochrome", |
| "painting" |
| ], |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
|
|
| export type PresetName = keyof typeof presets |
|
|
| export const defaultPreset: PresetName = "american_comic_90" |
|
|
| export const nonRandomPresets = Object.keys(presets).filter(p => p !== "random") |
|
|
| export const getPreset = (preset?: PresetName): Preset => presets[preset || defaultPreset] || presets[defaultPreset] |
|
|
| export const getRandomPreset = (): Preset => { |
| const presetName = pick(Object.keys(presets).filter(preset => preset !== "random")) as PresetName |
| return getPreset(presetName) |
| } |