Clavier Jolie avec HTML et JS
<!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>