diff --git a/index.html b/index.html index 1781066..8b07c4c 100644 --- a/index.html +++ b/index.html @@ -9,19 +9,7 @@ - - -
- - -
- - - - +
diff --git a/package-lock.json b/package-lock.json index 5082dce..54c14c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,40 @@ "@automerge/automerge-repo": "^1.2.1", "@automerge/automerge-repo-network-websocket": "^1.2.1", "@automerge/automerge-repo-storage-indexeddb": "^1.2.1", + "svelte": "^5.0.0-next.272", "vite-plugin-top-level-await": "^1.4.4", "vite-plugin-wasm": "^3.4.1" }, "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^5.0.3", + "@types/node": "^20.0.0", + "typescript": "^5.0.0", "vite": "^6.0.5" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ampproject/remapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@automerge/automerge": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-2.2.8.tgz", @@ -558,6 +585,30 @@ "node": ">=18" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -567,6 +618,15 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -859,6 +919,46 @@ "win32" ] }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.0.3.tgz", + "integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", + "debug": "^4.4.0", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.15", + "vitefu": "^1.0.4" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz", + "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.7" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "svelte": "^5.0.0", + "vite": "^6.0.0" + } + }, "node_modules/@swc/core": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.4.tgz", @@ -1103,13 +1203,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", - "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", + "version": "20.17.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.14.tgz", + "integrity": "sha512-w6qdYetNL5KRBiSClK/KWai+2IMEJuAj+EujKCumalFOwXtvOXaEan9AuwcRID2IcOIAWSIfR495hBtgKlx2zg==", "license": "MIT", - "peer": true, "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~6.19.2" } }, "node_modules/acorn": { @@ -1124,6 +1223,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-typescript": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz", + "integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==", + "license": "MIT", + "peerDependencies": { + "acorn": ">=8.9.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", @@ -1142,6 +1250,24 @@ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "license": "MIT" }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/base-x": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", @@ -1198,6 +1324,15 @@ "cbor-extract": "^2.2.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -1221,6 +1356,16 @@ } } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -1280,6 +1425,21 @@ "@esbuild/win32-x64": "0.24.2" } }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/esrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.3.tgz", + "integrity": "sha512-Xddc1RsoFJ4z9nR7W7BFaEPIp4UXoeQ0+077UdWLxbafMQFyU79sQJMk7kxNgRwQ9/aVgaKacCHC2pUACGwmYw==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -1306,6 +1466,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, "node_modules/isomorphic-ws": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", @@ -1315,6 +1484,31 @@ "ws": "*" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -1441,6 +1635,31 @@ "node": ">=0.10.0" } }, + "node_modules/svelte": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.18.0.tgz", + "integrity": "sha512-/Eb81lB8bVUxQPmkPVNBYrU9cZ544+9hE91ZUUXTMf7eWcGW84N1hS3gvv/XsUNOWLLg3IicXP2qa8W3KpTUHA==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "acorn-typescript": "^1.4.13", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^1.4.3", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", @@ -1495,7 +1714,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1505,11 +1723,10 @@ } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "license": "MIT", - "peer": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/uuid": { "version": "9.0.1", @@ -1637,6 +1854,25 @@ "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, + "node_modules/vitefu": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.5.tgz", + "integrity": "sha512-h4Vflt9gxODPFNGPwp4zAMZRpZR7eslzwH2c5hn5kNZ5rhnKyRJ50U+yGCdc2IRaBs8O4haIgLNGrV5CrpMsCA==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", @@ -1676,6 +1912,12 @@ "engines": { "node": ">=6" } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", + "license": "MIT" } } } diff --git a/package.json b/package.json index 6fc8e9b..7cf66bf 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,16 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^6.0.5", + "@sveltejs/vite-plugin-svelte": "^5.0.3", + "@types/node": "^20.0.0", "typescript": "^5.0.0", - "@types/node": "^20.0.0" + "vite": "^6.0.5" }, "dependencies": { "@automerge/automerge-repo": "^1.2.1", "@automerge/automerge-repo-network-websocket": "^1.2.1", "@automerge/automerge-repo-storage-indexeddb": "^1.2.1", + "svelte": "^5.0.0-next.272", "vite-plugin-top-level-await": "^1.4.4", "vite-plugin-wasm": "^3.4.1" } diff --git a/src/components/Canvas.svelte b/src/components/Canvas.svelte new file mode 100644 index 0000000..3d1075c --- /dev/null +++ b/src/components/Canvas.svelte @@ -0,0 +1,116 @@ + + +
+ draggedShape = null} + on:mousemove={handleDragMove} + > + {#each shapes as shape (shape.id)} + {#if shape.type === 'circle'} + handleDragStart(e, shape)} + /> + {:else if shape.type === 'triangle'} + [c.x, c.y]).flat() as [number, number, number, number, number, number]} + color={shape.color} + on:mousedown={(e: MouseEvent) => handleDragStart(e, shape)} + /> + {/if} + {/each} + + +
+ + +
+
+ + \ No newline at end of file diff --git a/src/components/shapes/Circle.svelte b/src/components/shapes/Circle.svelte new file mode 100644 index 0000000..bb56486 --- /dev/null +++ b/src/components/shapes/Circle.svelte @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/components/shapes/Triangle.svelte b/src/components/shapes/Triangle.svelte new file mode 100644 index 0000000..d8bd2b3 --- /dev/null +++ b/src/components/shapes/Triangle.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/docManager.ts b/src/docManager.ts index 8959e16..c70e2d4 100644 --- a/src/docManager.ts +++ b/src/docManager.ts @@ -19,26 +19,21 @@ export async function initRepo(): Promise> { if (rootDocUrl && isValidAutomergeUrl(rootDocUrl)) { handle = repo.find(rootDocUrl); - await handle.whenReady(); - - handle.change((doc: AppDocument) => { - if (!doc.schemaVersion) { - doc.schemaVersion = 1; - } - }); } else { - handle = repo.create({ - schemaVersion: CURRENT_SCHEMA_VERSION, - shapes: [] + handle = repo.create(); + handle.change((doc: AppDocument) => { + doc.schemaVersion = CURRENT_SCHEMA_VERSION; + doc.shapes = []; }); - await handle.whenReady(); document.location.hash = handle.url; } + await handle.whenReady(); return handle; } -export const updateDocWithNewCircle = (x: number, y: number, radius: number) => { +export function updateDocWithNewCircle(x: number, y: number, radius: number): void { + console.log('Adding circle:', { x, y, radius }); // Debug log handle.change((doc: AppDocument) => { const circle: CircleShape = { id: Date.now(), @@ -48,11 +43,15 @@ export const updateDocWithNewCircle = (x: number, y: number, radius: number) => radius, color: "red" }; + if (!doc.shapes) { + doc.shapes = []; + } doc.shapes.push(circle); }); } -export const updateDocWithNewTriangle = (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) => { +export function updateDocWithNewTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void { + console.log('Adding triangle:', { x1, y1, x2, y2, x3, y3 }); // Debug log handle.change((doc: AppDocument) => { const triangle: TriangleShape = { id: Date.now(), @@ -64,6 +63,9 @@ export const updateDocWithNewTriangle = (x1: number, y1: number, x2: number, y2: ], color: "blue" }; + if (!doc.shapes) { + doc.shapes = []; + } doc.shapes.push(triangle); }); } diff --git a/src/main.ts b/src/main.ts index a06cd91..7e993da 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,116 +1,15 @@ -import { initRepo, updateDocWithNewCircle, updateDocWithNewTriangle, updateDocWithShapeMove } from "./docManager"; -import { createOrUpdateShapes } from "./canvasManager"; -import { CircleShape } from "./types"; - -interface Config { - THROTTLE_MS: number; - DEFAULT_SHAPES: { - CIRCLE: Omit; - TRIANGLE: { - x1: number; - y1: number; - x2: number; - y2: number; - x3: number; - y3: number; - }; - }; -} - -const CONFIG: Config = { - THROTTLE_MS: 16, - DEFAULT_SHAPES: { - CIRCLE: { x: 100, y: 100, radius: 30 }, - TRIANGLE: { x1: 200, y1: 200, x2: 220, y2: 220, x3: 180, y3: 220 } - } -}; - -function initDragAndDrop(container: SVGSVGElement): void { - let isDragging = false; - let selectedShapeId: string | null = null; - - const throttledMoveShape = throttle((shapeId: string, x: number, y: number) => { - updateDocWithShapeMove(shapeId, x, y); - }, CONFIG.THROTTLE_MS); - - container.addEventListener("mousedown", (e: MouseEvent) => { - const target = e.target as SVGElement; - if (target instanceof SVGCircleElement || target instanceof SVGPolygonElement) { - isDragging = true; - selectedShapeId = target.id; - } - }); - - container.addEventListener("mousemove", (e: MouseEvent) => { - if (!isDragging || !selectedShapeId) return; - - const svgPoint = getSVGPoint(container, e.clientX, e.clientY); - throttledMoveShape(selectedShapeId, svgPoint.x, svgPoint.y); - }); - - container.addEventListener("mouseup", () => { - isDragging = false; - selectedShapeId = null; - }); -} - -function getSVGPoint(container: SVGSVGElement, x: number, y: number): DOMPoint { - const pt = container.createSVGPoint(); - pt.x = x; - pt.y = y; - const ctm = container.getScreenCTM(); - if (!ctm) { - throw new Error("Could not get screen CTM"); - } - return pt.matrixTransform(ctm.inverse()); -} - -function throttle void>(func: T, limit: number): T { - let inThrottle = false; - return function(this: any, ...args: Parameters) { - if (!inThrottle) { - func.apply(this, args); - inThrottle = true; - setTimeout(() => inThrottle = false, limit); - } - } as T; -} - -async function initApp(): Promise { - const container = document.querySelector("#shapesCanvas") as SVGSVGElement; - if (!container) throw new Error("Canvas container not found"); +import Canvas from './components/Canvas.svelte'; +import { initRepo } from './docManager'; +import { mount } from 'svelte'; +async function initApp() { const handle = await initRepo(); - - const doc = handle.docSync(); - if (!doc) throw new Error("Failed to sync document"); - - createOrUpdateShapes(container, doc.shapes); - - handle.on("change", (change) => { - createOrUpdateShapes(container, change.doc.shapes, change.patches); - }); - - initShapeButtons(); - initDragAndDrop(container); -} - -function initShapeButtons(): void { - const circleButton = document.querySelector("#addCircleButton") as HTMLElement; - const triangleButton = document.querySelector("#addTriangleButton") as HTMLElement; - - if (!circleButton || !triangleButton) { - throw new Error("Shape buttons not found"); - } - - circleButton.addEventListener("click", () => { - const { x, y, radius } = CONFIG.DEFAULT_SHAPES.CIRCLE; - updateDocWithNewCircle(x, y, radius); - }); - - triangleButton.addEventListener("click", () => { - const { x1, y1, x2, y2, x3, y3 } = CONFIG.DEFAULT_SHAPES.TRIANGLE; - updateDocWithNewTriangle(x1, y1, x2, y2, x3, y3); + + mount(Canvas, { + target: document.getElementById('app')!, + props: { + handle + } }); } diff --git a/vite.config.ts b/vite.config.ts index 416f532..ab10530 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from "vite" +import { svelte } from '@sveltejs/vite-plugin-svelte' import wasm from "vite-plugin-wasm" -import topLevelAwait from 'vite-plugin-top-level-await' +import topLevelAwait from "vite-plugin-top-level-await" export default defineConfig({ // customize this to your repo name for github pages deploy @@ -10,10 +11,14 @@ export default defineConfig({ target: "esnext", }, - plugins: [wasm(), topLevelAwait()], + plugins: [ + wasm(), + topLevelAwait(), + svelte() + ], worker: { format: "es", - plugins: () => [wasm()], + plugins: () => [svelte()], }, })