Skydata001's picture
Update index.html
c9fa4a0 verified
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title data-lang-key="pageTitle">SkyData - أداة إزالة الخلفية</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<style>
:root {
--primary-color: #007bff;
--primary-hover: #0056b3;
--glow-color-1: #6366f1;
--glow-color-2: #ec4899;
--glow-color-3: #f59e0b;
--dark-bg: #0d0d1a;
--bg-surface: #1a1a2e;
--text-color: #e0e0e0;
--text-muted: #aaa;
--border-color: #333;
--error-color: #EF665B;
--success-color: #28a745;
}
* {
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
tap-highlight-color: rgba(0, 0, 0, 0);
}
#app-container {
width: 100%;
overflow-x: hidden;
position: relative;
transform: translate3d(0, 0, 0);
min-height: 100vh;
display: flex;
flex-direction: column;
}
html { }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
direction: rtl;
background-color: var(--dark-bg);
color: var(--text-color);
margin: 0; padding: 0;
}
body::before {
content: '';
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(var(--glow-color-1), 0.15),
rgba(var(--glow-color-2), 0.1),
rgba(var(--glow-color-3), 0.15)
);
background-size: 400% 400%;
animation: glowingBackground 20s ease infinite;
z-index: -1;
filter: blur(50px);
}
@keyframes glowingBackground {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
main {
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 30px 0;
}
.main-wrapper {
max-width: 400px;
width: 95%;
}
.form {
display: flex;
flex-direction: column;
gap: 15px;
padding: 30px;
border-radius: 10px;
position: relative;
background-color: var(--bg-surface);
color: var(--text-color);
border: 1px solid var(--border-color);
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
animation: fadeIn 0.5s ease-out;
}
.title {
font-size: 24px;
font-weight: 600;
letter-spacing: -1px;
position: relative;
display: flex;
align-items: center;
color: var(--primary-color);
margin-bottom: 5px;
padding-right: 30px;
}
.title::before, .title::after {
position: absolute;
content: "";
height: 16px;
width: 16px;
border-radius: 50%;
right: 0px;
background-color: var(--primary-color);
}
.title::after { animation: pulse 1s linear infinite; }
.message-intro {
font-size: 14.5px;
color: var(--text-muted);
margin-bottom: 10px;
text-align: right;
}
.submit {
border: none;
outline: none;
padding: 14px;
border-radius: 8px;
color: #fff;
font-size: 1.2em;
font-weight: bold;
background-color: var(--primary-color);
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
margin-top: 15px;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
text-decoration: none;
}
.submit i { margin-left: 10px; }
[dir="rtl"] .submit i { margin-left: 0; margin-right: 10px; }
.submit:hover {
background-color: var(--primary-hover);
transform: translateY(-1px);
box-shadow: 0 6px 12px rgba(0, 123, 255, 0.4);
}
.submit:disabled { background: #555; cursor: not-allowed; box-shadow: none; }
#download-btn {
background-color: var(--success-color);
}
#download-btn:hover {
background-color: #218838;
}
.cancel-button {
display: block;
width: 100%;
text-decoration: none;
border: 1px solid var(--border-color);
outline: none;
padding: 14px;
border-radius: 8px;
color: var(--text-muted);
font-size: 1.2em;
font-weight: bold;
background-color: transparent;
cursor: pointer;
margin-top: 10px;
transition: all 0.3s ease;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.cancel-button i { margin-left: 10px; }
[dir="rtl"] .cancel-button i { margin-left: 0; margin-right: 10px; }
.cancel-button:hover {
background-color: var(--border-color);
color: var(--text-color);
}
.cancel-button:disabled { background: #555; cursor: not-allowed; border-color: #555; }
.loader-spinner {
border: 4px solid #333;
border-top: 4px solid var(--primary-color);
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: none;
margin: 15px auto 0;
}
#result-area {
display:none;
margin-top: 25px;
border-top: 1px solid var(--border-color);
padding-top: 25px;
text-align: center;
}
#result-img {
max-width: 100%;
border-radius: 8px;
border: 1px solid var(--border-color);
}
@keyframes pulse {
from { transform: scale(0.9); opacity: 1; }
to { transform: scale(1.8); opacity: 0; }
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
#global-toast {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 320px;
max-width: 90%;
padding: 15px;
display: none;
align-items: center;
gap: 10px;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
position: fixed;
bottom: -100px;
left: 50%;
transform: translateX(-50%);
z-index: 2000;
transition: opacity 0.3s ease, bottom 0.3s ease;
opacity: 0;
}
#global-toast.show {
display: flex;
opacity: 1;
bottom: 20px;
}
#global-toast.success {
background: #E0F2E9;
border: 1px solid var(--success-color);
}
#global-toast.success .toast-title { color: #155724; }
#global-toast.success .toast-icon { fill: var(--success-color); }
#global-toast.error {
background: #FCE8DB;
border: 1px solid var(--error-color);
}
#global-toast.error .toast-title { color: #71192F; }
#global-toast.error .toast-icon { fill: var(--error-color); }
.toast-icon {
width: 20px;
height: 20px;
flex-shrink: 0;
}
.toast-title {
font-weight: 600;
font-size: 14px;
width: 100%;
line-height: 1.4;
direction: rtl;
}
.toast-close-btn {
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
font-size: 1.5em;
line-height: 1;
padding: 0 5px;
margin-left: auto;
flex-shrink: 0;
}
[dir="rtl"] .toast-close-btn {
margin-left: 0;
margin-right: auto;
}
#global-toast.success .toast-close-btn { color: #155724; }
#global-toast.error .toast-close-btn { color: #71192F; }
/* (تم حذف media query الخاص بـ logo-container) */
</style>
</head>
<body>
<div id="app-container">
<main>
<div class="main-wrapper" id="loginWrapper">
<div class="form">
<p class="title" dir="rtl">
<i class="fas fa-magic" style="margin-left: 10px;"></i>
أداة إزالة الخلفية
</p>
<p class="message-intro">
ارفع صورتك واحصل عليها بخلفية شفافة. (الحد الأقصى: 10 ميجابايت)
</p>
<input type="file" id="file-input" accept="image/png, image/jpeg" style="display: none;">
<label for="file-input" class="submit" id="upload-label">
<i class="fas fa-upload"></i> اختر صورة
</label>
<button id="submit-btn" class="cancel-button" style="display: none;">
<i class="fas fa-rocket"></i> ابدأ المعالجة
</button>
<div class="loader-spinner" id="loadingSpinner"></div>
<div id="result-area">
<h3 style="color: var(--text-color);">النتيجة:</h3>
<img id="result-img" alt="الصورة بعد إزالة الخلفية">
<a href="#" id="download-btn" class="submit" style="display: none; margin-top: 15px;">
<i class="fas fa-download"></i> تحميل الصورة
</a>
</div>
</div>
</div>
</main>
<div id="global-toast">
<svg class="toast-icon" viewBox="0 0 24 24" height="24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m13 13h-2v-6h2zm0 4h-2v-2h2zm-1-15c-1.3132 0-2.61358.25866-3.82683.7612-1.21326.50255-2.31565 1.23915-3.24424 2.16773-1.87536 1.87537-2.92893 4.41891-2.92893 7.07107 0 2.6522 1.05357 5.1957 2.92893 7.0711.92859.9286 2.03098 1.6651 3.24424 2.1677 1.21325.5025 2.51363.7612 3.82683.7612 2.6522 0 5.1957-1.0536 7.0711-2.9289 1.8753-1.8754 2.9289-4.4189 2.9289-7.0711 0-1.3132-.2587-2.61358-.7612-3.82683-.5026-1.21326-1.2391-2.31565-2.1677-3.24424-.9286-.92858-2.031-1.66518-3.2443-2.16773-1.2132-.50254-2.5136-.7612-3.8268-.7612z"></path>
</svg>
<div class="toast-title" id="toast-title"></div>
<button class="toast-close-btn" id="toast-close-btn">&times;</button>
</div>
</div>
<script>
// --- عناصر الواجهة ---
const fileInput = document.getElementById('file-input');
const submitBtn = document.getElementById('submit-btn');
const uploadLabel = document.getElementById('upload-label');
const loadingSpinner = document.getElementById('loadingSpinner');
const resultArea = document.getElementById('result-area');
const resultImg = document.getElementById('result-img');
const downloadBtn = document.getElementById('download-btn');
// --- عناصر الإشعارات (Toast) ---
const globalToast = document.getElementById('global-toast');
const toastTitle = document.getElementById('toast-title');
const toastCloseBtn = document.getElementById('toast-close-btn');
let toastTimer;
// --- دالة إظهار الإشعارات ---
function showToast(message, type = 'success', duration = 5000) {
if (toastTimer) clearTimeout(toastTimer);
toastTitle.innerHTML = message;
globalToast.className = '';
globalToast.classList.add(type);
globalToast.classList.add('show');
if (duration > 0) {
toastTimer = setTimeout(() => {
globalToast.classList.remove('show');
}, duration);
}
}
// --- دالة إخفاء الإشعارات ---
toastCloseBtn.addEventListener('click', () => {
if (toastTimer) clearTimeout(toastTimer);
globalToast.classList.remove('show');
});
// --- معالج حدث اختيار الملف ---
fileInput.addEventListener('change', () => {
globalToast.classList.remove('show');
if (fileInput.files.length > 0) {
const file = fileInput.files[0];
const MAX_SIZE = 10 * 1024 * 1024; // 10 MB
if (file.size > MAX_SIZE) {
showToast('حجم الملف كبير جداً. الحد الأقصى 10 ميجابايت.', 'error', 0);
fileInput.value = '';
submitBtn.style.display = 'none';
resultArea.style.display = 'none';
downloadBtn.style.display = 'none';
return;
}
showToast(`تم اختيار: ${file.name}`, 'success', 3000);
submitBtn.style.display = 'flex';
resultArea.style.display = 'none';
downloadBtn.style.display = 'none';
}
});
// --- معالج حدث الضغط على زر "ابدأ المعالجة" ---
submitBtn.addEventListener('click', async () => {
if (fileInput.files.length === 0) return;
globalToast.classList.remove('show');
loadingSpinner.style.display = 'block';
submitBtn.disabled = true;
uploadLabel.style.pointerEvents = 'none';
uploadLabel.style.opacity = '0.7';
downloadBtn.style.display = 'none';
const formData = new FormData();
const file = fileInput.files[0];
formData.append('file', file);
try {
const response = await fetch('/remove-bg', {
method: 'POST',
body: formData
});
if (!response.ok) throw new Error('فشل المعالجة');
const imageBlob = await response.blob();
const imageUrl = URL.createObjectURL(imageBlob);
resultImg.src = imageUrl;
resultArea.style.display = 'block';
const originalFilename = file.name.split('.').slice(0, -1).join('.');
downloadBtn.download = `${originalFilename}-no-bg.png`;
downloadBtn.href = imageUrl;
downloadBtn.style.display = 'flex';
showToast('اكتملت المعالجة بنجاح!', 'success', 4000);
} catch (error) {
showToast('⚠️ حدث خطأ. حاول بصورة أخرى أو تأكد من اتصالك.', 'error', 0);
downloadBtn.style.display = 'none';
} finally {
loadingSpinner.style.display = 'none';
submitBtn.disabled = false;
uploadLabel.style.pointerEvents = 'auto';
uploadLabel.style.opacity = '1';
}
});
</script>
</body>
</html>