|
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: () => [], |
|
}, |
|
neutral: { |
|
id: "neutral", |
|
label: "Neutral (no style)", |
|
family: "american", |
|
color: "color", |
|
font: "actionman", |
|
llmPrompt: "", |
|
imagePrompt: (prompt: string) => [ |
|
prompt, |
|
], |
|
negativePrompt: () => [ ], |
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
japanese_manga: { |
|
id: "japanese_manga", |
|
label: "Japanese", |
|
family: "asian", |
|
color: "grayscale", |
|
font: "actionman", |
|
llmPrompt: "japanese manga", |
|
imagePrompt: (prompt: string) => [ |
|
`grayscale`, |
|
`detailed drawing`, |
|
`japanese manga`, |
|
prompt, |
|
|
|
|
|
|
|
|
|
|
|
|
|
], |
|
negativePrompt: () => [ |
|
"franco-belgian comic", |
|
"color album", |
|
"color", |
|
"american comic", |
|
"photo", |
|
"painting", |
|
"3D render" |
|
], |
|
}, |
|
japanese_color_manga: { |
|
id: "japanese_color_manga", |
|
label: "Japanese (color)", |
|
family: "asian", |
|
color: "color", |
|
font: "actionman", |
|
llmPrompt: "japanese color manga", |
|
imagePrompt: (prompt: string) => [ |
|
`color`, |
|
`detailed drawing`, |
|
`japanese manga`, |
|
prompt, |
|
|
|
|
|
|
|
|
|
|
|
|
|
], |
|
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", |
|
"detailed painting" |
|
|
|
], |
|
negativePrompt: () => [ |
|
"franco-belgian comic", |
|
"color album", |
|
"color", |
|
"manga", |
|
"comic", |
|
"american comic", |
|
"photo", |
|
"painting", |
|
"3D render" |
|
], |
|
}, |
|
traditional_chinese_painting: { |
|
id: "traditional_chinese_painting", |
|
label: "Traditional Chinese", |
|
family: "asian", |
|
color: "color", |
|
font: "actionman", |
|
llmPrompt: "chinese painting", |
|
imagePrompt: (prompt: string) => [ |
|
`traditional chinese painting about ${prompt}`, |
|
"traditional chinese painting", |
|
"ancient chinese painting", |
|
"intricate", |
|
"detailed", |
|
"detailed painting" |
|
|
|
], |
|
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", |
|
prompt, |
|
"comic album", |
|
"detailed drawing" |
|
|
|
], |
|
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`, |
|
prompt, |
|
"detailed drawing" |
|
|
|
|
|
|
|
|
|
|
|
], |
|
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`, |
|
prompt, |
|
"detailed drawing" |
|
|
|
|
|
|
|
|
|
], |
|
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 science fiction`, |
|
|
|
"color pulp comic panel", |
|
"1940", |
|
`${prompt}`, |
|
"detailed drawing" |
|
|
|
|
|
], |
|
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}`, |
|
"detailed drawing", |
|
"french comic panel", |
|
"franco-belgian style", |
|
"bande dessinée", |
|
"single panel", |
|
|
|
], |
|
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 animation`, |
|
`Pixar`, |
|
`cute`, |
|
`funny`, |
|
`Unreal engine`, |
|
`${prompt}`, |
|
`crisp`, |
|
`sharp` |
|
], |
|
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`, |
|
`${prompt}`, |
|
`detailed painting`, |
|
`intricate details` |
|
], |
|
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`, |
|
|
|
`${prompt}`, |
|
`intricate details`, |
|
|
|
], |
|
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" |
|
], |
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
photonovel: { |
|
id: "photonovel", |
|
label: "Vintage photonovel", |
|
family: "european", |
|
color: "color", |
|
font: "actionman", |
|
llmPrompt: "new movie", |
|
imagePrompt: (prompt: string) => [ |
|
`vintage photo`, |
|
`1950`, |
|
`1960`, |
|
`french new wave`, |
|
`faded colors`, |
|
`color movie screencap`, |
|
`${prompt}`, |
|
], |
|
negativePrompt: () => [ |
|
"manga", |
|
"anime", |
|
"american comic", |
|
"grayscale", |
|
"monochrome", |
|
"painting" |
|
], |
|
}, |
|
stockphoto: { |
|
id: "stockphoto", |
|
label: "Stock photo", |
|
family: "european", |
|
color: "color", |
|
font: "actionman", |
|
llmPrompt: "new movie", |
|
imagePrompt: (prompt: string) => [ |
|
`cinematic`, |
|
`hyperrealistic`, |
|
`footage`, |
|
`sharp 8k`, |
|
`analog`, |
|
`instagram`, |
|
`photoshoot`, |
|
`${prompt}`, |
|
`crisp details` |
|
], |
|
negativePrompt: () => [ |
|
"manga", |
|
"anime", |
|
"american comic", |
|
"grayscale", |
|
"monochrome", |
|
"painting" |
|
], |
|
}, |
|
} |
|
|
|
export type PresetName = keyof typeof presets |
|
|
|
export const defaultPreset: PresetName = "american_comic_50" |
|
|
|
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) |
|
} |