OneCompiler

Clavier Jolie avec HTML et JS

125


<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Clavier Virtuel Premium</title> <style> :root { --primary-color: #4a90e2; --secondary-color: #f39c12; --dark-color: #2c3e50; --light-color: #ecf0f1; }
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    body {
        min-height: 100vh;
        background: linear-gradient(135deg, #6c5ce7, #a363d8);
        font-family: 'Segoe UI', sans-serif;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px;
    }

    .container {
        width: 100%;
        max-width: 1200px;
    }

    .theme-selector {
        position: fixed;
        top: 20px;
        right: 20px;
        z-index: 1000;
    }

    .theme-btn {
        padding: 8px 15px;
        border: none;
        border-radius: 20px;
        background: var(--light-color);
        cursor: pointer;
        transition: 0.3s;
    }

    #display-container {
        width: 100%;
        margin-bottom: 20px;
        position: relative;
    }

    #display {
        width: 100%;
        height: 150px;
        background: rgba(255, 255, 255, 0.95);
        border-radius: 15px;
        padding: 15px;
        font-size: 18px;
        resize: vertical;
        border: none;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #word-count {
        position: absolute;
        bottom: 10px;
        right: 10px;
        background: rgba(0, 0, 0, 0.7);
        color: white;
        padding: 5px 10px;
        border-radius: 10px;
        font-size: 12px;
    }

    #keyboard {
        width: 100%;
        background: rgba(0, 0, 0, 0.85);
        padding: 20px;
        border-radius: 20px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
    }

    .row {
        display: flex;
        justify-content: center;
        margin: 5px 0;
        gap: 5px;
    }

    .key {
        flex-grow: 1;
        min-width: 40px;
        height: 60px;
        border-radius: 10px;
        border: none;
        background: linear-gradient(145deg, #ffffff, #e6e6e6);
        cursor: pointer;
        font-size: 18px;
        transition: all 0.2s;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        position: relative;
        overflow: hidden;
    }

    .key:active, .key.active {
        transform: translateY(2px);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    }

    .key::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        background: rgba(255, 255, 255, 0.3);
        border-radius: 50%;
        transform: translate(-50%, -50%);
        transition: width 0.3s, height 0.3s;
    }

    .key:active::after {
        width: 100px;
        height: 100px;
    }

    .special {
        background: linear-gradient(145deg, var(--secondary-color), #e67e22);
        color: white;
    }

    .function {
        background: linear-gradient(145deg, var(--primary-color), #357abd);
        color: white;
    }

    .space {
        flex-grow: 3;
        max-width: 400px;
    }

    .backspace {
        flex-grow: 2;
    }

    #controls {
        margin-top: 20px;
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
        justify-content: center;
    }

    .control-btn {
        padding: 10px 20px;
        border-radius: 25px;
        border: none;
        background: var(--primary-color);
        color: white;
        cursor: pointer;
        transition: 0.3s;
        font-size: 16px;
    }

    .control-btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    .emoji-panel {
        display: none;
        position: absolute;
        bottom: 100%;
        left: 0;
        background: white;
        padding: 10px;
        border-radius: 10px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        grid-template-columns: repeat(8, 1fr);
        gap: 5px;
    }

    .emoji-btn {
        padding: 5px;
        border: none;
        background: none;
        cursor: pointer;
        font-size: 20px;
    }

    @media (max-width: 768px) {
        .key {
            height: 50px;
            font-size: 16px;
            min-width: 30px;
        }

        .emoji-panel {
            grid-template-columns: repeat(6, 1fr);
        }
    }

    @media (max-width: 480px) {
        .key {
            height: 40px;
            font-size: 14px;
            min-width: 25px;
        }

        .control-btn {
            padding: 8px 15px;
            font-size: 14px;
        }

        .emoji-panel {
            grid-template-columns: repeat(4, 1fr);
        }
    }

    .suggestions {
        display: flex;
        gap: 10px;
        margin-bottom: 10px;
        flex-wrap: wrap;
    }

    .suggestion {
        background: rgba(255, 255, 255, 0.9);
        padding: 5px 10px;
        border-radius: 15px;
        cursor: pointer;
        font-size: 14px;
        transition: 0.3s;
    }

    .suggestion:hover {
        background: var(--primary-color);
        color: white;
    }
</style>
</head> <body> <div class="container"> <button class="theme-btn" id="theme-toggle">🌙</button> <div id="display-container"> <textarea id="display" readonly placeholder="Commencez à taper..."></textarea> <div id="word-count">Mots: 0 | Caractères: 0</div> </div> <div class="suggestions" id="suggestions"></div> <div id="keyboard"> <div class="row"> <button class="key special">é</button> <button class="key">1</button> <button class="key">2</button> <button class="key">3</button> <button class="key">4</button> <button class="key">5</button> <button class="key">6</button> <button class="key">7</button> <button class="key">8</button> <button class="key">9</button> <button class="key">0</button> <button class="key special">'</button> </div> <div class="row"> <button class="key">a</button> <button class="key">z</button> <button class="key">e</button> <button class="key">r</button> <button class="key">t</button> <button class="key">y</button> <button class="key">u</button> <button class="key">i</button> <button class="key">o</button> <button class="key">p</button> <button class="key special">è</button> </div> <div class="row"> <button class="key">q</button> <button class="key">s</button> <button class="key">d</button> <button class="key">f</button> <button class="key">g</button> <button class="key">h</button> <button class="key">j</button> <button class="key">k</button> <button class="key">l</button> <button class="key">m</button> <button class="key special">ù</button> </div> <div class="row"> <button class="key function">⇧</button> <button class="key">w</button> <button class="key">x</button> <button class="key">c</button> <button class="key">v</button> <button class="key">b</button> <button class="key">n</button> <button class="key backspace function">⌫</button> </div> <div class="row"> <button class="key special">?123</button> <button class="key">😀</button> <button class="key">.</button> <button class="key space"> </button> <button class="key">,</button> <button class="key special">Enter</button> </div> </div> <div id="controls"> <button class="control-btn" id="clear">Effacer</button> <button class="control-btn" id="sound">Son: On</button> <button class="control-btn" id="copy">Copier</button> <button class="control-btn" id="save">Sauvegarder</button> <button class="control-btn" id="load">Charger</button> </div> <div class="emoji-panel" id="emoji-panel"> <!-- Les emojis seront ajoutés dynamiquement --> </div> </div>
<script>
    const display = document.getElementById('display');
    const keyboard = document.getElementById('keyboard');
    const clearBtn = document.getElementById('clear');
    const soundBtn = document.getElementById('sound');
    const copyBtn = document.getElementById('copy');
    const saveBtn = document.getElementById('save');
    const loadBtn = document.getElementById('load');
    const wordCount = document.getElementById('word-count');
    const themeToggle = document.getElementById('theme-toggle');
    const emojiPanel = document.getElementById('emoji-panel');
    const suggestionsDiv = document.getElementById('suggestions');

    let isCaps = false;
    let soundEnabled = true;
    let isDarkMode = false;

    // Dictionnaire pour les suggestions
    const dictionary = {
        'bon': ['bonjour', 'bonne', 'bonsoir'],
        'mer': ['merci', 'mercure', 'merveilleux'],
        // Ajoutez plus de mots...
    };

    // Emojis communs
    const commonEmojis = ['😀', '😂', '❤️', '👍', '🎉', '🌟', '🔥', '💪', '😊', '🤔', '👋', '✨', '💯', '🙌', '👏', '💖'];

    function updateWordCount() {
        const text = display.value;
        const words = text.trim().split(/\s+/).filter(word => word.length > 0).length;
        const chars = text.length;
        wordCount.textContent = `Mots: ${words} | Caractères: ${chars}`;
    }

    function playKeySound() {
        if (soundEnabled) {
            const audio = new Audio('data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1fdJivrJBhNjVgodDbq2EcBj+a2/LDciUFLXrF7s+EQwUfW6vi0pVdBhNKk9DRpHMHDz2DvM+ygwgLMmyyzLyRCQkoXqfKxqAKCCFQmcnPrwsHGkSNxdS9DQcUPIG/18oQBxA3ernZ1hIHDTNy');
            audio.play();
        }
    }

    function showSuggestions(word) {
        suggestionsDiv.innerHTML = '';
        if (word && dictionary[word.toLowerCase()]) {
            dictionary[word.toLowerCase()].forEach(suggestion => {
                const suggestionEl = document.createElement('span');
                suggestionEl.className = 'suggestion';
                suggestionEl.textContent = suggestion;
                suggestionEl.onclick = () => {
                    const words = display.value.split(' ');
                    words[words.length - 1] = suggestion;
                    display.value = words.join(' ') + ' ';
                    updateWordCount();
                };
                suggestionsDiv.appendChild(suggestionEl);
            });
        }
    }

    keyboard.addEventListener('click', (e) => {
        if (e.target.classList.contains('key')) {
            playKeySound();
            const key = e.target.textContent;

            if (key === '⇧') {
                isCaps = !isCaps;
                document.querySelectorAll('.key').forEach(k => {
                    if (k.textContent.length === 1 && k.textContent.match(/[a-zA-Z]/)) {
                        k.textContent = isCaps ? k.textContent.toUpperCase() : k.textContent.toLowerCase();
                    }
                });
            } else if (key === '⌫') {
                display.value = display.value.slice(0, -1);
            } else if (key === 'Enter') {
                display.value += '\n';
            } else if (key === '😀') {
                emojiPanel.style.display = emojiPanel.style.display === 'grid' ? 'none' : 'grid';
            } else if (key !== 'Space') {
                display.value += key;
            } else {
                display.value += ' ';
            }

            const lastWord = display.value.split(' ').pop();
            showSuggestions(lastWord);
            updateWordCount();
            display.scrollTop = display.scrollHeight;
        }
    });

    // Initialiser le panel d'emojis
    commonEmojis.forEach(emoji => {
        const button = document.createElement('button');
        button.className = 'emoji-btn';
        button.textContent = emoji;
        button.onclick = () => {
            display.value += emoji;
            emojiPanel.style.display = 'none';
            updateWordCount();
        };
        emojiPanel.appendChild(button);
    });

    clearBtn.onclick = () => {
        display.value = '';
        updateWordCount();
    };

    soundBtn.onclick = () => {
        soundEnabled = !soundEnabled;
        soundBtn.textContent = `Son: ${soundEnabled ? 'On' : 'Off'}`;
    };

    copyBtn.onclick = () => {
        display.select();
        document.execCommand('copy');
    };

    saveBtn.onclick = () => {
        localStorage.setItem('savedText', display.value);
        alert('Texte sauvegardé!');
    };

    loadBtn.onclick = () => {
        const savedText = localStorage.getItem('savedText');
        if (savedText) {
            display.value = savedText;
            updateWordCount();
        }
    };

    themeToggle.onclick = () => {
        isDarkMode = !isDarkMode;
        document.body.style.background = isDarkMode ? 
            'linear-gradient(135deg, #2c3e50, #34495e)' : 
            'linear-gradient(135deg, #6c5ce7, #a363d8)';
        themeToggle.textContent = isDarkMode ? '☀️' : '🌙';
    };

    // Support clavier physique
    document.addEventListener('keydown', (e) => {
        const key = document.querySelector(`.key[data-key="${e.key}"]`);
        if (key) {
            key.classList.add('active');
            key.click();
        }
        playKeySound();
    });

    document.addEventListener('keyup', (e) => {
        const key = document.querySelector(`.key[data-key="${e.key}"]`);
        if (key) {
            key.classList.remove('active');
        }
    });

    // Initialisation
    updateWordCount();
</script>
</body> </html>