AjDRoger/tile-shuffle-master
0
1 2// Difficulty Selector Web Component3class DifficultySelector extends HTMLElement {4 constructor() {5 super();6 this.selectedDifficulty = 'medium';7 }8 9 connectedCallback() {10 this.attachShadow({ mode: 'open' });11 this.render();12 this.setupEventListeners();13 }14 15 setupEventListeners() {16 const buttons = this.shadowRoot.querySelectorAll('.difficulty-btn');17 buttons.forEach(btn => {18 btn.addEventListener('click', (e) => {19 const difficulty = e.currentTarget.dataset.difficulty;20 this.selectDifficulty(difficulty);21 });22 });23 }24 25 selectDifficulty(difficulty) {26 this.selectedDifficulty = difficulty;27 28 // Update UI29 const buttons = this.shadowRoot.querySelectorAll('.difficulty-btn');30 buttons.forEach(btn => {31 btn.classList.remove('active');32 if (btn.dataset.difficulty === difficulty) {33 btn.classList.add('active');34 }35 });36 37 // Dispatch custom event38 this.dispatchEvent(new CustomEvent('difficulty-changed', {39 detail: { difficulty: difficulty },40 bubbles: true41 }));42 43 // Show difficulty info44 this.updateDifficultyInfo(difficulty);45 46 // Save preference47 localStorage.setItem('tile-shuffle-difficulty', difficulty);48 }49 50 updateDifficultyInfo(difficulty) {51 const info = {52 easy: { moves: '30 moves', time: '5:00', desc: 'Perfect for beginners' },53 medium: { moves: '50 moves', time: '3:00', desc: 'Balanced challenge' },54 hard: { moves: '70 moves', time: '2:00', desc: 'For experienced players' },55 expert: { moves: '100 moves', time: '1:00', desc: 'Extreme challenge!' }56 };57 58 const infoEl = this.shadowRoot.querySelector('#difficulty-info');59 const selected = info[difficulty];60 61 infoEl.innerHTML = `62 <div class="text-sm text-slate-400 mb-2">${selected.desc}</div>63 <div class="flex justify-center gap-4 text-xs">64 <div class="flex items-center gap-1 bg-slate-800/50 px-2 py-1 rounded">65 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">66 <path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>67 </svg>68 ${info[difficulty].moves}69 </div>70 <div class="flex items-center gap-1 bg-slate-800/50 px-2 py-1 rounded">71 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">72 <circle cx="12" cy="12" r="10"></circle>73 <polyline points="12 6 12 12 16 14"></polyline>74 </svg>75 ${info[difficulty].time}76 </div>77 </div>78 `;79 }80 81 render() {82 this.shadowRoot.innerHTML = `83 <style>84 :host {85 display: block;86 }87 88 .difficulty-container {89 display: flex;90 flex-direction: column;91 align-items: center;92 gap: 1rem;93 }94 95 .difficulty-buttons {96 display: grid;97 grid-template-columns: repeat(4, 1fr);98 gap: 0.5rem;99 max-width: 400px;100 }101 102 .difficulty-btn {103 padding: 0.75rem 1rem;104 border-radius: 0.75rem;105 font-weight: 600;106 cursor: pointer;107 transition: all 0.3s ease;108 border: 1px solid rgba(148, 163, 184, 0.2);109 background: rgba(30, 41, 59, 0.5);110 color: #cbd5e1;111 text-align: center;112 position: relative;113 overflow: hidden;114 }115 116 .difficulty-btn::before {117 content: '';118 position: absolute;119 top: 0;120 left: -100%;121 width: 100%;122 height: 100%;123 background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);124 transition: left 0.5s;125 }126 127 .difficulty-btn:hover::before {128 left: 100%;129 }130 131 .difficulty-btn:hover {132 transform: translateY(-2px);133 border-color: rgba(20, 184, 166, 0.5);134 background: rgba(30, 41, 59, 0.8);135 }136 137 .difficulty-btn.active {138 background: linear-gradient(135deg, #14b8a6, #a855f7);139 color: white;140 border-color: transparent;141 box-shadow: 0 4px 12px rgba(20, 184, 166, 0.3);142 }143 144 .difficulty-label {145 font-size: 0.875rem;146 text-transform: capitalize;147 font-weight: 600;148 }149 150 .difficulty-desc {151 font-size: 0.75rem;152 opacity: 0.7;153 }154 155 #difficulty-info {156 min-height: 60px;157 transition: all 0.3s ease;158 }159 160 @media (max-width: 640px) {161 .difficulty-buttons {162 grid-template-columns: repeat(2, 1fr);163 max-width: 280px;164 }165 }166 </style>167 168 <div class="difficulty-container">169 <div class="difficulty-buttons">170 <button class="difficulty-btn" data-difficulty="easy">171 <div class="difficulty-label">Easy</div>172 <div class="difficulty-desc">Beginner</div>173 </button>174 <button class="difficulty-btn active" data-difficulty="medium">175 <div class="difficulty-label">Medium</div>176 <div class="difficulty-desc">Normal</div>177 </button>178 <button class="difficulty-btn" data-difficulty="hard">179 <div class="difficulty-label">Hard</div>180 <div class="difficulty-desc">Advanced</div>181 </button>182 <button class="difficulty-btn" data-difficulty="expert">183 <div class="difficulty-label">Expert</div>184 <div class="difficulty-desc">Extreme</div>185 </button>186 </div>187 188 <div id="difficulty-info" class="text-center">189 <div class="text-sm text-slate-400 mb-2">Balanced challenge</div>190 <div class="flex justify-center gap-4 text-xs">191 <div class="flex items-center gap-1 bg-slate-800/50 px-2 py-1 rounded">192 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">193 <path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>194 </svg>195 50 moves196 </div>197 <div class="flex items-center gap-1 bg-slate-800/50 px-2 py-1 rounded">198 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">199 <circle cx="12" cy="12" r="10"></circle>200 <polyline points="12 6 12 12 16 14"></polyline>201 </svg>202 3:00203 </div>204 </div>205 </div>206 </div>207 `;208 209 // Load saved difficulty preference210 const savedDifficulty = localStorage.getItem('tile-shuffle-difficulty');211 if (savedDifficulty) {212 this.selectDifficulty(savedDifficulty);213 } else {214 // Initialize with medium difficulty215 this.updateDifficultyInfo('medium');216 }217 }218}219 220customElements.define('difficulty-selector', DifficultySelector);221 