<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Global Translator | Fixed Version</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
width: 100%;
max-width: 1000px;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
header {
background: linear-gradient(to right, #0f4c75, #1b262c);
color: white;
padding: 25px 40px;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 15px;
}
.logo {
display: flex;
align-items: center;
gap: 15px;
}
.logo i {
font-size: 2.5rem;
color: #bbe1fa;
}
.logo-text {
line-height: 1.2;
}
.logo h1 {
font-size: 1.8rem;
font-weight: 700;
}
.logo p {
font-size: 0.9rem;
opacity: 0.8;
}
.api-status {
display: flex;
align-items: center;
gap: 8px;
background: rgba(255, 255, 255, 0.15);
padding: 10px 20px;
border-radius: 30px;
font-size: 1rem;
font-weight: 500;
}
.status-dot {
width: 12px;
height: 12px;
background: #4caf50;
border-radius: 50%;
box-shadow: 0 0 8px #4caf50;
}
.main-content {
padding: 30px;
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 25px;
}
.language-box {
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
height: 100%;
display: flex;
flex-direction: column;
}
.language-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid #eaeaea;
}
.language-header h2 {
color: #0f4c75;
font-size: 1.3rem;
display: flex;
align-items: center;
gap: 10px;
}
.language-header h2 i {
color: #3282b8;
}
select {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 10px;
background: white;
font-size: 1rem;
color: #333;
outline: none;
transition: all 0.3s;
width: 100%;
margin-bottom: 20px;
}
select:focus {
border-color: #3282b8;
box-shadow: 0 0 0 3px rgba(50, 130, 184, 0.2);
}
textarea {
width: 100%;
height: 200px;
padding: 15px;
border: 2px solid #e0e0e0;
border-radius: 10px;
resize: none;
font-size: 1.1rem;
color: #333;
background: white;
outline: none;
transition: all 0.3s;
flex-grow: 1;
}
textarea:focus {
border-color: #3282b8;
box-shadow: 0 0 0 3px rgba(50, 130, 184, 0.2);
}
.char-count {
text-align: right;
font-size: 0.85rem;
color: #777;
margin-top: 8px;
font-style: italic;
}
.swap-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 15px;
}
.swap-btn {
background: #0f4c75;
color: white;
border: none;
width: 55px;
height: 55px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s;
font-size: 1.3rem;
box-shadow: 0 5px 15px rgba(15, 76, 117, 0.3);
}
.swap-btn:hover {
background: #3282b8;
transform: scale(1.05);
}
.translate-btn {
background: linear-gradient(to right, #0f4c75, #3282b8);
color: white;
border: none;
padding: 15px 0;
font-size: 1.1rem;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s;
width: 100%;
font-weight: 600;
letter-spacing: 0.5px;
box-shadow: 0 5px 15px rgba(15, 76, 117, 0.3);
}
.translate-btn:hover {
background: linear-gradient(to right, #3282b8, #0f4c75);
transform: translateY(-3px);
}
.translate-btn:active {
transform: translateY(0);
}
.loading {
display: none;
text-align: center;
padding: 20px 0;
}
.loading i {
font-size: 2.5rem;
color: #0f4c75;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.result-box {
background: white;
border-radius: 10px;
border: 2px solid #e0e0e0;
padding: 15px;
min-height: 200px;
font-size: 1.1rem;
color: #333;
margin-top: 5px;
flex-grow: 1;
}
.footer {
text-align: center;
padding: 20px;
color: #555;
font-size: 0.9rem;
background: #f8f9fa;
border-top: 1px solid #eaeaea;
}
.api-key {
font-family: monospace;
background: #e9ecef;
padding: 3px 8px;
border-radius: 4px;
word-break: break-all;
}
.language-options {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-top: 20px;
}
.lang-option {
background: #e9ecef;
padding: 8px 12px;
border-radius: 8px;
text-align: center;
cursor: pointer;
transition: all 0.2s;
font-size: 0.9rem;
}
.lang-option:hover {
background: #d1d7dc;
}
.lang-option.active {
background: #0f4c75;
color: white;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
background: #4CAF50;
color: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
transform: translateX(200%);
transition: transform 0.3s ease;
z-index: 1000;
}
.notification.show {
transform: translateX(0);
}
@media (max-width: 768px) {
.main-content {
grid-template-columns: 1fr;
}
.swap-container {
flex-direction: row;
justify-content: center;
margin: 10px 0;
}
header {
flex-direction: column;
text-align: center;
}
.logo {
justify-content: center;
}
}
</style>
</head>
<body>
<div class="notification" id="notification">
<i class="fas fa-check-circle"></i> Translation successful!
</div>
<div class="container">
<header>
<div class="logo">
<i class="fas fa-language"></i>
<div class="logo-text">
<h1>Global Translator</h1>
<p>Powered by MyMemory Translation API</p>
</div>
</div>
<div class="api-status">
<div class="status-dot"></div>
<span>API Connected - Key Active</span>
</div>
</header>
<div class="main-content">
<div class="language-box">
<div class="language-header">
<h2><i class="fas fa-edit"></i> Source Text</h2>
</div>
<select id="sourceLang">
<option value="auto">Detect Language</option>
<option value="en" selected>English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="it">Italian</option>
<option value="pt">Portuguese</option>
<option value="ru">Russian</option>
<option value="zh">Chinese</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="ar">Arabic</option>
<option value="hi">Hindi</option>
</select>
<textarea id="sourceText" placeholder="Enter text to translate...">Hello, how are you today?</textarea>
<div class="char-count"><span id="charCount">23</span> characters</div>
<div class="language-options">
<div class="lang-option active" data-lang="en">English</div>
<div class="lang-option" data-lang="es">Spanish</div>
<div class="lang-option" data-lang="fr">French</div>
<div class="lang-option" data-lang="de">German</div>
</div>
</div>
<div class="swap-container">
<button class="swap-btn" id="swapBtn">
<i class="fas fa-exchange-alt"></i>
</button>
<button class="translate-btn" id="translateBtn">
<i class="fas fa-exchange-alt"></i> TRANSLATE
</button>
</div>
<div class="language-box">
<div class="language-header">
<h2><i class="fas fa-globe-americas"></i> Translation</h2>
</div>
<select id="targetLang">
<option value="es">Spanish</option>
<option value="en">English</option>
<option value="fr" selected>French</option>
<option value="de">German</option>
<option value="it">Italian</option>
<option value="pt">Portuguese</option>
<option value="ru">Russian</option>
<option value="zh">Chinese</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="ar">Arabic</option>
<option value="hi">Hindi</option>
</select>
<div class="result-box" id="translatedText">
Bonjour, comment allez-vous aujourd'hui?
</div>
<div class="language-options">
<div class="lang-option active" data-lang="fr">French</div>
<div class="lang-option" data-lang="it">Italian</div>
<div class="lang-option" data-lang="pt">Portuguese</div>
<div class="lang-option" data-lang="zh">Chinese</div>
</div>
</div>
</div>
<div class="loading" id="loading">
<i class="fas fa-spinner"></i>
</div>
<div class="footer">
<p>Using API Key: <span class="api-key">8qmCPxTiT6yzFNvuvmR8tDPsiTfZvBlJ</span></p>
<p>Powered by MyMemory Translation API from apilayer.com</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Elements
const sourceText = document.getElementById('sourceText');
const sourceLang = document.getElementById('sourceLang');
const targetLang = document.getElementById('targetLang');
const translateBtn = document.getElementById('translateBtn');
const swapBtn = document.getElementById('swapBtn');
const translatedText = document.getElementById('translatedText');
const loading = document.getElementById('loading');
const charCount = document.getElementById('charCount');
const langOptions = document.querySelectorAll('.lang-option');
const notification = document.getElementById('notification');
// Character counter
sourceText.addEventListener('input', function() {
charCount.textContent = sourceText.value.length;
});
// Language option buttons
langOptions.forEach(option => {
option.addEventListener('click', function() {
const lang = this.getAttribute('data-lang');
const box = this.closest('.language-box');
if (box.querySelector('.language-header h2').textContent.includes('Source')) {
sourceLang.value = lang;
// Update active state for source language options
document.querySelectorAll('.language-box:first-child .lang-option').forEach(opt => {
opt.classList.remove('active');
});
} else {
targetLang.value = lang;
// Update active state for target language options
document.querySelectorAll('.language-box:last-child .lang-option').forEach(opt => {
opt.classList.remove('active');
});
}
this.classList.add('active');
});
});
// Swap languages
swapBtn.addEventListener('click', function() {
const tempLang = sourceLang.value;
sourceLang.value = targetLang.value;
targetLang.value = tempLang;
const tempText = sourceText.value;
sourceText.value = translatedText.textContent;
translatedText.textContent = tempText;
// Update character count
charCount.textContent = sourceText.value.length;
// Swap active language buttons
const sourceActive = document.querySelector('.language-box:first-child .lang-option.active');
const targetActive = document.querySelector('.language-box:last-child .lang-option.active');
if (sourceActive && targetActive) {
const tempLangValue = sourceActive.getAttribute('data-lang');
sourceActive.setAttribute('data-lang', targetActive.getAttribute('data-lang'));
targetActive.setAttribute('data-lang', tempLangValue);
const tempLangText = sourceActive.textContent;
sourceActive.textContent = targetActive.textContent;
targetActive.textContent = tempLangText;
}
});
// Show notification
function showNotification() {
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
// Translate function
async function translateText() {
const text = sourceText.value.trim();
const source = sourceLang.value;
const target = targetLang.value;
if (!text) {
alert('Please enter some text to translate.');
return;
}
if (text.length > 500) {
alert('Text exceeds 500 characters. Please shorten your text.');
return;
}
// Show loading animation
loading.style.display = 'block';
translatedText.textContent = 'Translating...';
try {
// Using MyMemory Translation API
const apiKey = '8qmCPxTiT6yzFNvuvmR8tDPsiTfZvBlJ';
const url = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(text)}&langpair=${source}|${target}&key=${apiKey}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}
const data = await response.json();
if (data.responseStatus === 200 && data.responseData) {
translatedText.textContent = data.responseData.translatedText;
showNotification();
} else {
throw new Error(data.responseDetails || 'Translation failed');
}
} catch (error) {
console.error('Translation error:', error);
translatedText.textContent = 'Error: ' + error.message;
} finally {
// Hide loading animation
loading.style.display = 'none';
}
}
// Translate button event
translateBtn.addEventListener('click', translateText);
// Auto-translate when Enter is pressed (with Shift for new line)
sourceText.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
translateText();
}
});
// Initialize character count
charCount.textContent = sourceText.value.length;
});
</script>
</body>
</html>
Comments
Post a Comment