Sticker-eitaa / index.html
Hosdroid's picture
Update index.html
36c3d1b verified
Raw
History Blame Contribute Delete
17.6 kB
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>سازنده هوشمند استیکر ایتا</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn@5.0.19/index.css">
<style>
body {
font-family: 'Vazirmatn', sans-serif;
background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 50%, #fed7aa 100%);
min-height: 100vh;
}
.glass-panel {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.5);
}
.upload-zone {
background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='16' ry='16' stroke='%23EA580C' stroke-width='2' stroke-dasharray='12%2c 12' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
transition: all 0.3s ease;
}
.upload-zone:hover {
background-color: rgba(234, 88, 12, 0.05);
transform: translateY(-2px);
}
.upload-zone.dragover {
background-color: rgba(234, 88, 12, 0.1);
transform: scale(1.02);
}
.fade-in {
animation: fadeIn 0.5s ease-out forwards;
}
.slide-up {
animation: slideUp 0.5s ease-out forwards;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.spinner {
border: 3px solid rgba(234, 88, 12, 0.1);
border-left-color: #ea580c;
border-radius: 50%;
width: 24px;
height: 24px;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.btn-eitaa {
background: linear-gradient(135deg, #ea580c 0%, #c2410c 100%);
transition: all 0.3s ease;
}
.btn-eitaa:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px -5px rgba(234, 88, 12, 0.4);
}
.btn-eitaa:active {
transform: translateY(0);
}
</style>
</head>
<body class="flex items-center justify-center p-4">
<main class="w-full max-w-lg glass-panel rounded-3xl shadow-2xl p-6 md:p-8 slide-up">
<!-- Header -->
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-orange-100 text-orange-600 mb-4 shadow-sm">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/>
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
<line x1="12" y1="19" x2="12" y2="22"/>
</svg>
</div>
<h1 class="text-2xl md:text-3xl font-bold text-gray-800 mb-2">سازنده هوشمند استیکر ایتا</h1>
<p class="text-gray-500 text-sm md:text-base">تبدیل حرفه‌ای و سریع تصاویر به فرمت WebP با کیفیت بالا</p>
</div>
<!-- Upload Zone -->
<div id="uploadZone" class="upload-zone rounded-2xl p-8 text-center cursor-pointer mb-6 relative">
<input type="file" id="fileInput" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
<div class="pointer-events-none">
<svg class="mx-auto h-12 w-12 text-orange-400 mb-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<p class="text-gray-700 font-medium mb-1">برای انتخاب تصویر کلیک کنید</p>
<p class="text-gray-400 text-xs">پشتیبانی از تمام فرمت‌های تصویری (JPG, PNG, WEBP, BMP, TIFF و...)</p>
</div>
</div>
<!-- Loading State -->
<div id="loadingState" class="hidden flex-col items-center justify-center py-8">
<div class="spinner mb-4"></div>
<p class="text-orange-600 font-medium animate-pulse">در حال تحلیل و تبدیل حرفه‌ای به WebP...</p>
</div>
<!-- Error State -->
<div id="errorState" class="hidden bg-red-50 border border-red-200 rounded-2xl p-4 mb-6 fade-in">
<div class="flex items-start">
<svg class="h-6 w-6 text-red-500 ml-3 mt-0.5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<h3 class="text-red-800 font-bold text-sm mb-1">خطا در پردازش</h3>
<p id="errorMessage" class="text-red-600 text-sm"></p>
</div>
</div>
<button id="resetBtn" class="mt-4 w-full py-2 bg-red-100 text-red-700 rounded-xl font-medium hover:bg-red-200 transition-colors text-sm">
تلاش مجدد
</button>
</div>
<!-- Success State -->
<div id="successState" class="hidden fade-in">
<div class="bg-green-50 border border-green-200 rounded-2xl p-4 mb-6 flex items-center">
<svg class="h-6 w-6 text-green-500 ml-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<p class="text-green-800 font-bold text-sm">تبدیل با موفقیت انجام شد!</p>
<p class="text-green-600 text-xs mt-1" id="fileInfo"></p>
</div>
</div>
<div class="relative rounded-2xl overflow-hidden shadow-lg mb-6 bg-gray-100 border border-gray-200">
<img id="previewImage" class="w-full h-auto object-contain max-h-96" alt="پیش‌نمایش استیکر">
<div class="absolute bottom-2 left-2 bg-black/60 text-white text-xs px-2 py-1 rounded-lg backdrop-blur-sm">
فرمت: WEBP
</div>
</div>
<div class="space-y-3">
<button id="shareBtn" class="btn-eitaa w-full py-3.5 rounded-xl text-white font-bold text-base flex items-center justify-center gap-2 shadow-lg shadow-orange-200">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
<polyline points="16 6 12 2 8 6"/>
<line x1="12" y1="2" x2="12" y2="15"/>
</svg>
اشتراک‌گذاری و ارسال به ایتا
</button>
<button id="downloadBtn" class="w-full py-3 rounded-xl bg-gray-100 text-gray-700 font-bold text-base flex items-center justify-center gap-2 hover:bg-gray-200 transition-colors border border-gray-200">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
دانلود فایل WebP
</button>
<p class="text-center text-xs text-gray-400 mt-4 leading-relaxed">
نکته: در صورت عدم پشتیبانی مرورگر از اشتراک‌گذاری مستقیم، فایل به صورت خودکار دانلود شده و ایتا باز می‌شود.
<br>
<a href="https://www.eitaa.com/share/url?url=" target="_blank" class="text-orange-500 hover:underline mt-1 inline-block">قالب اشتراک‌گذاری ایتا</a>
</p>
</div>
</div>
</main>
<script>
const fileInput = document.getElementById('fileInput');
const uploadZone = document.getElementById('uploadZone');
const loadingState = document.getElementById('loadingState');
const errorState = document.getElementById('errorState');
const errorMessage = document.getElementById('errorMessage');
const successState = document.getElementById('successState');
const previewImage = document.getElementById('previewImage');
const fileInfo = document.getElementById('fileInfo');
const resetBtn = document.getElementById('resetBtn');
const shareBtn = document.getElementById('shareBtn');
const downloadBtn = document.getElementById('downloadBtn');
let convertedBlob = null;
let convertedFileName = 'sticker.webp';
// Drag and Drop effects
uploadZone.addEventListener('dragover', (e) => {
e.preventDefault();
uploadZone.classList.add('dragover');
});
uploadZone.addEventListener('dragleave', () => {
uploadZone.classList.remove('dragover');
});
uploadZone.addEventListener('drop', (e) => {
e.preventDefault();
uploadZone.classList.remove('dragover');
if (e.dataTransfer.files.length) {
handleFile(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
});
resetBtn.addEventListener('click', () => {
errorState.classList.add('hidden');
uploadZone.classList.remove('hidden');
fileInput.value = '';
});
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 بایت';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['بایت', 'کیلوبایت', 'مگابایت'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
function showError(msg) {
uploadZone.classList.add('hidden');
loadingState.classList.add('hidden');
errorState.classList.remove('hidden');
errorMessage.textContent = msg;
}
function handleFile(file) {
uploadZone.classList.add('hidden');
errorState.classList.add('hidden');
successState.classList.add('hidden');
loadingState.classList.remove('hidden');
loadingState.classList.add('flex');
// Validation
if (!file.type.startsWith('image/')) {
showError('این ممکن نیست آن تصویری نیست !');
return;
}
if (file.type === 'image/gif' || file.type.startsWith('video/')) {
showError('ایتا قابليت استیکر ویدئویی را ندارد !');
return;
}
// Process Image
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
processImage(img, file.name);
};
img.onerror = () => {
showError('خطا در خواندن فایل تصویر. لطفاً فایل دیگری انتخاب کنید.');
};
img.src = event.target.result;
};
reader.readAsDataURL(file);
}
function processImage(img, originalName) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Professional resizing: maintain aspect ratio, max dimension 512px (optimal for stickers)
// If user wants original size, we can skip, but 512px is professional standard for Eitaa stickers.
// The prompt says: "اگر اندازه تصویر 512 پیکسل در کل نبود هیچ اشکالی نیست و خروجی می دهد ایتا به اندازه کاری ندارد"
// So we will keep original size but cap at 1024 to prevent browser crash, and ensure high quality.
let width = img.width;
let height = img.height;
const maxDimension = 1024;
if (width > maxDimension || height > maxDimension) {
if (width > height) {
height = Math.round((height * maxDimension) / width);
width = maxDimension;
} else {
width = Math.round((width * maxDimension) / height);
height = maxDimension;
}
}
canvas.width = width;
canvas.height = height;
// High quality rendering
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(img, 0, 0, width, height);
// Convert to WebP with high quality (0.95)
canvas.toBlob((blob) => {
if (blob) {
convertedBlob = blob;
convertedFileName = originalName.replace(/\.[^/.]+$/, '') + '.webp';
const objectUrl = URL.createObjectURL(blob);
previewImage.src = objectUrl;
fileInfo.textContent = `ابعاد: ${width}×${height} پیکسل | حجم: ${formatBytes(blob.size)}`;
loadingState.classList.add('hidden');
loadingState.classList.remove('flex');
successState.classList.remove('hidden');
} else {
showError('خطا در تبدیل فرمت تصویر. لطفاً دوباره تلاش کنید.');
}
}, 'image/webp', 0.95);
}
downloadBtn.addEventListener('click', () => {
if (!convertedBlob) return;
const url = URL.createObjectURL(convertedBlob);
const a = document.createElement('a');
a.href = url;
a.download = convertedFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
});
shareBtn.addEventListener('click', async () => {
if (!convertedBlob) return;
const file = new File([convertedBlob], convertedFileName, { type: 'image/webp' });
const shareData = {
files: [file],
title: 'استیکر ایتا',
text: 'این استیکر را با سازنده هوشمند استیکر ایتا ساختم!'
};
// Check if Web Share API with files is supported
if (navigator.share && navigator.canShare && navigator.canShare(shareData)) {
try {
await navigator.share(shareData);
} catch (err) {
if (err.name !== 'AbortError') {
fallbackShare();
}
}
} else {
fallbackShare();
}
});
function fallbackShare() {
// Fallback: Download the file and open Eitaa share URL
const url = URL.createObjectURL(convertedBlob);
const a = document.createElement('a');
a.href = url;
a.download = convertedFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// Show alert and open Eitaa
setTimeout(() => {
alert('فایل استیکر دانلود شد.\nاکنون می‌توانید آن را در ایتا ضمیمه کنید.\n\nلینک اشتراک‌گذاری ایتا: https://www.eitaa.com/share/url?url=');
window.open('https://eitaa.com/', '_blank');
}, 500);
}
</script>
</body>
</html>