side-by-side
Browse files- src/routes/+page.svelte +34 -20
src/routes/+page.svelte
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
const animNoiseDuration = 3000 as const;
|
16 |
let canvasSize = 400;
|
17 |
let containerEl: HTMLDivElement;
|
18 |
-
let
|
19 |
let isShowSketch = false;
|
20 |
|
21 |
async function drawNoise() {
|
@@ -61,12 +61,14 @@
|
|
61 |
|
62 |
async function getCanvasSnapshot(
|
63 |
canvas: HTMLCanvasElement
|
64 |
-
): Promise<{ imgFile: File;
|
65 |
-
const
|
66 |
-
const res = await fetch(
|
67 |
const blob = await res.blob();
|
68 |
const imgFile = new File([blob], 'canvas shot.png', { type: 'image/png' });
|
69 |
-
|
|
|
|
|
70 |
}
|
71 |
|
72 |
async function submitRequest() {
|
@@ -79,13 +81,14 @@
|
|
79 |
}
|
80 |
|
81 |
isLoading = true;
|
82 |
-
isShowSketch=false;
|
|
|
83 |
|
84 |
// start noise animation
|
85 |
noiseTs = performance.now();
|
86 |
drawNoise();
|
87 |
|
88 |
-
const { imgFile,
|
89 |
const form = new FormData();
|
90 |
form.append('prompt', txt);
|
91 |
form.append('image', imgFile);
|
@@ -117,9 +120,8 @@
|
|
117 |
if (interval) {
|
118 |
clearInterval(interval);
|
119 |
}
|
120 |
-
|
121 |
-
|
122 |
-
isShowSketch=true;
|
123 |
let i = 0;
|
124 |
imageTs = performance.now();
|
125 |
drawImage(imgEls[i % imgEls.length]);
|
@@ -167,22 +169,31 @@
|
|
167 |
}
|
168 |
}
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
onMount(async () => {
|
171 |
-
const {innerWidth: windowWidth} = window;
|
172 |
-
canvasSize = Math.min(canvasSize, Math.floor(windowWidth*0.75));
|
173 |
containerEl.style.width = `${canvasSize}px`;
|
174 |
containerEl.style.height = `${canvasSize}px`;
|
|
|
|
|
175 |
await tick();
|
176 |
const drawingBoard = new window.DrawingBoard.Board('board-container', {
|
177 |
size: 10,
|
178 |
-
controls: [
|
179 |
-
'Color',
|
180 |
-
{ Size: { type: 'dropdown' } },
|
181 |
-
{ DrawingMode: { filler: false } },
|
182 |
-
],
|
183 |
droppable: true,
|
184 |
webStorage: false,
|
185 |
-
enlargeYourContainer: true
|
186 |
});
|
187 |
canvas = drawingBoard.canvas;
|
188 |
ctx = canvas.getContext('2d');
|
@@ -200,9 +211,12 @@
|
|
200 |
</svelte:head>
|
201 |
|
202 |
<div class="flex flex-wrap gap-x-4 gap-y-2 justify-center mt-8">
|
203 |
-
<
|
|
|
|
|
|
|
204 |
<div class="flex flex-col items-center {isLoading ? 'pointer-events-none' : ''}">
|
205 |
-
<div id="board-container" bind:this={containerEl}/>
|
206 |
<div class="flex gap-x-2 mt-4 items-center justify-center {isLoading ? 'animate-pulse' : ''}">
|
207 |
<input type="text" class="border-2 " placeholder="Add prompt" bind:value={txt} />
|
208 |
<button
|
|
|
15 |
const animNoiseDuration = 3000 as const;
|
16 |
let canvasSize = 400;
|
17 |
let containerEl: HTMLDivElement;
|
18 |
+
let sketchEl: HTMLCanvasElement;
|
19 |
let isShowSketch = false;
|
20 |
|
21 |
async function drawNoise() {
|
|
|
61 |
|
62 |
async function getCanvasSnapshot(
|
63 |
canvas: HTMLCanvasElement
|
64 |
+
): Promise<{ imgFile: File; imgBitmap: ImageBitmap }> {
|
65 |
+
const canvasDataUrl = canvas.toDataURL('png');
|
66 |
+
const res = await fetch(canvasDataUrl);
|
67 |
const blob = await res.blob();
|
68 |
const imgFile = new File([blob], 'canvas shot.png', { type: 'image/png' });
|
69 |
+
const imgData = canvas.getContext('2d')!.getImageData(0, 0, canvasSize, canvasSize);
|
70 |
+
const imgBitmap = await createImageBitmap(imgData);
|
71 |
+
return { imgFile, imgBitmap };
|
72 |
}
|
73 |
|
74 |
async function submitRequest() {
|
|
|
81 |
}
|
82 |
|
83 |
isLoading = true;
|
84 |
+
isShowSketch = false;
|
85 |
+
copySketch();
|
86 |
|
87 |
// start noise animation
|
88 |
noiseTs = performance.now();
|
89 |
drawNoise();
|
90 |
|
91 |
+
const { imgFile, imgBitmap: initialSketchBitmap } = await getCanvasSnapshot(canvas);
|
92 |
const form = new FormData();
|
93 |
form.append('prompt', txt);
|
94 |
form.append('image', imgFile);
|
|
|
120 |
if (interval) {
|
121 |
clearInterval(interval);
|
122 |
}
|
123 |
+
|
124 |
+
isShowSketch = true;
|
|
|
125 |
let i = 0;
|
126 |
imageTs = performance.now();
|
127 |
drawImage(imgEls[i % imgEls.length]);
|
|
|
169 |
}
|
170 |
}
|
171 |
|
172 |
+
function copySketch() {
|
173 |
+
const context = sketchEl.getContext('2d');
|
174 |
+
|
175 |
+
//set dimensions
|
176 |
+
sketchEl.width = canvas.width;
|
177 |
+
sketchEl.height = canvas.height;
|
178 |
+
|
179 |
+
//apply the old canvas to the new one
|
180 |
+
context!.drawImage(canvas, 0, 0);
|
181 |
+
}
|
182 |
+
|
183 |
onMount(async () => {
|
184 |
+
const { innerWidth: windowWidth } = window;
|
185 |
+
canvasSize = Math.min(canvasSize, Math.floor(windowWidth * 0.75));
|
186 |
containerEl.style.width = `${canvasSize}px`;
|
187 |
containerEl.style.height = `${canvasSize}px`;
|
188 |
+
sketchEl.style.width = `${canvasSize}px`;
|
189 |
+
sketchEl.style.height = `${canvasSize}px`;
|
190 |
await tick();
|
191 |
const drawingBoard = new window.DrawingBoard.Board('board-container', {
|
192 |
size: 10,
|
193 |
+
controls: ['Color', { Size: { type: 'dropdown' } }, { DrawingMode: { filler: false } }],
|
|
|
|
|
|
|
|
|
194 |
droppable: true,
|
195 |
webStorage: false,
|
196 |
+
enlargeYourContainer: true
|
197 |
});
|
198 |
canvas = drawingBoard.canvas;
|
199 |
ctx = canvas.getContext('2d');
|
|
|
211 |
</svelte:head>
|
212 |
|
213 |
<div class="flex flex-wrap gap-x-4 gap-y-2 justify-center mt-8">
|
214 |
+
<canvas
|
215 |
+
class="border-2 {!isShowSketch ? 'hidden' : ''}"
|
216 |
+
bind:this={sketchEl}
|
217 |
+
/>
|
218 |
<div class="flex flex-col items-center {isLoading ? 'pointer-events-none' : ''}">
|
219 |
+
<div id="board-container" bind:this={containerEl} />
|
220 |
<div class="flex gap-x-2 mt-4 items-center justify-center {isLoading ? 'animate-pulse' : ''}">
|
221 |
<input type="text" class="border-2 " placeholder="Add prompt" bind:value={txt} />
|
222 |
<button
|