radames commited on
Commit
560b99e
1 Parent(s): 4825ce7
Makefile CHANGED
@@ -1,9 +1,9 @@
1
  build-client:
2
  cd frontend && npm install && PUBLIC_DEV_MODE=PROD npm run build && rm -rf ../static && cp -r build/ ../static/
3
  build-dev:
4
- cd frontend && npm install && PUBLIC_DEV_MODE=DEV npm run build-dev && rm -rf ../static && cp -r build/ ../static/
5
  run-front-dev:
6
- cd frontend && npm install && PUBLIC_DEV_MODE=DEV npm run dev
7
  run-dev:
8
  rm -rf .data/ && FLASK_ENV=development python app.py
9
  run-prod:
 
1
  build-client:
2
  cd frontend && npm install && PUBLIC_DEV_MODE=PROD npm run build && rm -rf ../static && cp -r build/ ../static/
3
  build-dev:
4
+ cd frontend && npm install && npm run build-dev && rm -rf ../static && cp -r build/ ../static/
5
  run-front-dev:
6
+ cd frontend && npm install && npm run dev
7
  run-dev:
8
  rm -rf .data/ && FLASK_ENV=development python app.py
9
  run-prod:
frontend/package.json CHANGED
@@ -17,6 +17,8 @@
17
  "@tailwindcss/forms": "^0.5.3",
18
  "@tailwindcss/line-clamp": "^0.4.2",
19
  "@types/cookie": "^0.5.1",
 
 
20
  "@typescript-eslint/eslint-plugin": "^5.27.0",
21
  "@typescript-eslint/parser": "^5.27.0",
22
  "autoprefixer": "^10.4.11",
@@ -37,6 +39,8 @@
37
  "type": "module",
38
  "dependencies": {
39
  "@fontsource/fira-mono": "^4.5.0",
40
- "@liveblocks/client": "^0.18.2"
 
 
41
  }
42
  }
 
17
  "@tailwindcss/forms": "^0.5.3",
18
  "@tailwindcss/line-clamp": "^0.4.2",
19
  "@types/cookie": "^0.5.1",
20
+ "@types/d3-selection": "^3.0.3",
21
+ "@types/d3-zoom": "^3.0.1",
22
  "@typescript-eslint/eslint-plugin": "^5.27.0",
23
  "@typescript-eslint/parser": "^5.27.0",
24
  "autoprefixer": "^10.4.11",
 
39
  "type": "module",
40
  "dependencies": {
41
  "@fontsource/fira-mono": "^4.5.0",
42
+ "@liveblocks/client": "^0.18.2",
43
+ "d3-selection": "^3.0.0",
44
+ "d3-zoom": "^3.0.0"
45
  }
46
  }
frontend/src/app.d.ts CHANGED
@@ -1,6 +1,7 @@
1
  // See https://kit.svelte.dev/docs/types#app
2
  // for information about these interfaces
3
  // and what to do when importing types
 
4
 
5
  declare global {
6
  namespace App {
@@ -12,4 +13,7 @@ declare global {
12
  parentIFrame: unknown;
13
  }
14
  }
 
 
 
15
  }
 
1
  // See https://kit.svelte.dev/docs/types#app
2
  // for information about these interfaces
3
  // and what to do when importing types
4
+ import type { ZoomTransform } from 'd3-zoom';
5
 
6
  declare global {
7
  namespace App {
 
13
  parentIFrame: unknown;
14
  }
15
  }
16
+ interface Event {
17
+ transform: ZoomTransform;
18
+ }
19
  }
frontend/src/lib/App.svelte ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import Cursor from '$lib/Cursor.svelte';
3
+ import Canvas from '$lib/Canvas.svelte';
4
+ import type { Room } from '@liveblocks/client';
5
+ import { onDestroy } from 'svelte';
6
+ /**
7
+ * The main Liveblocks code for the example.
8
+ * Check in src/routes/index.svelte to see the setup code.
9
+ */
10
+
11
+ export let room: Room;
12
+
13
+ // Get initial values for presence and others
14
+ let myPresence = room.getPresence();
15
+ let others = room.getOthers();
16
+
17
+ // Subscribe to further changes
18
+ // const unsubscribeMyPresence = room.subscribe('my-presence', (presence) => {
19
+ // myPresence = presence;
20
+ // });
21
+
22
+ // const unsubscribeOthers = room.subscribe('others', (otherUsers) => {
23
+ // others = otherUsers;
24
+ // });
25
+
26
+ // Unsubscribe when unmounting
27
+ onDestroy(() => {
28
+ unsubscribeMyPresence();
29
+ unsubscribeOthers();
30
+ });
31
+
32
+ // Update cursor presence to current pointer location
33
+ function handlePointerMove(event: PointerEvent) {
34
+ event.preventDefault();
35
+ room.updatePresence({
36
+ cursor: {
37
+ x: Math.round(event.clientX),
38
+ y: Math.round(event.clientY)
39
+ }
40
+ });
41
+ }
42
+
43
+ // When the pointer leaves the page, set cursor presence to null
44
+ function handlePointerLeave() {
45
+ room.updatePresence({
46
+ cursor: null
47
+ });
48
+ }
49
+
50
+ const COLORS = [
51
+ '#E57373',
52
+ '#9575CD',
53
+ '#4FC3F7',
54
+ '#81C784',
55
+ '#FFF176',
56
+ '#FF8A65',
57
+ '#F06292',
58
+ '#7986CB'
59
+ ];
60
+ </script>
61
+
62
+ <main on:pointerleave={handlePointerLeave} on:pointermove={handlePointerMove}>
63
+ <!-- Show the current user's cursor location -->
64
+ <div class="text">
65
+ {myPresence?.cursor
66
+ ? `${myPresence.cursor.x} × ${myPresence.cursor.y}`
67
+ : 'Move your cursor to broadcast its position to other people in the room.'}
68
+ </div>
69
+
70
+ <!-- When others connected, iterate through others and show their cursors -->
71
+ {#if others}
72
+ {#each [...others] as { connectionId, presence } (connectionId)}
73
+ {#if presence?.cursor}
74
+ <Cursor
75
+ color={COLORS[connectionId % COLORS.length]}
76
+ x={presence.cursor.x}
77
+ y={presence.cursor.y}
78
+ />
79
+ {/if}
80
+ {/each}
81
+ {/if}
82
+
83
+ </main>
84
+
85
+ <Canvas />
86
+ <h3 class="text-xl">TESTS</h3>
87
+ <style lang="postcss" scoped>
88
+ main {
89
+ /* @apply fixed top-0 left-0 w-screen h-screen flex flex-col items-center justify-center touch-none bg-white; */
90
+ /* position: absolute;
91
+ top: 0;
92
+ left: 0;
93
+ width: 100vw;
94
+ height: 100vh;
95
+ display: flex;
96
+ place-content: center;
97
+ place-items: center;
98
+ touch-action: none;
99
+ background-color: white; */
100
+ }
101
+
102
+ .text {
103
+ max-width: 380px;
104
+ margin: 0 16px;
105
+ text-align: center;
106
+ }
107
+ </style>
frontend/src/lib/Canvas.svelte CHANGED
@@ -1,103 +1,51 @@
1
  <script lang="ts">
2
- import Cursor from '$lib/Cursor.svelte';
3
- import type { Room } from '@liveblocks/client';
4
- import { onDestroy } from 'svelte';
5
- /**
6
- * The main Liveblocks code for the example.
7
- * Check in src/routes/index.svelte to see the setup code.
8
- */
9
-
10
- export let room: Room;
11
-
12
- // Get initial values for presence and others
13
- let myPresence = room.getPresence();
14
- let others = room.getOthers();
15
-
16
- // Subscribe to further changes
17
- const unsubscribeMyPresence = room.subscribe('my-presence', (presence) => {
18
- myPresence = presence;
19
- });
20
-
21
- const unsubscribeOthers = room.subscribe('others', (otherUsers) => {
22
- others = otherUsers;
23
- });
24
-
25
- // Unsubscribe when unmounting
26
- onDestroy(() => {
27
- unsubscribeMyPresence();
28
- unsubscribeOthers();
 
 
 
29
  });
30
 
31
- // Update cursor presence to current pointer location
32
- function handlePointerMove(event: PointerEvent) {
33
- event.preventDefault();
34
- room.updatePresence({
35
- cursor: {
36
- x: Math.round(event.clientX),
37
- y: Math.round(event.clientY)
38
- }
39
  });
40
  }
41
-
42
- // When the pointer leaves the page, set cursor presence to null
43
- function handlePointerLeave() {
44
- room.updatePresence({
45
- cursor: null
46
- });
47
- }
48
-
49
- const COLORS = [
50
- '#E57373',
51
- '#9575CD',
52
- '#4FC3F7',
53
- '#81C784',
54
- '#FFF176',
55
- '#FF8A65',
56
- '#F06292',
57
- '#7986CB'
58
- ];
59
  </script>
60
 
61
- <main on:pointerleave={handlePointerLeave} on:pointermove={handlePointerMove}>
62
- <!-- Show the current user's cursor location -->
63
- <div class="text">
64
- {myPresence?.cursor
65
- ? `${myPresence.cursor.x} × ${myPresence.cursor.y}`
66
- : 'Move your cursor to broadcast its position to other people in the room.'}
67
- </div>
68
-
69
- <!-- When others connected, iterate through others and show their cursors -->
70
- {#if others}
71
- {#each [...others] as { connectionId, presence } (connectionId)}
72
- {#if presence?.cursor}
73
- <Cursor
74
- color={COLORS[connectionId % COLORS.length]}
75
- x={presence.cursor.x}
76
- y={presence.cursor.y}
77
- />
78
- {/if}
79
- {/each}
80
- {/if}
81
- </main>
82
 
83
  <style lang="postcss" scoped>
84
- main {
85
- @apply fixed top-0 left-0 w-screen h-screen flex flex-col items-center justify-center touch-none bg-white;
86
- /* position: absolute;
87
- top: 0;
88
- left: 0;
89
- width: 100vw;
90
- height: 100vh;
91
- display: flex;
92
- place-content: center;
93
- place-items: center;
94
- touch-action: none;
95
- background-color: white; */
96
- }
97
-
98
- .text {
99
- max-width: 380px;
100
- margin: 0 16px;
101
- text-align: center;
102
  }
103
  </style>
 
1
  <script lang="ts">
2
+ import { zoom, zoomIdentity } from 'd3-zoom';
3
+ import { select, type Selection } from 'd3-selection';
4
+ import { onMount, tick } from 'svelte';
5
+
6
+ const width = 512 * 2;
7
+ const height = 512 * 2;
8
+
9
+ let canvasEl: HTMLCanvasElement;
10
+ let canvasCtx: CanvasRenderingContext2D;
11
+
12
+ const margin = { top: 50, right: 50, bottom: 50, left: 50 };
13
+ const extent = [
14
+ [margin.left, margin.top],
15
+ [width - margin.right, height - margin.top]
16
+ ] as [[number, number], [number, number]];
17
+
18
+ const zoomHandler = zoom()
19
+ .scaleExtent([0.5, 2])
20
+ // .translateExtent(extent)
21
+ .extent(extent)
22
+ .on('zoom', zoomed);
23
+
24
+ onMount(() => {
25
+ select(canvasEl.parentElement)
26
+ .call(zoomHandler as any)
27
+ .call(zoomHandler.transform as any, zoomIdentity);
28
+ canvasCtx = canvasEl.getContext('2d') as CanvasRenderingContext2D;
29
+ canvasCtx.fillStyle = 'red';
30
+ canvasCtx.rect(100, 100, 500, 500);
31
+ canvasCtx.fill();
32
  });
33
 
34
+ function zoomed(e: Event) {
35
+ const transform = e.transform;
36
+ console.log(canvasEl.style.transform, transform);
37
+ tick().then(() => {
38
+ canvasEl.style.transform = `translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`;
 
 
 
39
  });
40
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  </script>
42
 
43
+ <div class="fixed w-screen h-screen top-0 left-0 overflow-hidden border-4 border-black">
44
+ <canvas bind:this={canvasEl} {width} {height} />
45
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  <style lang="postcss" scoped>
48
+ canvas {
49
+ transform-origin: 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
  </style>
frontend/src/lib/store.ts CHANGED
@@ -5,7 +5,14 @@ import { browser } from '$app/environment';
5
  export const loadingState = writable<string>('');
6
  export const isLoading = writable<boolean>(false);
7
 
8
- const initialUser: User = crypto.randomUUID();
 
 
 
 
 
 
 
9
 
10
  export const currentUser = writable<User>(
11
  browser ? JSON.parse(localStorage['user'] || JSON.stringify(initialUser)) : initialUser
 
5
  export const loadingState = writable<string>('');
6
  export const isLoading = writable<boolean>(false);
7
 
8
+ let initialUser: User;
9
+ if (typeof crypto['randomUUID'] === 'undefined') {
10
+ initialUser = (1e7 + '').replace(/\d/g, (c) =>
11
+ (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
12
+ );
13
+ } else {
14
+ initialUser = crypto.randomUUID();
15
+ }
16
 
17
  export const currentUser = writable<User>(
18
  browser ? JSON.parse(localStorage['user'] || JSON.stringify(initialUser)) : initialUser
frontend/src/routes/+page.svelte CHANGED
@@ -6,14 +6,14 @@
6
  import { createClient } from '@liveblocks/client';
7
  import { currentUser } from '$lib/store';
8
 
9
- import Canvas from '$lib/Canvas.svelte';
10
  import type { Presence, Storage } from '$lib/types';
11
-
12
  const apiUrl =
13
  PUBLIC_DEV_MODE === 'DEV'
14
  ? 'http://localhost:7860'
15
  : '/embed/huggingface-projects/color-palette-generator-sd';
16
-
17
  let client: Client;
18
  let room: Room;
19
  let roomId = 'sveltekit-live-cursors';
@@ -42,27 +42,29 @@
42
  });
43
  </script>
44
 
45
- <div class="max-w-screen-md mx-auto px-3 py-8 relative z-0">
46
- <h1 class="text-3xl font-bold leading-normal">Stable Diffussion Outpainting Multiplayer</h1>
47
- <p class="text-sm" />
48
- <div class="relative top-0 z-50 bg-white dark:bg-black py-3">
49
- <form class="grid grid-cols-6">
50
- <input
51
- class="input"
52
- placeholder="A photo of a beautiful sunset in San Francisco"
53
- title="Input prompt to generate image and obtain palette"
54
- type="text"
55
- name="prompt"
56
- disabled={$isLoading}
57
- />
58
- <button class="button" disabled={$isLoading} title="Generate Palette">
59
- Create Palette
60
- </button>
61
- </form>
 
 
62
  </div>
63
- <div class="relative">
64
  {#if room}
65
- <Canvas {room} />
66
  {/if}
67
  </div>
68
  </div>
 
6
  import { createClient } from '@liveblocks/client';
7
  import { currentUser } from '$lib/store';
8
 
9
+ import App from '$lib/App.svelte';
10
  import type { Presence, Storage } from '$lib/types';
11
+ console.log('PUBLIC_DEV_MODE', PUBLIC_DEV_MODE);
12
  const apiUrl =
13
  PUBLIC_DEV_MODE === 'DEV'
14
  ? 'http://localhost:7860'
15
  : '/embed/huggingface-projects/color-palette-generator-sd';
16
+ console.log(apiUrl);
17
  let client: Client;
18
  let room: Room;
19
  let roomId = 'sveltekit-live-cursors';
 
42
  });
43
  </script>
44
 
45
+ <div class="max-w-screen-md mx-auto px-3 py-8 relative">
46
+ <div class="relative z-10">
47
+ <h1 class="text-3xl font-bold leading-normal">Stable Diffussion Outpainting Multiplayer</h1>
48
+ <p class="text-sm" />
49
+ <div class="relative bg-white dark:bg-black py-3">
50
+ <form class="grid grid-cols-6">
51
+ <input
52
+ class="input"
53
+ placeholder="A photo of a beautiful sunset in San Francisco"
54
+ title="Input prompt to generate image and obtain palette"
55
+ type="text"
56
+ name="prompt"
57
+ disabled={$isLoading}
58
+ />
59
+ <button class="button" disabled={$isLoading} title="Generate Palette">
60
+ Create Palette
61
+ </button>
62
+ </form>
63
+ </div>
64
  </div>
65
+ <div class="relative z-0">
66
  {#if room}
67
+ <App {room} />
68
  {/if}
69
  </div>
70
  </div>
frontend/vite.config.dev.ts CHANGED
@@ -4,6 +4,7 @@ import type { UserConfig } from 'vite';
4
  const config: UserConfig = {
5
  plugins: [sveltekit()],
6
  server: {
 
7
  proxy: {
8
  '/moon': {
9
  target: 'https://huggingface.co',
 
4
  const config: UserConfig = {
5
  plugins: [sveltekit()],
6
  server: {
7
+ host: "0.0.0.0",
8
  proxy: {
9
  '/moon': {
10
  target: 'https://huggingface.co',