CoolFace
Apppublic

AjDRoger/tile-shuffle-master

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
difficulty-selector.js221 linesDownload Raw Back to components
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