A draggable, pannable canvas for organizing content as overlapping cards. Perfect for bibliographies, knowledge management, and visual tracking.
A spatial canvas is a drag-and-drop workspace where content lives as overlapping cards. Instead of a linear list, you arrange papers, articles, and demos spatially—like pinning notes to a physical board, but digital.
Why spatial?
- Visual clustering — Group related cards by topic or theme
- Non-linear exploration — Follow your intuition, not a rigid list
- Persistent memory — Your arrangement saves automatically, so you can pick up where you left off
| Feature | Description |
|---|---|
| Draggable Cards | Grab any card and move it anywhere on the canvas |
| Pan Navigation | Drag the background to explore your space |
| Auto Z-Index | Hover over a card for 150ms to bring it to front |
| Persistent Layout | Your arrangement is saved to cookies automatically |
| Dark Theme | Dracula-inspired palette for comfortable reading |
| GitHub Pages Ready | Deploy with one build command |
- Click "Use this template" on GitHub
- Clone your new repository:
git clone https://github.com/your-username/spatial-canvas.git cd spatial-canvas - Install dependencies:
npm install
- Run locally:
npm run dev
- Go to your repository Settings → Pages
- Under "Build and deployment", select Source: GitHub Actions
- Push to
master— GitHub automatically builds and deploys!
That's it. Every push to master triggers a deployment.
npm run buildThen in GitHub Settings → Pages:
- Source: Deploy from a branch
- Branch:
master/distfolder
npm install
npm run devnpm run buildEdit src/data/initialCards.ts:
{
id: 'c1',
x: 100, // horizontal position
y: 200, // vertical position
zIndex: 1, // stacking order (leave as 1)
title: 'Paper Title',
description: 'Brief description of the paper.',
type: 'article', // 'article' or 'demo'
link: 'https://arxiv.org/abs/...',
}Colors are defined in tailwind.config.js under the dracula key. Modify the hex values to match your brand.
The canvas bounds are set in src/components/Canvas.tsx. Update the w-[1400px] h-[900px] classes to fit your content.
| Technology | Purpose |
|---|---|
| React | UI framework |
| Zustand | Lightweight state management |
| Tailwind CSS | Utility-first styling |
| Vite | Fast build tool |
| TypeScript | Type safety |
src/
├── components/
│ ├── Canvas.tsx # Main canvas with pan/drag handling
│ ├── Card.tsx # Draggable card
│ └── ResetButton.tsx # Restore default layout
├── store/
│ └── canvasStore.ts # Zustand store + cookie persistence
├── data/
│ └── initialCards.ts # Default card definitions
├── hooks/
│ └── useCardDrag.ts # Drag interaction logic
└── index.css # Tailwind + custom styles
Contributions welcome! Whether it's fixing bugs, adding features, or improving docs:
- Fork and create a branch:
git checkout -b feat/your-feature - Make your changes
- Run
npm run lintto check for issues - Commit with a clear message
- Open a pull request
This project is available under CC BY 4.0 (Creative Commons Attribution 4.0).
You are free to:
- ✅ Use for personal or commercial projects
- ✅ Modify to suit your needs
- ✅ Share with others
You must:
- 📝 Credit Jonna Matthiesen as the original author
See creativecommons.org/licenses/by/4.0 for details.
- Dracula Theme — Beautiful dark color palette
- Zustand — Minimal state management
- All who use and contribute to this template