You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

234 lines
8.7 KiB

class VirtualKeyboard {
static show(inputElement) {
// Create the virtual keyboard container
const keyboardContainer = document.createElement('div');
keyboardContainer.classList.add('virtual-keyboard');
document.body.appendChild(keyboardContainer);
// Create the display container for input characters
const displayContainer = document.createElement('div');
displayContainer.classList.add('virtual-keyboard-display');
document.body.appendChild(displayContainer);
// Create the text display box above the number keys
const textDisplayBox = document.createElement('div');
textDisplayBox.classList.add('virtual-keyboard-text-display');
textDisplayBox.style.height = '40px'; // Initialize height
textDisplayBox.textContent = inputElement.value; // Initialize content
keyboardContainer.appendChild(textDisplayBox);
// Define the keys for the virtual keyboard
const keyLayout = [
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'Backspace'],
['Tab', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'Del'],
['CapsLock', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'Enter'],
['Shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'Shift'],
['Space']
];
let isShift = false;
let isCapsLock = false;
// Create buttons for each key
keyLayout.forEach(row => {
const rowContainer = document.createElement('div');
rowContainer.classList.add('virtual-keyboard-row');
row.forEach(key => {
const keyButton = document.createElement('button');
keyButton.textContent = key;
keyButton.classList.add(`key-${key.toLowerCase()}`);
keyButton.addEventListener('mousedown', (event) => {
event.preventDefault(); // Prevent losing focus from the input element
keyButton.classList.add('active'); // Add active class on mousedown
if (key === 'Backspace') {
inputElement.value = inputElement.value.slice(0, -1);
} else if (key === 'Del') {
inputElement.value = '';
} else if (key === 'Tab') {
inputElement.value += '\t';
} else if (key === 'Space') {
inputElement.value += ' ';
} else if (key === 'Enter') {
document.body.removeChild(keyboardContainer);
document.body.removeChild(displayContainer);
} else if (key === 'Shift') {
// isShift = !isShift;
// this.toggleShift(keyButton, isShift);
} else if (key === 'CapsLock') {
isCapsLock = !isCapsLock;
this.toggleCapsLock(keyButton, isCapsLock);
} else {
inputElement.value += isCapsLock ? key.toUpperCase() : key.toLowerCase();
}
inputElement.dispatchEvent(new Event('input')); // Trigger input event to update Vue binding
displayContainer.textContent = inputElement.value; // Update display container with input value
textDisplayBox.textContent = inputElement.value; // Update text display box with input value
});
keyButton.addEventListener('mouseup', () => {
keyButton.classList.remove('active'); // Remove active class on mouseup
keyButton.style.background = '#fff'; // Reset background immediately
});
keyButton.addEventListener('mouseleave', () => {
keyButton.classList.remove('active'); // Remove active class if mouse leaves the button
keyButton.style.background = '#fff'; // Reset background immediately
});
rowContainer.appendChild(keyButton);
});
keyboardContainer.appendChild(rowContainer);
});
// Position the keyboard at the bottom of the screen
keyboardContainer.style.position = 'fixed';
keyboardContainer.style.bottom = '0';
keyboardContainer.style.left = '50%';
keyboardContainer.style.transform = 'translateX(-50%)';
keyboardContainer.style.width = '100%';
keyboardContainer.style.maxWidth = '800px';
keyboardContainer.style.margin = '0 auto';
keyboardContainer.style.border = '1px solid #999';
// Position the display container above the keyboard
displayContainer.style.position = 'fixed';
displayContainer.style.bottom = 'calc(100% + 10px)';
displayContainer.style.left = '50%';
displayContainer.style.transform = 'translateX(-50%)';
displayContainer.style.width = '100%';
displayContainer.style.maxWidth = '800px';
displayContainer.style.textAlign = 'center';
displayContainer.style.padding = '10px';
displayContainer.style.background = '#f0f0f0';
displayContainer.style.borderTop = '1px solid #999';
displayContainer.style.boxShadow = '0 -2px 10px rgba(0, 0, 0, 0.1)';
displayContainer.style.zIndex = '1000';
// Style the text display box
textDisplayBox.style.width = '100%';
textDisplayBox.style.padding = '10px';
textDisplayBox.style.background = '#e0e0e0';
textDisplayBox.style.textAlign = 'center';
textDisplayBox.style.fontSize = '18px';
textDisplayBox.style.marginBottom = '10px';
// Hide the keyboard and display container when the input loses focus
inputElement.addEventListener('blur', () => {
setTimeout(() => {
if (document.activeElement !== inputElement) {
document.body.removeChild(keyboardContainer);
document.body.removeChild(displayContainer);
}
}, 30);
});
}
static toggleShift(button, isShift) {
button.classList.toggle('active', isShift);
}
static toggleCapsLock(button, isCapsLock) {
const keys = document.querySelectorAll('.virtual-keyboard button');
keys.forEach(key => {
if (key.textContent.length === 1 && key.textContent.match(/[a-z]/i)) {
key.textContent = isCapsLock ? key.textContent.toUpperCase() : key.textContent.toLowerCase();
}
});
}
}
// Add some basic styles for the virtual keyboard
const style = document.createElement('style');
style.textContent = `
.virtual-keyboard {
display: flex;
flex-direction: column;
background: #f0f0f0;
padding: 10px;
border-top: 1px solid #999;
border: 1px solid #999;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
max-width: 800px;
margin: 0 auto;
}
.virtual-keyboard-row {
display: flex;
justify-content: center;
margin-bottom: 5px;
}
.virtual-keyboard button {
margin: 5px;
padding: 15px;
font-size: 18px;
cursor: pointer;
border: none;
border-radius: 5px;
background: #fff;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: background 0.3s, box-shadow 0.3s;
flex: 1 1 8%;
max-width: 60px;
}
.virtual-keyboard button:hover {
background: #e0e0e0;
}
.virtual-keyboard button:active {
background: #d0d0d0;
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2);
}
.virtual-keyboard button.active {
background: #d0d0d0;
}
.virtual-keyboard .key-backspace {
flex: 1 1 10%;
max-width: 100px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.virtual-keyboard .key-enter {
flex: 1 1 10%;
max-width: 100px;
}
.virtual-keyboard .key-shift {
flex: 1 1 15%;
max-width: 150px;
}
.virtual-keyboard .key-capslock,
.virtual-keyboard .key-tab,
.virtual-keyboard .key-del {
flex: 1 1 10%;
max-width: 100px;
}
.virtual-keyboard .key-space {
flex: 1 1 60%;
max-width: 400px;
}
.virtual-keyboard-display {
font-size: 24px;
color: #333;
}
.virtual-keyboard-text-display {
width: 100%;
padding: 10px;
background: #e0e0e0;
text-align: center;
font-size: 18px;
margin-bottom: 10px;
}
.virtual-keyboard-row:first-child {
justify-content: space-between;
}
.virtual-keyboard-row:nth-child(2) {
justify-content: space-between;
}
.virtual-keyboard-row:nth-child(3) {
justify-content: space-between;
}
.virtual-keyboard-row:nth-child(4) {
justify-content: space-between;
}
.virtual-keyboard-row:nth-child(5) {
justify-content: center;
}
`;
document.head.appendChild(style);