Commit
•
974ed41
1
Parent(s):
a40bf40
various improvements
Browse files- src/app/engine/presets.ts +175 -3
- src/app/interface/grid/index.tsx +1 -1
- src/app/interface/panel/index.tsx +6 -3
- src/app/interface/top-menu/index.tsx +7 -1
- src/app/interface/zoom/index.tsx +1 -1
- src/app/main.tsx +9 -4
- src/app/queries/getStory.ts +1 -1
- src/app/store/index.ts +1 -1
src/app/engine/presets.ts
CHANGED
@@ -74,8 +74,64 @@ export const presets: Record<string, Preset> = {
|
|
74 |
"3D render"
|
75 |
],
|
76 |
},
|
77 |
-
|
78 |
-
label: "American",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
family: "american",
|
80 |
color: "color",
|
81 |
font: "actionman",
|
@@ -102,6 +158,122 @@ export const presets: Record<string, Preset> = {
|
|
102 |
"3D render"
|
103 |
],
|
104 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
armorican: {
|
106 |
label: "Armorican",
|
107 |
family: "european",
|
@@ -109,7 +281,7 @@ export const presets: Record<string, Preset> = {
|
|
109 |
font: "actionman",
|
110 |
llmPrompt: "new color album",
|
111 |
imagePrompt: (prompt: string) => [
|
112 |
-
`color
|
113 |
`about ${prompt}`,
|
114 |
"romans",
|
115 |
"gauls",
|
|
|
74 |
"3D render"
|
75 |
],
|
76 |
},
|
77 |
+
american_comic_90: {
|
78 |
+
label: "American (modern)",
|
79 |
+
family: "american",
|
80 |
+
color: "color",
|
81 |
+
font: "actionman",
|
82 |
+
llmPrompt: "american comic",
|
83 |
+
imagePrompt: (prompt: string) => [
|
84 |
+
`american comic about ${prompt}`,
|
85 |
+
"single panel",
|
86 |
+
"modern american comic",
|
87 |
+
"comicbook style",
|
88 |
+
"2010s",
|
89 |
+
"digital print",
|
90 |
+
"color comicbook",
|
91 |
+
"color drawing"
|
92 |
+
],
|
93 |
+
negativePrompt: () => [
|
94 |
+
"manga",
|
95 |
+
"anime",
|
96 |
+
"american comic",
|
97 |
+
"action",
|
98 |
+
"grayscale",
|
99 |
+
"monochrome",
|
100 |
+
"photo",
|
101 |
+
"painting",
|
102 |
+
"3D render"
|
103 |
+
],
|
104 |
+
},
|
105 |
+
american_comic_40: {
|
106 |
+
label: "American (1940)",
|
107 |
+
family: "american",
|
108 |
+
color: "color",
|
109 |
+
font: "actionman",
|
110 |
+
llmPrompt: "american comic",
|
111 |
+
imagePrompt: (prompt: string) => [
|
112 |
+
`american comic about ${prompt}`,
|
113 |
+
"single panel",
|
114 |
+
"american comic",
|
115 |
+
"comicbook style",
|
116 |
+
"1940",
|
117 |
+
"40s",
|
118 |
+
"color comicbook",
|
119 |
+
"color drawing"
|
120 |
+
],
|
121 |
+
negativePrompt: () => [
|
122 |
+
"manga",
|
123 |
+
"anime",
|
124 |
+
"american comic",
|
125 |
+
"action",
|
126 |
+
"grayscale",
|
127 |
+
"monochrome",
|
128 |
+
"photo",
|
129 |
+
"painting",
|
130 |
+
"3D render"
|
131 |
+
],
|
132 |
+
},
|
133 |
+
american_comic_50: {
|
134 |
+
label: "American (1950)",
|
135 |
family: "american",
|
136 |
color: "color",
|
137 |
font: "actionman",
|
|
|
158 |
"3D render"
|
159 |
],
|
160 |
},
|
161 |
+
american_comic_60: {
|
162 |
+
label: "American (1960)",
|
163 |
+
family: "american",
|
164 |
+
color: "color",
|
165 |
+
font: "actionman",
|
166 |
+
llmPrompt: "american comic",
|
167 |
+
imagePrompt: (prompt: string) => [
|
168 |
+
`american comic about ${prompt}`,
|
169 |
+
"single panel",
|
170 |
+
"american comic",
|
171 |
+
"comicbook style",
|
172 |
+
"1960",
|
173 |
+
"60s",
|
174 |
+
"color comicbook",
|
175 |
+
"color drawing"
|
176 |
+
],
|
177 |
+
negativePrompt: () => [
|
178 |
+
"manga",
|
179 |
+
"anime",
|
180 |
+
"american comic",
|
181 |
+
"action",
|
182 |
+
"grayscale",
|
183 |
+
"monochrome",
|
184 |
+
"photo",
|
185 |
+
"painting",
|
186 |
+
"3D render"
|
187 |
+
],
|
188 |
+
},
|
189 |
+
|
190 |
+
/*
|
191 |
+
pulp_sf: {
|
192 |
+
label: "Pulp SF",
|
193 |
+
family: "european",
|
194 |
+
color: "color",
|
195 |
+
font: "actionman",
|
196 |
+
llmPrompt: "new pulp science fiction",
|
197 |
+
imagePrompt: (prompt: string) => [
|
198 |
+
`color comic panel`,
|
199 |
+
`${prompt}`,
|
200 |
+
"pulp science fiction",
|
201 |
+
"vintage",
|
202 |
+
"1940",
|
203 |
+
"1950",
|
204 |
+
"single panel",
|
205 |
+
"comic album"
|
206 |
+
],
|
207 |
+
negativePrompt: () => [
|
208 |
+
"manga",
|
209 |
+
"anime",
|
210 |
+
"american comic",
|
211 |
+
"grayscale",
|
212 |
+
"monochrome",
|
213 |
+
"photo",
|
214 |
+
"painting",
|
215 |
+
"3D render"
|
216 |
+
],
|
217 |
+
},
|
218 |
+
*/
|
219 |
+
humanoid: {
|
220 |
+
label: "Humanoid",
|
221 |
+
family: "european",
|
222 |
+
color: "color",
|
223 |
+
font: "actionman",
|
224 |
+
llmPrompt: "new album by moebius",
|
225 |
+
imagePrompt: (prompt: string) => [
|
226 |
+
`color comic panel`,
|
227 |
+
`${prompt}`,
|
228 |
+
"style of Moebius",
|
229 |
+
"by Moebius",
|
230 |
+
"french comic panel",
|
231 |
+
"franco-belgian style",
|
232 |
+
"bande dessinée",
|
233 |
+
"single panel",
|
234 |
+
"comic album"
|
235 |
+
],
|
236 |
+
negativePrompt: () => [
|
237 |
+
"manga",
|
238 |
+
"anime",
|
239 |
+
"american comic",
|
240 |
+
"grayscale",
|
241 |
+
"monochrome",
|
242 |
+
"photo",
|
243 |
+
"painting",
|
244 |
+
"3D render"
|
245 |
+
],
|
246 |
+
},
|
247 |
+
milou: {
|
248 |
+
label: "Haddock",
|
249 |
+
family: "european",
|
250 |
+
color: "color",
|
251 |
+
font: "actionman",
|
252 |
+
llmPrompt: "new album by Hergé",
|
253 |
+
imagePrompt: (prompt: string) => [
|
254 |
+
`color comic panel`,
|
255 |
+
`${prompt}`,
|
256 |
+
"style of Hergé",
|
257 |
+
"by Hergé",
|
258 |
+
"tintin style",
|
259 |
+
"french comic panel",
|
260 |
+
"franco-belgian style",
|
261 |
+
"color panel",
|
262 |
+
"bande dessinée",
|
263 |
+
"single panel",
|
264 |
+
"comic album"
|
265 |
+
],
|
266 |
+
negativePrompt: () => [
|
267 |
+
"manga",
|
268 |
+
"anime",
|
269 |
+
"american comic",
|
270 |
+
"grayscale",
|
271 |
+
"monochrome",
|
272 |
+
"photo",
|
273 |
+
"painting",
|
274 |
+
"3D render"
|
275 |
+
],
|
276 |
+
},
|
277 |
armorican: {
|
278 |
label: "Armorican",
|
279 |
family: "european",
|
|
|
281 |
font: "actionman",
|
282 |
llmPrompt: "new color album",
|
283 |
imagePrompt: (prompt: string) => [
|
284 |
+
`color comic panel`,
|
285 |
`about ${prompt}`,
|
286 |
"romans",
|
287 |
"gauls",
|
src/app/interface/grid/index.tsx
CHANGED
@@ -16,7 +16,7 @@ export function Grid({ children, className }: { children: ReactNode; className:
|
|
16 |
className
|
17 |
)}
|
18 |
style={{
|
19 |
-
gap: `${
|
20 |
}}
|
21 |
>
|
22 |
{children}
|
|
|
16 |
className
|
17 |
)}
|
18 |
style={{
|
19 |
+
gap: `${(zoomLevel / 100) * 0.7}vw`
|
20 |
}}
|
21 |
>
|
22 |
{children}
|
src/app/interface/panel/index.tsx
CHANGED
@@ -164,11 +164,14 @@ export function Panel({
|
|
164 |
|
165 |
const frameClassName = cn(
|
166 |
`w-full h-full`,
|
167 |
-
`border-stone-
|
168 |
`transition-all duration-200 ease-in-out`,
|
169 |
-
zoomLevel >
|
|
|
|
|
|
|
|
|
170 |
`shadow-sm`,
|
171 |
-
`rounded-sm`,
|
172 |
`overflow-hidden`,
|
173 |
`print:shadow-none`,
|
174 |
)
|
|
|
164 |
|
165 |
const frameClassName = cn(
|
166 |
`w-full h-full`,
|
167 |
+
`border-stone-800`,
|
168 |
`transition-all duration-200 ease-in-out`,
|
169 |
+
zoomLevel > 140 ? `border-[2px] md:border-[4px] rounded-sm md:rounded-md` :
|
170 |
+
zoomLevel > 120 ? `border-[1.5px] md:border-[3px] rounded-xs md:rounded-sm` :
|
171 |
+
zoomLevel > 90 ? `border-[1px] md:border-[2px] rounded-xs md:rounded-sm` :
|
172 |
+
zoomLevel > 40 ? `border-[0.5px] md:border-[1px] rounded-none md:rounded-xs` :
|
173 |
+
`border-transparent md:border-[0.5px] rounded-none md:rounded-none`,
|
174 |
`shadow-sm`,
|
|
|
175 |
`overflow-hidden`,
|
176 |
`print:shadow-none`,
|
177 |
)
|
src/app/interface/top-menu/index.tsx
CHANGED
@@ -97,11 +97,14 @@ export function TopMenu() {
|
|
97 |
<Input
|
98 |
placeholder="Story"
|
99 |
className="w-full bg-neutral-300 text-neutral-800 dark:bg-neutral-300 dark:text-neutral-800"
|
100 |
-
disabled={atLeastOnePanelIsBusy}
|
101 |
onChange={(e) => {
|
102 |
setDraft(e.target.value)
|
103 |
}}
|
104 |
onKeyDown={({ key }) => {
|
|
|
|
|
|
|
105 |
if (key === 'Enter') {
|
106 |
if (draft.trim() !== prompt.trim()) {
|
107 |
setPrompt(draft.trim())
|
@@ -112,6 +115,9 @@ export function TopMenu() {
|
|
112 |
/>
|
113 |
<Button
|
114 |
onClick={() => {
|
|
|
|
|
|
|
115 |
if (draft.trim() !== prompt.trim()) {
|
116 |
setPrompt(draft.trim())
|
117 |
}
|
|
|
97 |
<Input
|
98 |
placeholder="Story"
|
99 |
className="w-full bg-neutral-300 text-neutral-800 dark:bg-neutral-300 dark:text-neutral-800"
|
100 |
+
// disabled={atLeastOnePanelIsBusy}
|
101 |
onChange={(e) => {
|
102 |
setDraft(e.target.value)
|
103 |
}}
|
104 |
onKeyDown={({ key }) => {
|
105 |
+
if (isBusy) {
|
106 |
+
return
|
107 |
+
}
|
108 |
if (key === 'Enter') {
|
109 |
if (draft.trim() !== prompt.trim()) {
|
110 |
setPrompt(draft.trim())
|
|
|
115 |
/>
|
116 |
<Button
|
117 |
onClick={() => {
|
118 |
+
if (isBusy) {
|
119 |
+
return
|
120 |
+
}
|
121 |
if (draft.trim() !== prompt.trim()) {
|
122 |
setPrompt(draft.trim())
|
123 |
}
|
src/app/interface/zoom/index.tsx
CHANGED
@@ -22,7 +22,7 @@ export function Zoom() {
|
|
22 |
<VerticalSlider
|
23 |
defaultValue={[zoomLevel]}
|
24 |
min={30}
|
25 |
-
max={
|
26 |
step={1}
|
27 |
onValueChange={value => setZoomLevel(value[0] || 10)}
|
28 |
value={[zoomLevel]}
|
|
|
22 |
<VerticalSlider
|
23 |
defaultValue={[zoomLevel]}
|
24 |
min={30}
|
25 |
+
max={250}
|
26 |
step={1}
|
27 |
onValueChange={value => setZoomLevel(value[0] || 10)}
|
28 |
value={[zoomLevel]}
|
src/app/main.tsx
CHANGED
@@ -106,13 +106,16 @@ export default function Main() {
|
|
106 |
<div>
|
107 |
<TopMenu />
|
108 |
<div className={cn(
|
109 |
-
`flex items-start w-screen h-screen pt-[120px]
|
110 |
`transition-all duration-200 ease-in-out`,
|
111 |
-
`
|
112 |
-
|
113 |
fonts.actionman.className
|
114 |
)}>
|
115 |
-
<div className=
|
|
|
|
|
|
|
116 |
<div
|
117 |
ref={pageRef}
|
118 |
className={cn(
|
@@ -128,11 +131,13 @@ export default function Main() {
|
|
128 |
`border border-stone-200`,
|
129 |
`shadow-2xl`,
|
130 |
`print:shadow-none`,
|
|
|
131 |
`print:width-screen`
|
132 |
)}
|
133 |
style={{
|
134 |
width: `${zoomLevel}%`,
|
135 |
padding: `${Math.round((zoomLevel / 100) * 16)}px`
|
|
|
136 |
}}
|
137 |
>
|
138 |
<LayoutElement />
|
|
|
106 |
<div>
|
107 |
<TopMenu />
|
108 |
<div className={cn(
|
109 |
+
`flex items-start w-screen h-screen pt-[120px] md:pt-[72px] overflow-y-scroll`,
|
110 |
`transition-all duration-200 ease-in-out`,
|
111 |
+
zoomLevel > 105 ? `px-0` : `pl-2 pr-16 md:pl-16 md:pr-16`,
|
112 |
+
`print:pt-0 print:px-0 print:pl-0 print:pr-0`,
|
113 |
fonts.actionman.className
|
114 |
)}>
|
115 |
+
<div className={cn(
|
116 |
+
`flex flex-col w-full`,
|
117 |
+
zoomLevel > 105 ? `items-start` : `items-center`
|
118 |
+
)}>
|
119 |
<div
|
120 |
ref={pageRef}
|
121 |
className={cn(
|
|
|
131 |
`border border-stone-200`,
|
132 |
`shadow-2xl`,
|
133 |
`print:shadow-none`,
|
134 |
+
`print:border-0`,
|
135 |
`print:width-screen`
|
136 |
)}
|
137 |
style={{
|
138 |
width: `${zoomLevel}%`,
|
139 |
padding: `${Math.round((zoomLevel / 100) * 16)}px`
|
140 |
+
// marginLeft: `${zoomLevel > 100 ? `100`}`
|
141 |
}}
|
142 |
>
|
143 |
<LayoutElement />
|
src/app/queries/getStory.ts
CHANGED
@@ -29,7 +29,7 @@ export const getStory = async ({
|
|
29 |
role: "user",
|
30 |
content: `The story is: ${prompt}`,
|
31 |
}
|
32 |
-
])
|
33 |
|
34 |
|
35 |
let result = ""
|
|
|
29 |
role: "user",
|
30 |
content: `The story is: ${prompt}`,
|
31 |
}
|
32 |
+
]) + "```json\n["
|
33 |
|
34 |
|
35 |
let result = ""
|
src/app/store/index.ts
CHANGED
@@ -39,7 +39,7 @@ export const useStore = create<{
|
|
39 |
panels: [],
|
40 |
captions: {},
|
41 |
layout: getRandomLayoutName(),
|
42 |
-
zoomLevel:
|
43 |
page: undefined as unknown as HTMLDivElement,
|
44 |
isGeneratingStory: false,
|
45 |
panelGenerationStatus: {},
|
|
|
39 |
panels: [],
|
40 |
captions: {},
|
41 |
layout: getRandomLayoutName(),
|
42 |
+
zoomLevel: 60,
|
43 |
page: undefined as unknown as HTMLDivElement,
|
44 |
isGeneratingStory: false,
|
45 |
panelGenerationStatus: {},
|