Commit graph

13 commits

Author SHA1 Message Date
Danila Poyarkov 1ffc61cf50 fix(text): bundle Inter ExtraBold font 2026-05-18 00:59:05 +03:00
Danila Poyarkov 66f562b52f fix(fonts): bundle Inter bold 2026-05-13 03:50:35 +03:00
Tem-man 1e2df31636
fix(core): improve CJK font fallback loading
- Allow CJK fallback loading to use local variable system fonts
- Add Windows CJK fallback families
- Harden CanvasKit WASM asset resolution and serving
2026-05-05 18:39:39 +03:00
Danila Poyarkov 63d3f2e0cb fix(kiwi): improve figma export fidelity 2026-04-25 15:57:15 +03:00
Mahmoud Almontasser 9ed102b706 feat: add Arabic and RTL support 2026-03-29 11:42:30 +02:00
Anton Soldatov 168c25c189
feat: mobile layout, PWA support (#27) (#27)
- Mobile-responsive editor with bottom drawer, ribbon nav, HUD overlay
- Touch support: single-finger tools, two-finger pinch-zoom
- PWA: manifest, service worker, installability
- Extract LayerTree from LayersPanel, shared utils (colorToCSS, initials, toolIcons)
- Constants moved to src/constants.ts, clipboard state to editor store
- reka-ui Popover/DropdownMenu in MobileHud

Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-03-05 19:51:51 +03:00
Danila Poyarkov 76134ccc1a Collab UI polish, vue-router, extract HsvColorArea
- Move CollabPanel to right panel header (like Figma)
- /share/:roomId shows join dialog with name input before connecting
- Add vue-router with / and /share/:roomId routes
- Extract EditorView from App.vue
- Extract HsvColorArea component from ColorPicker + FillPicker
  (eliminates ~160 lines of duplicated HSV logic)
- Extract syncNodePropsToYMap in use-collab.ts
- Register Yjs update listener before opening WebSocket (fix race)
- Scrollable AppMenu without scrollbar (scrollbar-none utility)
- Overflow-x hidden on LayersPanel
- Gitignore .wrangler build artifacts
- SPA catch-all redirect for Cloudflare Pages
2026-03-01 17:15:08 +03:00
Danila Poyarkov 2add3ac4c0 Real-time collaboration with Yjs CRDT over Cloudflare Durable Objects
- Cloudflare Worker + Durable Object server (packages/collab/)
  - One DO per room with WebSocket Hibernation for near-zero idle cost
  - Yjs sync protocol for document state (CRDT merge)
  - Yjs awareness protocol for cursors, selection, presence
  - Persists doc state to DO storage
  - CORS headers for cross-origin WebSocket upgrade

- Client composable (src/composables/use-collab.ts)
  - Y.Doc ↔ SceneGraph bidirectional binding
  - Awareness: broadcasts cursor position, selection, name, color
  - Auto-join from /share/:roomId URL
  - Suppresses echo loops between Yjs and graph updates

- CollabPanel component (src/components/CollabPanel.vue)
  - Share button generates room link, copies to clipboard
  - Join flow: paste link or room ID
  - Avatar stack with colored initials and tooltips
  - Name input persisted to localStorage

- Remote cursor rendering in CanvasKit
  - Colored arrow cursor + name label pill per remote peer
  - Remote selection outlines in peer's color
  - Only shows cursors on the same page

- SPA redirect for /share/* routes (Cloudflare Pages _redirects)
2026-03-01 16:44:37 +03:00
Danila Poyarkov 503a561753 Symlink favicons from desktop/icons, add all sizes for Safari/Chrome
.ico (any), 32px PNG, 128px PNG, apple-touch-icon (512px).
Symlinks instead of copies so icons stay in sync.
2026-03-01 15:46:31 +03:00
Danila Poyarkov f8f85970e1 Add favicon, persist banner dismissal in localStorage 2026-03-01 15:44:25 +03:00
Danila Poyarkov dc3c5a47b1 Fix .fig import/export round-trip
- Parse fig-kiwi container format properly: strip header, extract
  schema and data chunks, decompress (Zstd or deflate)
- Import uses the schema embedded in the fig-kiwi container (supports
  newer Figma files with unknown fields)
- Export uses the codec's schema via getCompiledSchema/getSchemaBytes
- Consolidate schema loading: remove duplicate figma-schema.bin fetch
  from clipboard and export; both now use codec's initCodec()
- Fix IS_TAURI for non-browser environments (SSR/Bun)
2026-02-28 15:12:24 +03:00
Danila Poyarkov 155f7b3af1 Encode fig-kiwi binary on copy for Figma paste compatibility
Copy now produces actual fig-kiwi binary (Kiwi schema + encoded
Message with NodeChanges) matching Figma's clipboard format. Schema
is bundled as public/figma-schema.bin (28KB deflated, 540 defs)
and prefetched on app init.

Dual clipboard: synchronous OpenPencil internal format written via
clipboardData.setData, then navigator.clipboard.write overwrites
with combined HTML containing both (figma) and (openpencil) markers.
Paste checks our format first, falls back to Figma decode.
2026-02-27 23:31:01 +03:00
Danila Poyarkov 7139546cb5 Add text editing with Paragraph API and inline overlay
Font loading:
- Inter Regular font bundled (342KB TTF)
- TypefaceFontProvider for Paragraph API
- MakeFreeTypeFaceFromData for Font object
- Fonts load async, fallback to drawText before ready

Text rendering:
- ParagraphBuilder with font family, size, letter spacing,
  line height, text alignment
- Multi-line text wraps to node width
- Text nodes render at correct position in local space

Inline editing:
- Double-click text node → HTML textarea overlay
- Positioned/sized to match node on canvas (zoom-aware)
- Live updates to scene graph on input
- Escape or blur commits edit
- Keyboard events stop propagation during editing
- Text cursor for TEXT tool
2026-02-27 22:57:39 +03:00