started using Claude Code
This commit is contained in:
152
CLAUDE.md
Normal file
152
CLAUDE.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Labelmaker is a Phoenix LiveView web application that generates text-based images via URL. Users can visit `labelmaker.xyz/Your Text` to instantly get an image with their text, with various customization options (font, color, outline, size). The app is designed for creating decals in Tabletop Simulator.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **Elixir + Phoenix Framework** (Phoenix 1.7+ with LiveView)
|
||||
- **ImageMagick** (`magick` command) for image generation
|
||||
- **Tailwind CSS** for styling
|
||||
- **esbuild** for JavaScript bundling
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Development
|
||||
```sh
|
||||
# Install dependencies and set up assets
|
||||
mix setup
|
||||
|
||||
# Start Phoenix server (runs on http://localhost:4000)
|
||||
mix phx.server
|
||||
|
||||
# Start server with interactive Elixir shell
|
||||
iex -S mix phx.server
|
||||
```
|
||||
|
||||
### Testing
|
||||
```sh
|
||||
# Run all tests
|
||||
mix test
|
||||
|
||||
# Run a specific test file
|
||||
mix test test/labelmaker_web/controllers/label_controller_test.exs
|
||||
|
||||
# Run a specific test
|
||||
mix test test/labelmaker_web/controllers/label_controller_test.exs:42
|
||||
```
|
||||
|
||||
### Assets
|
||||
```sh
|
||||
# Install asset build tools (Tailwind, esbuild)
|
||||
mix assets.setup
|
||||
|
||||
# Build assets for development
|
||||
mix assets.build
|
||||
|
||||
# Build assets for production (minified + digest)
|
||||
mix assets.deploy
|
||||
```
|
||||
|
||||
### Docker
|
||||
```sh
|
||||
docker build -t labelmaker .
|
||||
docker run -p 4000:4000 labelmaker
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Request Flow
|
||||
|
||||
1. **Homepage (`/`)**: `LabelmakerWeb.Home` LiveView provides an interactive form where users can preview text with different styling options
|
||||
2. **Image Generation (`/:label`)**: `LabelmakerWeb.LabelController.show/2` handles dynamic image generation
|
||||
|
||||
### Core Components
|
||||
|
||||
**`LabelmakerWeb.LabelController`** (lib/labelmaker_web/controllers/label_controller.ex)
|
||||
- Main entry point for image generation requests
|
||||
- Takes URL path (label text) and query parameters (color, font, outline, size, width, height, align)
|
||||
- Generates SHA256 hash from parameters to create unique filename for caching
|
||||
- Checks if cached image exists; if not, builds ImageMagick command and generates image
|
||||
- Stores generated images in `priv/static/labels/`
|
||||
- Returns image as PNG response
|
||||
|
||||
**`LabelmakerWeb.Tools`** (lib/labelmaker_web/tools.ex)
|
||||
- Contains parameter processing and validation logic
|
||||
- `process_parameters/1`: Validates and normalizes user input against permitted values
|
||||
- Handles two sizing modes:
|
||||
- **Font mode** (default): Uses `label:` with `-pointsize` for natural text sizing
|
||||
- **Width x Height mode**: Uses `caption:` with `-size WxH` for fixed dimensions
|
||||
- `generate_link/1`: Creates URLs based on current parameters and sizing mode
|
||||
- `process_label/1`: Handles `\n` to actual newline conversion for multi-line labels
|
||||
- Input validation: filters colors, fonts, sizes, outlines against permitted lists
|
||||
|
||||
**`LabelmakerWeb.Constants`** (lib/labelmaker_web/constants.ex)
|
||||
- Single source of truth for all permitted values and defaults
|
||||
- Defines available colors, fonts, sizes, alignments
|
||||
- Font map supports shortcuts (e.g., "h" → "Helvetica", "cs" → "Comic-Sans-MS")
|
||||
- Max dimensions: 1024x1024 pixels
|
||||
- Max label length: 1024 characters
|
||||
- Available fonts: Comic Sans, Courier, Georgia, Helvetica, Impact, Verdana
|
||||
|
||||
**`LabelmakerWeb.Home`** (lib/labelmaker_web/live/home.ex)
|
||||
- LiveView for homepage with interactive preview
|
||||
- Handles real-time updates via `handle_event/3`:
|
||||
- `update_label`: Updates label text and styling parameters
|
||||
- `update_preview`: Changes preview background (gradient/solid)
|
||||
- `update_sizing`: Toggles between font size mode and width×height mode
|
||||
- `update_alignment`: Changes text alignment (left/center/right)
|
||||
- Redirects to `/:label` route when user submits the form
|
||||
|
||||
**`LabelmakerWeb.RadioComponent`** (lib/labelmaker_web/live/components/radio_component.ex)
|
||||
- Reusable Phoenix Component for radio button groups
|
||||
- Used in the homepage form for alignment selection
|
||||
|
||||
### ImageMagick Command Construction
|
||||
|
||||
The controller builds ImageMagick commands programmatically:
|
||||
|
||||
1. **Basic settings**: background, fill color, font
|
||||
2. **Outline settings**: stroke color and width (if not "none")
|
||||
3. **Size settings**: Either pointsize + `label:` OR width×height + `caption:`
|
||||
4. **Final settings**: Adds metadata comment and output filepath
|
||||
|
||||
Example generated command:
|
||||
```sh
|
||||
magick -background none -fill black -font Helvetica -stroke white -strokewidth 1 -pointsize 72 label:Hello World output.png
|
||||
```
|
||||
|
||||
### Sizing Modes
|
||||
|
||||
The app supports two distinct sizing modes (controlled by `sizing` parameter):
|
||||
|
||||
- **Font mode** (`sizing=font`): ImageMagick calculates image size based on font size; natural text rendering
|
||||
- **Width × Height mode** (`sizing=wxh`): Fixed canvas dimensions with text wrapped/aligned within bounds
|
||||
|
||||
### Parameter Processing
|
||||
|
||||
All parameters flow through `Tools.process_parameters/1`:
|
||||
1. Merge with defaults from `Constants.defaults()`
|
||||
2. Process label (convert `\n` escapes)
|
||||
3. Validate each parameter against permitted lists
|
||||
4. Filter out invalid values
|
||||
5. Calculate derived values (preview_height, rows, link)
|
||||
6. Return merged map with all parameters
|
||||
|
||||
### Caching Strategy
|
||||
|
||||
Images are cached using SHA256 hash of the processed options map:
|
||||
- Hash includes: label, color, font, outline, size, width, height, align
|
||||
- Cached files stored in `priv/static/labels/`
|
||||
- Before generating, checks if file exists
|
||||
- No expiration mechanism (cache persists until manually cleared)
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **ImageMagick dependency**: The `magick` command must be available in PATH
|
||||
- **Alignment/Gravity mapping**: User-facing "left/center/right" maps to ImageMagick "west/center/east" gravity values (see `Tools.process_gravity/1`)
|
||||
- **URL escaping**: Special characters in labels must be URL-encoded; `\n` is processed as literal newline
|
||||
- **Main branch**: This repo uses `trunk` as the main branch (not `main` or `master`)
|
||||
Reference in New Issue
Block a user