Skip to content

Commit 88d0aa8

Browse files
author
Top-5
committed
Update README.md and package.json to reflect spritesheet implementation and custom drag-and-drop system
1 parent 0dc7938 commit 88d0aa8

File tree

4 files changed

+78
-43
lines changed

4 files changed

+78
-43
lines changed

.github/PAGES_FIX.md

Lines changed: 0 additions & 32 deletions
This file was deleted.

README.md

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
[![Deploy to GitHub Pages](https://github.com/top-5/klondike/actions/workflows/deploy.yml/badge.svg)](https://github.com/top-5/klondike/actions/workflows/deploy.yml)
55
[![License](https://img.shields.io/badge/license-Custom%20Non--Commercial-blue.svg)](LICENSE)
66

7-
A modern, type-safe implementation of Classic Klondike Solitaire, built with React, TypeScript, and Vite, featuring beautiful spritesheet cards, intuitive drag & drop, auto-move functionality, and full move validation logic.
7+
A modern, type-safe implementation of Classic Klondike Solitaire, built with React, TypeScript, and Vite, featuring beautiful spritesheet-based card graphics, custom mouse-driven drag & drop, auto-move functionality, and full move validation logic.
88

99
🎮 **[Play Now on GitHub Pages](https://top-5.github.io/klondike/)**
1010

11+
![Klondike Solitaire Screenshot](public/screenshot.png)
12+
1113
## ✨ Features
1214

1315
- ♠️ **Classic Klondike Rules** – Traditional solitaire gameplay
1416
- 🎨 **Beautiful Card Graphics** – High-quality spritesheet rendering with subtle animations
15-
- 🎮 **Drag & Drop Interface** – Intuitive card movement with smooth animations
17+
- 🖱️ **Custom Drag & Drop** – Precise mouse-driven card movement with real-time visual feedback
18+
- 🎯 **Multi-Card Stack Dragging** – Drag entire card sequences smoothly with proper offset
1619
- 🚀 **Auto-Move to Foundation** – Double-click cards to automatically send them to foundations
1720
-**Flying Animation** – Cards fly to their destination with beautiful arc motion
1821
-**Move Validation** – Only valid moves allowed
@@ -44,7 +47,7 @@ npm run preview
4447
npm test
4548
```
4649

47-
Open http://localhost:5173/ to play.
50+
Open http://localhost:10010/ to play.
4851

4952
## 🛠️ Development
5053

@@ -74,6 +77,8 @@ npm run test:coverage
7477
| Layer | Technology | Purpose |
7578
|-------|-----------|---------|
7679
| UI | React 18 | Game interface |
80+
| Graphics | Spritesheet | Card rendering via canvas extraction |
81+
| Drag System | Custom Mouse Events | Precise positioning & multi-card stacks |
7782
| Build | Vite 5 | Lightning-fast dev + build |
7883
| Language | TypeScript 5.7 | Type-safe logic |
7984
| Tests | Vitest 2.1 | Unit testing |
@@ -92,8 +97,13 @@ cardserver/
9297
│ ├── main.tsx # React entry point
9398
│ ├── App.tsx # Main game component
9499
│ ├── App.css # Styling
95-
│ ├── types.ts # Type definitions & glyphs
100+
│ ├── types.ts # Type definitions
101+
│ ├── cardSprites.ts # Spritesheet loader
96102
│ └── gameLogic.ts # Klondike rules engine
103+
├── public/
104+
│ ├── deck.png # Card spritesheet (4x13 grid)
105+
│ ├── back.jpg # Card back image
106+
│ └── screenshot.png # Game screenshot
97107
├── test/
98108
│ └── *.test.ts # Unit tests
99109
└── .github/
@@ -187,14 +197,70 @@ interface GameState {
187197
}
188198
```
189199

190-
## 🎨 Card Colors (CSS Technique)
200+
## 🎨 Card Graphics Implementation
201+
202+
The game uses a **spritesheet-based card rendering system** for optimal performance and visual quality:
203+
204+
### Spritesheet Layout
205+
- **File**: `public/deck.png` (4 rows × 13 columns)
206+
- **Row mapping**: 0=Clubs, 1=Hearts, 2=Spades, 3=Diamonds
207+
- **Column mapping**: 0=A, 1=2, ..., 9=10, 10=J, 11=Q, 12=K
208+
- **Card back**: `public/back.jpg`
209+
210+
### Loading Process (`cardSprites.ts`)
211+
1. Load `deck.png` spritesheet into memory
212+
2. Calculate frame dimensions (width/13, height/4)
213+
3. Extract each card using canvas `drawImage()` with precise coordinates
214+
4. Convert to data URLs for React img elements
215+
5. Cache all 52 cards for instant rendering
216+
217+
This approach provides:
218+
- ✅ High-quality card graphics with smooth edges
219+
- ✅ Fast rendering (pre-extracted, cached data URLs)
220+
- ✅ Single spritesheet download (better than 52 separate images)
221+
- ✅ Subtle animations via CSS transforms
222+
223+
## 🖱️ Custom Drag & Drop System
224+
225+
The game implements a **custom mouse-driven drag system** (not HTML5 drag API) for precise control:
226+
227+
### Why Custom Implementation?
228+
- HTML5 drag API forces semi-transparency on drag images (browser limitation)
229+
- Needed pixel-perfect positioning without "jump" on drag start
230+
- Required multi-card stack dragging with proper visual offset
231+
- Wanted full control over cursor states and visual feedback
232+
233+
### How It Works
234+
1. **Mouse Down**: Calculate offset from card's top-left to click position
235+
2. **Mouse Move**: Track global mouse position, update drag overlay position
236+
3. **Drag Overlay**: Fixed-position div at `mouseX - offsetX`, `mouseY - offsetY`
237+
4. **Original Cards**: Set to `opacity: 0` during drag (fully invisible, no ghosting)
238+
5. **Drop Detection**: Use `elementFromPoint()` to find drop zone under cursor
239+
6. **Mouse Up**: Validate move, update game state, reset cursor
240+
241+
### Features
242+
- 🎯 **Precise positioning** – Card stays under cursor at click point
243+
- 📚 **Multi-card stacks** – Drag sequences with 25px offset per card
244+
- 👁️ **Clean visuals** – No ghostly images or transparency issues
245+
- 🖱️ **Cursor feedback** – grab → grabbing → normal states
246+
-**High performance** – No unnecessary re-renders
247+
248+
## 🎨 CSS Animations
191249

192250
```css
193-
.red { color: #dc143c; text-shadow: 0 0 1px #dc143c; }
194-
.black { color: #000; text-shadow: 0 0 1px #000; }
195-
```
251+
/* Shimmer effect on cards */
252+
@keyframes cardShimmer {
253+
0%, 100% { box-shadow: 0 2px 8px rgba(0,0,0,0.15); }
254+
50% { box-shadow: 0 4px 16px rgba(0,0,0,0.25); }
255+
}
196256

197-
Applies transparent glyphs with shadow tint for vibrant Unicode cards.
257+
/* Flying animation for auto-move */
258+
@keyframes flyToFoundation {
259+
0% { transform: scale(1) translateY(0); }
260+
50% { transform: scale(0.9) translateY(-30px); }
261+
100% { transform: scale(1) translateY(0); opacity: 0; }
262+
}
263+
```
198264

199265
## 🚀 Deployment
200266

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "klondike-solitaire",
33
"version": "2.0.0",
4-
"description": "Klondike Solitaire game built with React, TypeScript, and Vite using Unicode colored card glyphs",
4+
"description": "Klondike Solitaire game built with React, TypeScript, and Vite using spritesheet-based card graphics and custom drag-and-drop",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
@@ -26,7 +26,8 @@
2626
"react",
2727
"typescript",
2828
"vite",
29-
"unicode-cards"
29+
"spritesheet",
30+
"custom-drag-drop"
3031
],
3132
"author": "Top-5",
3233
"license": "SEE LICENSE IN LICENSE",

public/screenshot.png

511 KB
Loading

0 commit comments

Comments
 (0)