diff --git a/.prettierrc b/.prettierrc index 9573023..20c211a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,6 @@ "trailingComma": "none", "printWidth": 100, "plugins": ["prettier-plugin-svelte"], - "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] + "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }], + "bracketSameLine": true } diff --git a/bun.lockb b/bun.lockb index 5e87b52..f7ea78b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index f165e8e..bd86d69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@selenite/commons", - "version": "0.1.4", + "version": "0.2.1", "scripts": { "dev": "vite dev", "build": "vite build && npm run package", @@ -36,16 +36,19 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint": "^8.56.7", "@types/lodash-es": "^4.17.12", + "autoprefixer": "^10.4.19", "eslint": "^9.0.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.36.0", "globals": "^15.0.0", "lodash-es": "^4.17.21", + "postcss": "^8.4.39", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.1.2", "publint": "^0.1.9", "svelte": "^5.0.0-next.1", "svelte-check": "^3.6.0", + "tailwindcss": "^3.4.4", "tslib": "^2.4.1", "typescript": "^5.0.0", "typescript-eslint": "^8.0.0-alpha.20", diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/src/app.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/src/app.html b/src/app.html index f22aeaa..de8f7a8 100644 --- a/src/app.html +++ b/src/app.html @@ -6,7 +6,7 @@ %sveltekit.head% - -
%sveltekit.body%
+ +
%sveltekit.body%
diff --git a/src/lib/actions/canvas.ts b/src/lib/actions/canvas.ts new file mode 100644 index 0000000..94b26a1 --- /dev/null +++ b/src/lib/actions/canvas.ts @@ -0,0 +1,64 @@ +import { lerp } from '$lib/utils'; +import type { Action } from 'svelte/action'; + +export type Transform = { x: number; y: number; k: number }; + +function drawLines({ + canvas, + transform, + spacing: baseSpacing = 80 + }: { + canvas: HTMLCanvasElement; + + transform: Transform; + spacing?: number; + }) { + if (transform.k < 0.01) return; + const ctx = canvas.getContext('2d'); + if (!ctx) { + throw new Error('Canvas is not a 2d canvas.'); + } + ctx.save(); + ctx.beginPath(); + const scalingFactor = Math.floor(1 + -Math.log(transform.k) / Math.log(3)); + const spacing = scalingFactor > 0 ? baseSpacing * scalingFactor : baseSpacing; + console.log('spacing\t', spacing); + const step = spacing * transform.k; + console.log('zoom\t', transform.k); + // Draw vertical lines + for (let x = (transform.x % step) - step; x <= canvas.width; x += step) { + ctx.moveTo(x, 0); + ctx.lineTo(x, canvas.height); + } + + // Draw horizontal lines + for (let y = (transform.y % step) - step; y <= canvas.height; y += step) { + ctx.moveTo(0, y); + ctx.lineTo(canvas.width, y); + } + // Stroke the lines + ctx.strokeStyle = '#ddd'; + ctx.lineWidth = transform.k > 0.1 ? 0.08 : lerp(0.08, 0, (transform.k - 0.01) / 0.09); + ctx.stroke(); + ctx.restore(); + } + +export const gridLines: Action = ( + canvas, + params +) => { + const ctx = canvas.getContext('2d'); + if (!ctx) { + throw new Error('Canvas is not a 2d canvas.'); + } + + drawLines({ ...params, canvas }); + + return { + destroy() {}, + update(params) { + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawLines({ canvas, ...params }); + } + }; +}; diff --git a/src/lib/actions/index.ts b/src/lib/actions/index.ts index 00f349a..007994c 100644 --- a/src/lib/actions/index.ts +++ b/src/lib/actions/index.ts @@ -1,6 +1,7 @@ import type { Action } from 'svelte/action'; export * from './focusTrap.js' export * from './shortcut.js' +export * from './canvas.js' let handleFocusLeaveRefCount = 0; let handleFocusLeaveCallbacks: ((isKeyboard: boolean) => void)[] = []; function handleKeydown(e: KeyboardEvent) { diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 3e63952..d464d98 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -4,7 +4,7 @@ export * from './string.js'; export * from './eventListeners.js'; export * from './array/index.js' - +export * from './math.js' export { v4 as uuidv4 } from 'uuid'; import {v4 as uuid} from 'uuid' let idCount = 0; diff --git a/src/lib/utils/math.ts b/src/lib/utils/math.ts new file mode 100644 index 0000000..b64a4d4 --- /dev/null +++ b/src/lib/utils/math.ts @@ -0,0 +1,3 @@ +export function lerp(start: number, end: number, alpha: number) { + return start + (end - start) * alpha; +} \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..093ea88 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,18 @@ + +
+ +
+ + \ No newline at end of file diff --git a/src/routes/canvas/+page.svelte b/src/routes/canvas/+page.svelte new file mode 100644 index 0000000..88bfa48 --- /dev/null +++ b/src/routes/canvas/+page.svelte @@ -0,0 +1,43 @@ + + + + +
+ +
+ + diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..d4be033 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{html,js,ts,svelte}'], + theme: { + extend: {} + }, + plugins: [] +}; + diff --git a/tsconfig.json b/tsconfig.json index 6f788f1..815029b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "module": "NodeNext", - "moduleResolution": "NodeNext" + "module": "ES2022", + "moduleResolution": "Bundler" } }