mirror of
https://github.com/ZSeven-W/openpencil.git
synced 2026-05-31 19:04:29 +07:00
chore: update documentation and add MIT License
Enhance CLAUDE.md with detailed architecture, key modules, and AI configuration. Introduce LICENSE file with MIT License terms. Remove obsolete Header component to streamline the codebase.
This commit is contained in:
parent
89e9279244
commit
5abc432396
4 changed files with 66 additions and 89 deletions
29
CLAUDE.md
29
CLAUDE.md
|
|
@ -14,9 +14,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Architecture
|
||||
|
||||
OpenPencil is an open-source vector design tool (alternative to Pencil.dev) with a Design-as-Code philosophy. Built as a **TanStack Start** full-stack React application with Bun runtime.
|
||||
OpenPencil is an open-source vector design tool (alternative to Pencil.dev) with a Design-as-Code philosophy. Built as a **TanStack Start** full-stack React application with Bun runtime. Server API powered by **Nitro**.
|
||||
|
||||
**Key technologies:** React 19, Fabric.js v7 (canvas engine), Zustand v5 (state management), TanStack Router (file-based routing), Tailwind CSS v4, Vite 7, TypeScript (strict mode).
|
||||
**Key technologies:** React 19, Fabric.js v7 (canvas engine), Zustand v5 (state management), TanStack Router (file-based routing), Tailwind CSS v4, shadcn/ui (UI primitives), Vite 7, Nitro (server), TypeScript (strict mode).
|
||||
|
||||
### Data Flow
|
||||
|
||||
|
|
@ -43,12 +43,19 @@ React Components (Toolbar, LayerPanel, PropertyPanel)
|
|||
|
||||
### Key Modules
|
||||
|
||||
- **`src/canvas/`** — Fabric.js integration: canvas init, drawing events, viewport (pan/zoom), selection sync, bidirectional document↔canvas sync, object factory
|
||||
- **`src/stores/`** — Zustand stores: `canvas-store` (UI state), `document-store` (PenDocument tree CRUD)
|
||||
- **`src/types/`** — Type system: `pen.ts` (PenDocument/PenNode), `canvas.ts` (ToolType), `styles.ts` (Fill/Stroke/Effect)
|
||||
- **`src/components/editor/`** — Editor layout, toolbar, tool buttons
|
||||
- **`src/components/panels/`** — Layer panel, property panel with section components
|
||||
- **`src/components/shared/`** — Reusable UI: ColorPicker, NumberInput, SliderInput
|
||||
- **`src/canvas/`** — Fabric.js integration: canvas init, drawing events, viewport (pan/zoom), selection sync, smart guides, bidirectional document↔canvas sync, object factory
|
||||
- **`src/stores/`** — Zustand stores: `canvas-store` (UI/tool/selection/viewport), `document-store` (PenDocument tree CRUD), `history-store` (undo/redo), `ai-store` (chat/code generation state)
|
||||
- **`src/types/`** — Type system: `pen.ts` (PenDocument/PenNode), `canvas.ts` (ToolType), `styles.ts` (Fill/Stroke/Effect), `variables.ts` (VariableDefinition)
|
||||
- **`src/components/editor/`** — Editor layout, toolbar, tool buttons, status bar
|
||||
- **`src/components/panels/`** — Layer panel, property panel (fill/stroke/size/corner-radius/effects/text/appearance sections), AI chat panel, code panel
|
||||
- **`src/components/shared/`** — Reusable UI: ColorPicker, NumberInput, DropdownSelect, ExportDialog, SaveDialog
|
||||
- **`src/components/ui/`** — shadcn/ui primitives: Button, Select, Separator, Slider, Toggle, Tooltip
|
||||
- **`src/services/ai/`** — AI chat service, design prompts, design-to-node generation
|
||||
- **`src/services/codegen/`** — React+Tailwind and HTML+CSS code generators
|
||||
- **`src/hooks/`** — `use-keyboard-shortcuts` (global keyboard event handling)
|
||||
- **`src/lib/`** — Utility functions (`utils.ts` with `cn()` for class merging)
|
||||
- **`src/utils/`** — File operations (save/open .pen), export (PNG/SVG), node clone, pen file normalization, syntax highlight
|
||||
- **`server/api/ai/`** — Nitro server API: `chat.ts` (streaming chat), `generate.ts` (non-streaming generation). Supports Anthropic API key or Claude Agent SDK (local OAuth) as dual providers
|
||||
|
||||
### Fabric.js v7 Gotchas
|
||||
|
||||
|
|
@ -70,7 +77,7 @@ File-based routing via TanStack Router. Routes in `src/routes/`, auto-generated
|
|||
|
||||
### Styling
|
||||
|
||||
Tailwind CSS v4 imported via `src/styles.css`. Icons from `lucide-react`.
|
||||
Tailwind CSS v4 imported via `src/styles.css`. UI primitives from shadcn/ui (`src/components/ui/`). Icons from `lucide-react`. shadcn/ui config in `components.json`.
|
||||
|
||||
## Code Style
|
||||
|
||||
|
|
@ -109,3 +116,7 @@ Tailwind CSS v4 imported via `src/styles.css`. Icons from `lucide-react`.
|
|||
- subject 用英文,小写开头,不加句号,祈使语气(如 `add`、`fix`、`remove`)。
|
||||
- body 可选,解释 **why** 而非 what,可用中英文。
|
||||
- 一个 commit 只做一件事。不要把不相关的改动混在一起。
|
||||
|
||||
## License
|
||||
|
||||
MIT License. See [LICENSE](./LICENSE) for details.
|
||||
|
|
|
|||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 ZSeven—W
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
39
README.md
39
README.md
|
|
@ -14,7 +14,7 @@ Open-source vector design tool with a Design-as-Code philosophy. An alternative
|
|||
- **File operations**: Save/open .pen files (JSON-based, Git-friendly), auto-save support
|
||||
- **Export**: PNG and SVG export with scale options (Cmd+Shift+E)
|
||||
- **Code generation**: Generate React+Tailwind or HTML+CSS code from designs (Cmd+Shift+C)
|
||||
- **AI assistant**: Built-in AI chat panel for design assistance (Cmd+J)
|
||||
- **AI assistant**: Built-in AI chat panel for design assistance (Cmd+J), supports Anthropic API or local Claude Code
|
||||
- **Keyboard shortcuts**: Tool keys (V/R/O/L/T/F/H), Delete, arrow nudge, bracket keys for z-order, Cmd+A select all
|
||||
|
||||
## Tech Stack
|
||||
|
|
@ -22,8 +22,10 @@ Open-source vector design tool with a Design-as-Code philosophy. An alternative
|
|||
- **Framework:** [TanStack Start](https://tanstack.com/start) (React 19, SSR, file-based routing)
|
||||
- **Canvas:** [Fabric.js](http://fabricjs.com/) v7
|
||||
- **State:** [Zustand](https://zustand-demo.pmnd.rs/) v5
|
||||
- **UI:** [shadcn/ui](https://ui.shadcn.com/) (Radix + Tailwind primitives)
|
||||
- **Styling:** [Tailwind CSS](https://tailwindcss.com/) v4
|
||||
- **Icons:** [Lucide React](https://lucide.dev/)
|
||||
- **Server:** [Nitro](https://nitro.build/) (API routes)
|
||||
- **Runtime:** [Bun](https://bun.sh/)
|
||||
- **Build:** [Vite](https://vite.dev/) 7
|
||||
|
||||
|
|
@ -36,6 +38,13 @@ bun --bun run dev
|
|||
|
||||
Open http://localhost:3000 and click "New Design" to enter the editor.
|
||||
|
||||
### AI Configuration
|
||||
|
||||
The AI assistant works in two modes:
|
||||
|
||||
- **Anthropic API**: Set `ANTHROPIC_API_KEY` in `.env`
|
||||
- **Local Claude Code**: No config needed — uses Claude Agent SDK with OAuth login as fallback
|
||||
|
||||
## Scripts
|
||||
|
||||
| Command | Description |
|
||||
|
|
@ -49,21 +58,23 @@ Open http://localhost:3000 and click "New Design" to enter the editor.
|
|||
|
||||
```
|
||||
src/
|
||||
canvas/ # Fabric.js canvas engine, drawing, sync, guides
|
||||
canvas/ # Fabric.js canvas engine, drawing, sync, guides
|
||||
components/
|
||||
editor/ # Editor layout, toolbar
|
||||
panels/ # Layer panel, property panel, AI chat, code panel
|
||||
shared/ # Reusable UI (ColorPicker, NumberInput, ExportDialog, etc.)
|
||||
hooks/ # Keyboard shortcuts
|
||||
editor/ # Editor layout, toolbar, status bar
|
||||
panels/ # Layer panel, property panel, AI chat, code panel
|
||||
shared/ # Reusable UI (ColorPicker, NumberInput, ExportDialog, etc.)
|
||||
ui/ # shadcn/ui primitives (Button, Select, Slider, etc.)
|
||||
hooks/ # Keyboard shortcuts
|
||||
lib/ # Utility functions (cn class merging)
|
||||
services/
|
||||
ai/ # AI chat service, prompts, design generation
|
||||
codegen/ # React and HTML code generators
|
||||
stores/ # Zustand stores (canvas, document, history, AI)
|
||||
types/ # PenDocument/PenNode types, style types
|
||||
utils/ # File operations, export, node clone, syntax highlight
|
||||
routes/ # TanStack Router pages (/, /editor)
|
||||
ai/ # AI chat service, prompts, design generation
|
||||
codegen/ # React+Tailwind and HTML+CSS code generators
|
||||
stores/ # Zustand stores (canvas, document, history, AI)
|
||||
types/ # PenDocument/PenNode types, style types, variables
|
||||
utils/ # File operations, export, node clone, syntax highlight
|
||||
routes/ # TanStack Router pages (/, /editor)
|
||||
server/
|
||||
api/ # Server-side API endpoints
|
||||
api/ai/ # Nitro API: streaming chat, AI generation
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
|
|
@ -77,4 +88,4 @@ server/
|
|||
|
||||
## License
|
||||
|
||||
MIT
|
||||
[MIT](./LICENSE)
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
import { Link } from '@tanstack/react-router'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { Home, Menu, X } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
export default function Header() {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="p-4 flex items-center bg-card text-foreground border-b border-border">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setIsOpen(true)}
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu size={20} />
|
||||
</Button>
|
||||
<h1 className="ml-4 text-xl font-semibold">
|
||||
<Link to="/">
|
||||
<img
|
||||
src="/tanstack-word-logo-white.svg"
|
||||
alt="TanStack Logo"
|
||||
className="h-10"
|
||||
/>
|
||||
</Link>
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<aside
|
||||
className={`fixed top-0 left-0 h-full w-80 bg-background text-foreground shadow-2xl z-50 transform transition-transform duration-300 ease-in-out flex flex-col ${
|
||||
isOpen ? 'translate-x-0' : '-translate-x-full'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between p-4 border-b border-border">
|
||||
<h2 className="text-xl font-bold">Navigation</h2>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setIsOpen(false)}
|
||||
aria-label="Close menu"
|
||||
>
|
||||
<X size={20} />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<nav className="flex-1 p-4 overflow-y-auto">
|
||||
<Link
|
||||
to="/"
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="flex items-center gap-3 p-3 rounded-lg hover:bg-accent transition-colors mb-2"
|
||||
activeProps={{
|
||||
className:
|
||||
'flex items-center gap-3 p-3 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors mb-2',
|
||||
}}
|
||||
>
|
||||
<Home size={20} />
|
||||
<span className="font-medium">Home</span>
|
||||
</Link>
|
||||
</nav>
|
||||
</aside>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in a new issue