| 1 | |
| 2 | import type { Suit as SuitType } from './PlayingCard'; |
| 3 | |
| 4 | |
| 5 | const PATHS: Record<Exclude<SuitType, 'J'>, string> = { |
| 6 | H: 'M50 90C22 68 5 51 5 31 5 16 16 6 30 6c9 0 16 5 20 13 4-8 11-13 20-13 14 0 25 10 25 25 0 20-17 37-45 59z', |
| 7 | D: 'M50 3c11 17 24 32 39 47-15 15-28 30-39 47C39 80 26 65 11 50 26 35 39 20 50 3z', |
| 8 | S: 'M50 4c13 19 43 33 43 57 0 14-10 22-22 22-8 0-14-4-17-10 1 10 5 17 13 22H33c8-5 12-12 13-22-3 6-9 10-17 10C17 83 7 75 7 61 7 37 37 23 50 4z', |
| 9 | C: 'M50 7a19 19 0 0 1 15 30.6A19 19 0 1 1 55.5 70c1.3 10 5 18.5 13.5 24h-38c8.5-5.5 12.2-14 13.5-24A19 19 0 1 1 35 37.6 19 19 0 0 1 50 7z', |
| 10 | }; |
| 11 | |
| 12 | export function SuitIcon({ |
| 13 | suit, |
| 14 | size = '1em', |
| 15 | className, |
| 16 | }: { |
| 17 | suit: SuitType; |
| 18 | size?: string | number; |
| 19 | className?: string; |
| 20 | }) { |
| 21 | if (suit === 'J') return null; |
| 22 | return ( |
| 23 | <svg viewBox="0 0 100 100" width={size} height={size} className={className} aria-hidden="true"> |
| 24 | <path d={PATHS[suit]} fill="currentColor" /> |
| 25 | </svg> |
| 26 | ); |
| 27 | } |
| 28 | |
| 29 | |
| 30 | const CUT = { fill: 'var(--card-face)' }; |
| 31 | |
| 32 | |
| 33 | export function CourtIcon({ rank, className }: { rank: number; className?: string }) { |
| 34 | return ( |
| 35 | <svg viewBox="0 0 100 100" className={className} aria-hidden="true" fill="currentColor"> |
| 36 | {rank === 13 && ( |
| 37 | <> |
| 38 | <path d="M50 2h5v7h7v5h-7v8h-5v-8h-7V9h7z" /> |
| 39 | <path d="M15 74 9 33l21 17 20-27 20 27 21-17-6 41z" /> |
| 40 | <circle cx="9" cy="29" r="5" /> |
| 41 | <circle cx="91" cy="29" r="5" /> |
| 42 | <rect x="15" y="78" width="70" height="10" rx="2.5" /> |
| 43 | <circle cx="50" cy="60" r="5.5" style={CUT} /> |
| 44 | <circle cx="31" cy="64" r="3" style={CUT} /> |
| 45 | <circle cx="69" cy="64" r="3" style={CUT} /> |
| 46 | <rect x="21" y="81.5" width="58" height="3" rx="1.5" style={CUT} /> |
| 47 | </> |
| 48 | )} |
| 49 | {rank === 12 && ( |
| 50 | <> |
| 51 | <path d="M13 74c0-13 2-26 5-36l15 17 17-21 17 21 15-17c3 10 5 23 5 36z" /> |
| 52 | <circle cx="18" cy="32" r="6" /> |
| 53 | <circle cx="50" cy="26" r="7" /> |
| 54 | <circle cx="82" cy="32" r="6" /> |
| 55 | <circle cx="33" cy="50" r="3.5" /> |
| 56 | <circle cx="67" cy="50" r="3.5" /> |
| 57 | <rect x="13" y="78" width="74" height="10" rx="5" /> |
| 58 | <path d="M50 52c5 5 8 8 8 12a8 8 0 0 1-16 0c0-4 3-7 8-12z" style={CUT} /> |
| 59 | <circle cx="27" cy="83" r="2.5" style={CUT} /> |
| 60 | <circle cx="50" cy="83" r="2.5" style={CUT} /> |
| 61 | <circle cx="73" cy="83" r="2.5" style={CUT} /> |
| 62 | </> |
| 63 | )} |
| 64 | {rank === 11 && ( |
| 65 | <> |
| 66 | <path d="M64 46C70 27 82 14 98 7c-3 15-11 28-24 41z" /> |
| 67 | <path |
| 68 | d="M66 45C74 31 84 20 95 11" |
| 69 | fill="none" |
| 70 | strokeWidth="2.2" |
| 71 | style={{ stroke: 'var(--card-face)' }} |
| 72 | /> |
| 73 | <path d="M27 67c0-19 10-30 24-30s24 11 24 30z" /> |
| 74 | <path d="M5 73c0-8 20-12 45-12s45 4 45 12-20 11-45 11S5 81 5 73z" /> |
| 75 | <rect x="27" y="59" width="48" height="5" style={CUT} /> |
| 76 | <circle cx="50" cy="73" r="3" style={CUT} /> |
| 77 | </> |
| 78 | )} |
| 79 | </svg> |
| 80 | ); |
| 81 | } |
| 82 | |
| 83 | |
| 84 | export function JesterIcon({ className }: { className?: string }) { |
| 85 | return ( |
| 86 | <svg viewBox="0 0 100 100" className={className} aria-hidden="true" fill="currentColor"> |
| 87 | <path d="M46 14c4 29 8 35 38 42-30 7-34 13-38 42-4-29-8-35-38-42 30-7 34-13 38-42z" /> |
| 88 | <path d="M84 6c1.6 9.5 3 11 12 13-9 2-10.4 3.5-12 13-1.6-9.5-3-11-12-13 9-2 10.4-3.5 12-13z" /> |
| 89 | <circle cx="46" cy="56" r="6" style={CUT} /> |
| 90 | </svg> |
| 91 | ); |
| 92 | } |