Spaces:
Paused
Paused
| <html lang="fa" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
| <title>Subtitle Studio Pro</title> | |
| <!-- لینک فونتها --> | |
| <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700;900&display=swap" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Lalezar&display=swap" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Amiri:wght@400;700&display=swap" rel="stylesheet"> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> | |
| <!-- لینک به فایل CSS --> | |
| <link rel="stylesheet" href="/static/css/style.css"> | |
| <!-- استایلهای اختصاصی باکسها (به روز شده برای سایز جدید) --> | |
| <style> | |
| .box-style-preview { | |
| background-color: #ffffff; | |
| border-radius: 8px; | |
| padding: 4px 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 2px; | |
| direction: rtl; | |
| font-family: 'Vazirmatn'; | |
| font-weight: 900; | |
| font-size: 0.75rem; | |
| box-shadow: 0 4px 15px rgba(0,0,0,0.5); | |
| max-width: 100%; | |
| overflow: hidden; | |
| white-space: nowrap; | |
| } | |
| .box-word { padding: 2px 4px; border-radius: 4px; transition: all 0.25s cubic-bezier(0.25, 1, 0.5, 1); color: #d1d1d6; position: relative; z-index: 1; } | |
| .box-word.past { color: #000000; } | |
| .box-word.active { background-color: #1a1a1a; color: #ffffff; transform: scale(1.1); box-shadow: 0 4px 10px rgba(0,0,0,0.2); z-index: 2; } | |
| /* استایل آلفا (به روز شده برای سایز جدید) */ | |
| .alpha-style-preview { | |
| background-color: transparent; border-radius: 14px; padding: 5px; display: flex; align-items: center; justify-content: center; | |
| gap: 2px; | |
| direction: rtl; font-family: 'Vazirmatn'; font-weight: 900; font-size: 0.75rem; max-width: 100%; overflow: hidden; white-space: nowrap; | |
| } | |
| .alpha-word { padding: 2px 4px; border-radius: 8px; transition: all 0.25s; color: rgba(255, 255, 255, 0.35); background-color: transparent; position: relative; z-index: 1; } | |
| .alpha-word.past { color: #ffffff; background-color: transparent; } | |
| .alpha-word.active { background: linear-gradient(135deg, #7c4dff, #b388ff); color: #ffffff; transform: scale(1.1); z-index: 2; box-shadow: 0 4px 12px rgba(124, 77, 255, 0.4); } | |
| /* --- استایل پیغام هوشمندانه هوش مصنوعی --- */ | |
| .coach-overlay { | |
| position: fixed; inset: 0; background: rgba(0,0,0,0.75); backdrop-filter: blur(5px); | |
| z-index: 9999; display: none; opacity: 0; transition: opacity 0.3s; | |
| } | |
| .coach-overlay.show { opacity: 1; } | |
| .coach-tooltip { | |
| position: fixed; left: 50%; transform: translateX(-50%); | |
| background: linear-gradient(145deg, #1e1e2e, #161622); border: 2px solid #7C4DFF; | |
| border-radius: 24px; padding: 25px; width: 90%; max-width: 380px; text-align: center; | |
| box-shadow: 0 20px 50px rgba(124, 77, 255, 0.5); | |
| animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; | |
| opacity: 0; | |
| z-index: 10001; | |
| } | |
| @keyframes popIn { | |
| 0% { opacity: 0; transform: translateX(-50%) scale(0.8) translateY(20px); } | |
| 100% { opacity: 1; transform: translateX(-50%) scale(1) translateY(0); } | |
| } | |
| .coach-icon { | |
| width: 75px; height: 75px; background: linear-gradient(135deg, #FF0080, #7C4DFF); | |
| border-radius: 50%; display: flex; align-items: center; justify-content: center; | |
| font-size: 2.5rem; color: #fff; margin: -60px auto 15px auto; | |
| box-shadow: 0 10px 20px rgba(124, 77, 255, 0.6); border: 4px solid #1e1e2e; | |
| } | |
| .coach-title { font-size: 1.3rem; font-weight: 900; color: #fff; margin-bottom: 12px; } | |
| .coach-text { font-size: 0.95rem; color: #e2e8f0; line-height: 1.7; margin-bottom: 25px; } | |
| .coach-btn { | |
| background: linear-gradient(90deg, #7C4DFF, #00D7FF); border: none; padding: 15px 30px; | |
| border-radius: 18px; color: #fff; font-size: 1.1rem; font-weight: bold; font-family: inherit; | |
| cursor: pointer; box-shadow: 0 5px 20px rgba(0, 215, 255, 0.4); transition: transform 0.2s; | |
| width: 100%; | |
| } | |
| .coach-btn:active { transform: scale(0.95); } | |
| .coach-arrow { | |
| position: fixed; font-size: 2.5rem; color: #00D7FF; | |
| animation: bounceArrowDown 1.5s infinite; | |
| filter: drop-shadow(0 0 15px rgba(0,215,255,0.9)); | |
| z-index: 10001; | |
| } | |
| @keyframes bounceArrowDown { | |
| 0%, 100% { transform: translateX(-50%) translateY(0); } | |
| 50% { transform: translateX(-50%) translateY(-15px); } | |
| } | |
| .relative-z-coach { | |
| position: relative; | |
| z-index: 10000 ; | |
| box-shadow: 0 0 0 4px rgba(124, 77, 255, 0.8), 0 0 20px rgba(124, 77, 255, 0.8); | |
| border-radius: 12px; | |
| background: #2a2a2a ; | |
| transition: all 0.3s; | |
| } | |
| /* --- استایلهای دکمه + (اضافه کردن کلمه) کاملاً جدا از کلمه --- */ | |
| .add-word-btn { | |
| display: none; /* فقط وقتی کلمه قبلیش اکتیو هست دیده میشه */ | |
| width: 32px; | |
| height: 32px; | |
| border-radius: 50%; | |
| background: var(--chip-bg); /* همرنگ پسزمینه کلمات دیگر */ | |
| color: #aaa; /* همرنگ متن کلمات دیگر */ | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.1rem; | |
| margin-right: 8px; /* ایجاد فاصله از کلمه */ | |
| cursor: pointer; | |
| transition: transform 0.2s; | |
| z-index: 10; | |
| } | |
| .add-word-btn:active { | |
| transform: scale(0.85); | |
| } | |
| /* نمایش دکمه بدون انیمیشن */ | |
| .word-chip.active + .add-word-btn { | |
| display: flex; | |
| } | |
| /* استایل کلمات اضافه شده دستی (زیر کلمه) */ | |
| .word-chip.manual-word { | |
| font-size: 0.8rem; | |
| padding: 6px 12px; | |
| background: rgba(124, 77, 255, 0.1); | |
| border: 1px dashed #7C4DFF; | |
| color: #ddd; | |
| } | |
| .word-chip.manual-word.active { | |
| background: var(--primary); | |
| border: 1px solid #fff; | |
| color: #fff; | |
| font-weight: bold; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Toast --> | |
| <div id="toastNotification" class="toast-notification"> | |
| <i class="fa-solid fa-circle-check"></i> | |
| <span>این رنگ در حافظه رنگ ها ذخیره شد</span> | |
| </div> | |
| <!-- اینپوت فایل مخفی (برای آپلود) --> | |
| <input type="file" id="fileIn" hidden accept="video/*" onchange="startUpload()"> | |
| <!-- مدال تغییر نام (پروژه) --> | |
| <div id="renameModal" class="modal-overlay"> | |
| <div class="modal-box"> | |
| <div class="modal-title">تغییر نام پروژه</div> | |
| <input type="text" id="renameInput" class="input-field" placeholder="نام جدید را وارد کنید"> | |
| <div class="modal-actions"> | |
| <button class="modal-btn btn-confirm" onclick="saveRename()">ذخیره</button> | |
| <button class="modal-btn btn-cancel" onclick="closeRenameModal()">لغو</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- مدال اضافه کردن کلمه جدید دستی --> | |
| <div id="addWordModal" class="modal-overlay"> | |
| <div class="modal-box"> | |
| <div class="modal-icon" style="color: #00D7FF;"><i class="fa-solid fa-keyboard"></i></div> | |
| <div class="modal-title">اضافه کردن کلمه جدید</div> | |
| <div class="modal-desc">کلمه جدید دقیقاً بعد از کلمه انتخاب شده اضافه میشود و زمانبندی به صورت خودکار محاسبه میگردد.</div> | |
| <input type="text" id="newWordInput" class="input-field" placeholder="کلمه را تایپ کنید..."> | |
| <div class="modal-actions"> | |
| <button class="modal-btn btn-confirm" style="background: #00D7FF; color: #000;" onclick="confirmAddWord()">اضافه کن</button> | |
| <button class="modal-btn btn-cancel" onclick="closeAddWordModal()">انصراف</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- مدال تایید (عمومی) --> | |
| <div id="confirmationModal" class="modal-overlay"> | |
| <div class="modal-box"> | |
| <div id="confirmIcon" class="modal-icon"><i class="fa-solid fa-question-circle"></i></div> | |
| <div id="confirmTitle" class="modal-title">آیا مطمئن هستید؟</div> | |
| <div id="confirmDesc" class="modal-desc">این عمل غیرقابل بازگشت است.</div> | |
| <div class="modal-actions"> | |
| <button id="confirmBtn" class="modal-btn btn-confirm-action">بله</button> | |
| <button class="modal-btn btn-cancel" onclick="closeConfirmationModal()">انصراف</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- منوی مدیریت پروژه (پایین صفحه) --> | |
| <div class="action-sheet-overlay" id="projectActionOverlay" onclick="closeActionSheet()"> | |
| <div class="action-sheet" id="projectActionSheet" onclick="event.stopPropagation()"> | |
| <div class="sheet-title-main">مدیریت پروژه</div> | |
| <button class="sheet-btn" onclick="openRenameModal()"> | |
| <i class="fa-solid fa-pen"></i> تغییر نام | |
| </button> | |
| <button class="sheet-btn delete-btn" onclick="openDeleteConfirmation()"> | |
| <i class="fa-solid fa-trash-can"></i> حذف پروژه | |
| </button> | |
| </div> | |
| </div> | |
| <!-- صفحه خانه --> | |
| <div id="homeScreen"> | |
| <div class="home-header">پروژههای من</div> | |
| <div id="noProjectsPlaceholder" style="display: none;"> | |
| <div class="placeholder-icon"><i class="fa-solid fa-film"></i></div> | |
| <div class="placeholder-text">هنوز پروژهای ساخته نشده!</div> | |
| <p style="color:#555; font-size: 0.9rem; margin-top:10px;">برای شروع، روی دکمه "ایجاد پروژه" بزنید</p> | |
| </div> | |
| <div class="projects-grid" id="projectsGrid"></div> | |
| <button class="fab-add" onclick="document.getElementById('fileIn').click()"> | |
| <i class="fa-solid fa-plus-circle"></i> ایجاد پروژه | |
| </button> | |
| </div> | |
| <!-- بخش ادیتور --> | |
| <div id="editorScreen"> | |
| <div class="top-bar"> | |
| <button class="btn-home" onclick="goHome()"> | |
| <i class="fa-solid fa-arrow-right"></i> | |
| </button> | |
| <div style="font-weight:bold" id="currentProjectTitle">پروژه</div> | |
| <button class="btn-exp" onclick="render()" style="padding: 8px 20px; font-size: 0.9rem;">خروجی نهایی <i class="fa-solid fa-chevron-left"></i></button> | |
| </div> | |
| <div id="workspace"> | |
| <div id="scaler"> | |
| <div id="videoContainer" onclick="togglePlay()"> | |
| <video id="vid" playsinline webkit-playsinline></video> | |
| <div id="playOverlay"><i class="fa-solid fa-play"></i></div> | |
| <div id="subtitleLayer"><div id="activeText" ondblclick="toggleTool('text')"></div></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="magic-bar"> | |
| <button class="btn-ai-magic" onclick="toggleTool('magic')" id="btn-magic"> | |
| <i class="fa-solid fa-wand-magic-sparkles"></i> | |
| <span>طراحـی هوشمـنـد AI</span> | |
| </button> | |
| </div> | |
| <div class="controls-bar"> | |
| <button class="tool-btn" onclick="toggleTool('style')" id="btn-style"><i class="fa-solid fa-layer-group"></i><span>استایل</span></button> | |
| <button class="tool-btn" onclick="toggleTool('appearance')" id="btn-appearance"><i class="fa-solid fa-palette"></i><span>ظاهر</span></button> | |
| <button class="tool-btn" onclick="toggleTool('font')" id="btn-font"><i class="fa-solid fa-sliders"></i><span>تنظیمات</span></button> | |
| <button class="tool-btn" onclick="toggleTool('text')" id="btn-text"><i class="fa-solid fa-pen-to-square"></i><span>متن</span></button> | |
| </div> | |
| <div id="toolsContainer"> | |
| <!-- ابزار هوش مصنوعی --> | |
| <div id="section-magic" class="tool-section"> | |
| <label>توصیف کنید چه ظاهری میخواهید:</label> | |
| <textarea id="magicPrompt" style="min-height: 60px;" placeholder="مثال: تم نئون صورتی با فونت بولد..."></textarea> | |
| <button class="btn-magic-action" onclick="generateAIStyle()"> | |
| <i class="fa-solid fa-sparkles"></i> اعمال طراحی | |
| </button> | |
| </div> | |
| <!-- ابزار استایل --> | |
| <div id="section-style" class="tool-section"> | |
| <div class="custom-style-container" id="customAccordion" onclick="toggleCustomAccordion()"> | |
| <div class="custom-header"> | |
| <div class="custom-header-title"> | |
| <i class="fa-solid fa-sliders"></i> استایل اختصاصی | |
| </div> | |
| <i class="fa-solid fa-chevron-down toggle-icon"></i> | |
| </div> | |
| <div class="custom-content" onclick="event.stopPropagation()"> | |
| <label>نوع نمایش:</label> | |
| <div class="style-grid-2col" style="margin-bottom: 25px;"> | |
| <div class="style-card" onclick="activateCustomStyle(); setStylePreset('classic', this)" ondblclick="handleClassicDoubleClick(this)" style="background:rgba(0,0,0,0.3); min-height: 100px; aspect-ratio: auto;"> | |
| <div style="font-weight:bold; font-size:1rem; color:#fff;">ساده</div> | |
| <div style="color:#ccc; font-size:0.8rem;">کلاسیک</div> | |
| </div> | |
| <div class="style-card" onclick="activateCustomStyle(); setStylePreset('progressive_write', this)" style="background:rgba(0,0,0,0.3); min-height: 100px; aspect-ratio: auto;"> | |
| <div style="font-weight:bold; font-size:1rem; color:#fff;">کلمه به کلمه</div> | |
| <div style="color:#ccc; font-size:0.8rem;">تایپ تدریجی</div> | |
| </div> | |
| </div> | |
| <div class="color-trigger-row"> | |
| <div class="color-trigger" onclick="openColorPicker('main', event)"> | |
| <span class="color-label">رنگ متن</span> | |
| <div class="color-preview-circle" id="preview-main-btn" style="background-color:#ffffff;"></div> | |
| </div> | |
| <div class="color-trigger" onclick="openColorPicker('bg', event)"> | |
| <span class="color-label">رنگ حاشیه</span> | |
| <div class="color-preview-circle" id="preview-bg-btn" style="background-color:#000000;"></div> | |
| </div> | |
| </div> | |
| <div class="row" style="display:flex; gap:10px;"> | |
| <button class="btn-exp mode-btn active" onclick="activateCustomStyle(); setMode('solid')">کادر پر</button> | |
| <button class="btn-exp mode-btn" onclick="activateCustomStyle(); setMode('transparent')">شیشهای</button> | |
| <button class="btn-exp mode-btn" onclick="activateCustomStyle(); setMode('outline')">فقط دورخط</button> | |
| </div> | |
| </div> | |
| </div> | |
| <div style="border-top:1px solid #333; margin: 20px 0 15px 0;"></div> | |
| <p style="color:#888; font-size:0.85rem; margin-bottom:15px;">قالبهای آماده هوشمند:</p> | |
| <div class="style-grid"> | |
| <!-- ردیف ۱ راست: نئون آلفا --> | |
| <div class="style-card selected" onclick="setStylePreset('alpha_gradient', this)"> | |
| <div class="alpha-style-preview" id="animPreviewAlpha"> | |
| <span class="alpha-word">سلام</span> | |
| <span class="alpha-word">اینجا</span> | |
| <span class="alpha-word">آلفا</span> | |
| <span class="alpha-word">است</span> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">نئون آلفا</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۱ چپ: موزیک پلیر --> | |
| <div class="style-card" onclick="setStylePreset('music_player', this)"> | |
| <div class="music-style-preview" style="height: auto; width:100%; display: flex; align-items: center; justify-content: center; background: transparent;"> | |
| <div style="background: #ffffff; padding: 4px 15px; border-radius: 50px; box-shadow: 0 4px 10px rgba(0,0,0,0.2); color: #000000; font-weight: 900; font-size: 0.7rem; font-family: 'Vazirmatn';"> | |
| <span>سلام اینجا آلفا است</span> | |
| </div> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">موزیک پلیر</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۲ راست: باکس متحرک --> | |
| <div class="style-card" onclick="setStylePreset('instagram_box', this)"> | |
| <div class="box-style-preview" id="animPreviewBox"> | |
| <span class="box-word">سلام</span> | |
| <span class="box-word">اینجا</span> | |
| <span class="box-word">آلفا</span> | |
| <span class="box-word">است</span> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">باکس متحرک</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۲ چپ: کارائوکه رنگی --> | |
| <div class="style-card" onclick="setStylePreset('karaoke_static', this)"> | |
| <div class="anim-box" id="animPreviewStatic"> | |
| <span class="anim-word static-anim">سلام</span> | |
| <span class="anim-word static-anim">اینجا</span> | |
| <span class="anim-word static-anim">آلفا</span> | |
| <span class="anim-word static-anim">است</span> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">کارائوکه رنگی</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۳ راست: هایلایت آبی --> | |
| <div class="style-card" onclick="setStylePreset('auto_director', this)"> | |
| <div class="anim-box"> | |
| <span class="anim-word" style="color:#00D7FF; text-shadow:0 0 10px rgba(0, 215, 255, 0.6);">سلام</span> | |
| <span class="anim-word">اینجا آلفا است</span> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">هایلایت آبی</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۳ چپ: سفید مینیمال --> | |
| <div class="style-card" onclick="setStylePreset('plain_white', this)"> | |
| <div style="font-size:0.9rem; color:#fff; font-weight:900; white-space:nowrap;">سلام اینجا آلفا است</div> | |
| <div class="card-info"> | |
| <div class="card-title-style">سفید مینیمال</div> | |
| </div> | |
| </div> | |
| <!-- ردیف ۴: حاشیه مشکی --> | |
| <div class="style-card" onclick="setStylePreset('white_outline', this)"> | |
| <div style="font-size:0.9rem; color:#fff; font-weight:900; -webkit-text-stroke: 0.8px #000; text-shadow: 1px 1px 2px rgba(0,0,0,0.5); white-space:nowrap;">سلام اینجا آلفا است</div> | |
| <div class="card-info"> | |
| <div class="card-title-style">حاشیه مشکی</div> | |
| </div> | |
| </div> | |
| <!-- استایل جدید: نوار ساده --> | |
| <div class="style-card" onclick="setStylePreset('simple_bar', this)"> | |
| <div style="width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;"> | |
| <div style="width: 60%; height: 4px; background: #fff; border-radius: 2px; position: relative;"> | |
| <div style="width: 50%; height: 6px; background: #FDD835; position: absolute; top: -1px; left: 0; border-radius: 2px; box-shadow: 0 0 5px rgba(253,216,53,0.5);"></div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.2); border-radius: 8px; padding: 4px 10px; font-size: 0.7rem; color: #fff; font-weight: bold;"> | |
| سلام اینجا آلفا است | |
| </div> | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">نوار ساده</div> | |
| </div> | |
| </div> | |
| <!-- استایل جدید: لبههای تیره --> | |
| <div class="style-card" onclick="setStylePreset('dark_edges', this)"> | |
| <div style=" | |
| color: #fff; | |
| font-weight: 900; | |
| font-size: 0.75rem; | |
| padding: 5px 12px; | |
| border-radius: 8px; | |
| background: linear-gradient(to left, rgba(0,0,0,0.8) 0%, transparent 50%, rgba(0,0,0,0.8) 100%), #AA00FF; | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| white-space: nowrap; | |
| "> | |
| سلام اینجا آلفا است | |
| </div> | |
| <div class="card-info"> | |
| <div class="card-title-style">آبی نئون</div> | |
| </div> | |
| </div> | |
| <!-- استایل جدید: ابر نئونی --> | |
| <div class="style-card" onclick="setStylePreset('blue_cloud', this)"> | |
| <div style=" | |
| background: transparent; /* حذف کادر سیاه و شفافسازی پسزمینه */ | |
| padding: 6px 12px; | |
| color: #00b4ff; | |
| font-family: 'Sarbaz', sans-serif; /* هماهنگ کردن فونت پیشفرض به سرباز */ | |
| font-weight: 900; | |
| font-size: 0.9rem; | |
| -webkit-text-stroke: 0.5px #ffffff; | |
| text-shadow: 0 0 10px rgba(0, 162, 255, 0.9); | |
| white-space: nowrap; | |
| ">سلام اینجا آلفا است</div> | |
| <div class="card-info"> | |
| <div class="card-title-style">ابر نئونی</div> <!-- تغییر نام به عنوان شکیلتر --> | |
| </div> | |
| </div> | |
| <!-- استایل جدید: آبی دورسفید (بدون ابر) --> | |
| <div class="style-card" onclick="setStylePreset('blue_outline', this)"> | |
| <div style=" | |
| background: transparent; | |
| padding: 6px 12px; | |
| color: #0000FF; | |
| font-family: 'Sarbaz', sans-serif; | |
| font-weight: 900; | |
| font-size: 0.9rem; | |
| -webkit-text-stroke: 1.3px #ffffff; | |
| paint-order: stroke fill; | |
| -webkit-paint-order: stroke fill; | |
| white-space: nowrap; | |
| ">سلام اینجا آلفا است</div> | |
| <div class="card-info"> | |
| <div class="card-title-style">حاشیه سفید</div> | |
| </div> | |
| </div> | |
| <!-- استایل جدید: کلمات ریزان (نسخه با کلمه فعال) --> | |
| <div class="style-card" onclick="setStylePreset('falling_words', this)"> | |
| <div style="background-color: #F77D57; padding: 6px 14px; border-radius: 12px; direction: rtl; font-family: 'Vazirmatn'; font-weight: 900; font-size: 0.75rem; color: #fff; display: flex; gap: 4px; min-width: 100px; justify-content: center;"> | |
| <span class="fw-anim fw-1">سلام</span> | |
| <span class="fw-anim fw-2">اینجا</span> | |
| <span class="fw-anim fw-3">آلفا</span> | |
| <span class="fw-anim fw-4">است</span> | |
| </div> | |
| <style> | |
| .fw-anim { display: inline-block; opacity: 0; transform: translateY(-15px); color: #fff; } | |
| .fw-1 { animation: fwDrop1 4s infinite; } | |
| .fw-2 { animation: fwDrop2 4s infinite; } | |
| .fw-3 { animation: fwDrop3 4s infinite; } | |
| .fw-4 { animation: fwDrop4 4s infinite; } | |
| @keyframes fwDrop1 { | |
| 0% { opacity: 0; transform: translateY(-15px); color: #FFEB3B; } | |
| 10%, 20% { opacity: 1; transform: translateY(0); color: #FFEB3B; } | |
| 21%, 85% { opacity: 1; transform: translateY(0); color: #fff; } | |
| 86%, 100% { opacity: 0; transform: translateY(0); } | |
| } | |
| @keyframes fwDrop2 { | |
| 0%, 20% { opacity: 0; transform: translateY(-15px); color: #FFEB3B; } | |
| 30%, 40% { opacity: 1; transform: translateY(0); color: #FFEB3B; } | |
| 41%, 85% { opacity: 1; transform: translateY(0); color: #fff; } | |
| 86%, 100% { opacity: 0; transform: translateY(0); } | |
| } | |
| @keyframes fwDrop3 { | |
| 0%, 40% { opacity: 0; transform: translateY(-15px); color: #FFEB3B; } | |
| 50%, 60% { opacity: 1; transform: translateY(0); color: #FFEB3B; } | |
| 61%, 85% { opacity: 1; transform: translateY(0); color: #fff; } | |
| 86%, 100% { opacity: 0; transform: translateY(0); } | |
| } | |
| @keyframes fwDrop4 { | |
| 0%, 60% { opacity: 0; transform: translateY(-15px); color: #FFEB3B; } | |
| 70%, 85% { opacity: 1; transform: translateY(0); color: #FFEB3B; } | |
| 86%, 100% { opacity: 0; transform: translateY(0); } | |
| } | |
| </style> | |
| <div class="card-info"> | |
| <div class="card-title-style">کلمات ریزان</div> | |
| </div> | |
| </div> | |
| </div> <!-- این تگ بسته شدنِ style-grid هست --> | |
| </div> | |
| <!-- ابزار ظاهر --> | |
| <div id="section-appearance" class="tool-section"> | |
| <div class="control-group-panel"> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-text-height"></i><span>اندازه متن</span></div> | |
| <div class="percent-badge" id="lbl-size">50%</div> | |
| </div> | |
| <div class="range-container"> | |
| <input type="range" id="fz" min="0" max="100" value="50" oninput="updateRange(this, 'lbl-size'); upd()"> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-arrows-left-right"></i><span>موقعیت افقی متن</span></div> | |
| <div class="percent-badge" id="lbl-x">0%</div> | |
| </div> | |
| <div class="range-container"> | |
| <div class="center-marker"></div> | |
| <input type="range" id="posX" min="-100" max="100" value="0" oninput="updateRange(this, 'lbl-x'); upd()"> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-arrows-up-down"></i><span>موقعیت عمودی متن</span></div> | |
| <div class="percent-badge" id="lbl-y">20%</div> | |
| </div> | |
| <div class="range-container"> | |
| <input type="range" id="pos" min="0" max="100" value="20" oninput="updateRange(this, 'lbl-y'); upd()"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="control-group-panel" id="boxControlsPanel"> | |
| <div class="box-preview-area"> | |
| <div id="boxPreview" class="box-preview-element"> | |
| <span>متن نمونه</span> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-vector-square"></i><span>گردی کادر</span></div> | |
| <div class="percent-badge" id="lbl-radius">16px</div> | |
| </div> | |
| <div class="range-container"> | |
| <input type="range" id="radius" min="1" max="50" value="16" oninput="updateRange(this, 'lbl-radius', 'px'); upd()"> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-arrows-left-right-to-line"></i><span>فاصله افقی</span></div> | |
| <div class="percent-badge" id="lbl-paddingX">20px</div> | |
| </div> | |
| <div class="range-container"> | |
| <input type="range" id="paddingX" min="5" max="100" value="20" oninput="updateRange(this, 'lbl-paddingX', 'px'); upd()"> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="header-neon"> | |
| <div class="title-neon"><i class="fa-solid fa-ruler-vertical"></i><span>فاصله عمودی</span></div> | |
| <div class="percent-badge" id="lbl-paddingY">10px</div> | |
| </div> | |
| <div class="range-container"> | |
| <input type="range" id="paddingY" min="5" max="50" value="10" oninput="updateRange(this, 'lbl-paddingY', 'px'); upd()"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ابزار فونت و تنظیمات --> | |
| <div id="section-font" class="tool-section"> | |
| <div class="sub-nav-container"> | |
| <div class="sub-nav-btn" onclick="switchSubTab('opacity', this)">انیمیشن</div> | |
| <div class="sub-nav-btn active" onclick="switchSubTab('settings', this)">رنگ</div> | |
| <div class="sub-nav-btn" onclick="switchSubTab('fonts', this)">فونت</div> | |
| </div> | |
| <!-- تب تنظیمات --> | |
| <div id="sub-settings" class="sub-section-content active"> | |
| <div id="settingsContainerInline"></div> | |
| <div style="text-align:center; color:#666; font-size:0.8rem; margin-top:20px;"> | |
| تنظیمات اختصاصی استایل انتخاب شده | |
| </div> | |
| <!-- پایان تب تنظیمات --> | |
| </div> | |
| <!-- تب شفافیت (بخش جدید) --> | |
| <div id="sub-opacity" class="sub-section-content"> | |
| <div class="settings-row-toggle active"> | |
| <div class="setting-header" onclick="toggleUnreadOpacity(this)"> | |
| <div class="settings-left-part"> | |
| <div class="settings-icon-box"> | |
| <svg viewBox="0 0 24 24" fill="var(--primary)" style="width:20px; height:20px;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg> | |
| </div> | |
| <span class="settings-label">کم رنگ شدن کلمات جلو</span> | |
| </div> | |
| <div class="premium-toggle"></div> | |
| </div> | |
| </div> | |
| <div style="text-align:center; color:#666; font-size:0.8rem; margin-top:15px; padding:0 10px;"> | |
| با فعال کردن این گزینه کلمات جلو کمرنگ خواهد شد. | |
| </div> | |
| <!-- دکمه جدید برای کمرنگ شدن جلو و عقب --> | |
| <div id="surroundingToggleCard" class="settings-row-toggle" style="margin-top: 15px;"> | |
| <div class="setting-header" onclick="toggleSurroundingOpacity(this)"> | |
| <div class="settings-left-part"> | |
| <div class="settings-icon-box"> | |
| <svg viewBox="0 0 24 24" fill="var(--primary)" style="width:20px; height:20px;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-2-5.5l5-3.5-5-3.5v7z"/></svg> | |
| </div> | |
| <span class="settings-label">کم رنگ شدن کلمات جلو و عقب</span> | |
| </div> | |
| <div class="premium-toggle"></div> | |
| </div> | |
| </div> | |
| <div style="text-align:center; color:#666; font-size:0.8rem; margin-top:15px; padding:0 10px;"> | |
| با فعال کردن این گزینه، کلمات قبل و بعد از کلمه فعال کمرنگ میشوند. | |
| </div> | |
| <div id="typewriterToggleCard" class="settings-row-toggle" style="margin-top: 15px;"> | |
| <div class="setting-header" onclick="toggleTypewriter(this)"> | |
| <div class="settings-left-part"> | |
| <div class="settings-icon-box"> | |
| <svg viewBox="0 0 24 24" fill="var(--primary)" style="width:20px; height:20px;"><path d="M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z"/></svg> | |
| </div> | |
| <span class="settings-label">انیمیشن تایپ شدن حروف</span> | |
| </div> | |
| <div class="premium-toggle"></div> | |
| </div> | |
| </div> | |
| <div style="text-align:center; color:#666; font-size:0.8rem; margin-top:15px; padding:0 10px;"> | |
| با فعال کردن این گزینه، کلمات آینده مخفی شده و حروف به نرمی تایپ میشوند. | |
| </div> | |
| </div> | |
| <!-- تب فونت --> | |
| <div id="sub-fonts" class="sub-section-content"> | |
| <div class="font-grid"> | |
| <button class="font-btn" style="font-family:'Lalezar'; font-size:1rem;" onclick="setFont('lalezar', this)">لاله زار</button> | |
| <button class="font-btn ticked" style="font-family:'Pinar'; font-size:1rem;" onclick="setFont('pinar', this)">پینار</button> | |
| <button class="font-btn" style="font-family:'Amiri'; font-weight:bold; font-size:1rem;" onclick="setFont('amiri', this)">امیری</button> | |
| <button class="font-btn" style="font-family:'Sarbaz'; font-size:1rem;" onclick="setFont('sarbaz', this)">سرباز</button> | |
| <button class="font-btn" style="font-family:'IranNastaliq'; font-size:1rem;" onclick="setFont('nastaliq', this)">نستعلیق</button> | |
| <button class="font-btn" style="font-family:'VazirThin'; font-weight:100; font-size:1rem;" onclick="setFont('vazir-thin', this)">وزیر نازک</button> | |
| <button class="font-btn" style="font-family:'MadaThin'; font-weight:200; font-size:1rem;" onclick="setFont('mada-thin', this)">مادا نازک</button> | |
| <button class="font-btn" style="font-family:'ArefBold';" onclick="setFont('aref-bold', this)">دست نویس بولد</button> | |
| <button class="font-btn" style="font-family:'Dastnevis'; font-size:1rem;" onclick="setFont('dastnevis', this)">دستنویس</button> | |
| <button class="font-btn" style="font-family:'Entazar'; font-size:1rem;" onclick="setFont('entazar', this)">انتظار</button> | |
| <button class="font-btn" style="font-family:'Kamran'; font-size:1rem;" onclick="setFont('kamran', this)">تو خالی</button> | |
| <button class="font-btn" style="font-family:'Gharib'; font-size:1rem;" onclick="setFont('gharib', this)">غریب</button> | |
| <button class="font-btn" style="font-family:'Vazirmatn'; font-weight:900; font-size:1rem;" onclick="setFont('vazir', this)">وزیر ضخیم</button> | |
| <button class="font-btn" style="font-family:'Hasti'; font-size:1rem;" onclick="setFont('hasti', this)">هستی</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ابزار متن --> | |
| <div id="section-text" class="tool-section" style="padding: 0;"> | |
| <div class="text-editor-ui"> | |
| <div class="toolbar-area" id="toolbar"> | |
| <div class="tool-circle" onclick="openSheet('delete')"><i class="fa-solid fa-trash-can"></i></div> | |
| <div class="tool-circle" onclick="openColorPicker('word', event)"><i class="fa-solid fa-palette"></i></div> | |
| <div class="tool-circle" onclick="openSheet('text')"><i class="fa-solid fa-pen"></i></div> | |
| <div class="tool-circle" onclick="openSheet('time')"><i class="fa-regular fa-clock"></i></div> | |
| <div class="tool-circle" id="btnSplit" onclick="toggleSplit()"><i class="fa-solid fa-level-down-alt" style="transform: rotate(90deg);"></i></div> | |
| <!-- دکمه تنظیمات/تولید مجدد --> | |
| <div class="tool-circle" onclick="openSheet('regenerate')"><i class="fa-solid fa-gear"></i></div> | |
| </div> | |
| <div class="fixed-info-bar"> | |
| <span class="global-time-text" id="globalTimeDisplay">00:00 / 00:00</span> | |
| </div> | |
| <div class="timeline-scroll-area" id="timelineScroll"> | |
| <div class="spacer"></div> | |
| <div class="spacer"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Backdrop انتخاب رنگ --> | |
| <div id="pickerBackdrop" class="picker-backdrop" onclick="closePicker()"></div> | |
| <!-- Modal اصلی انتخاب رنگ --> | |
| <div id="colorPickerModal" class="picker-modal"> | |
| <div class="picker-header"> | |
| <div class="picker-icon" onclick="saveAndClosePicker()"><i class="fa-solid fa-check"></i></div> | |
| <div style="height: 5px; width: 46px; background: rgba(255,255,255,.18); border-radius: 999px;"></div> | |
| <div class="picker-icon" onclick="closePicker()"><i class="fa-solid fa-xmark"></i></div> | |
| </div> | |
| <div class="picker-tabs"> | |
| <div class="picker-tab" id="tab-manual" onclick="switchTab('manual')">دستی</div> | |
| <div class="picker-tab active" id="tab-spectrum" onclick="switchTab('spectrum')">طیف</div> | |
| <div class="picker-tab" id="tab-grid" onclick="switchTab('grid')">گرید</div> | |
| </div> | |
| <!-- بخش طیف --> | |
| <div id="view-spectrum" class="view-section active-view"> | |
| <div class="spectrum-container" id="spectrumArea"> | |
| <div class="spectrum-overlay"></div> | |
| <div class="spectrum-handle" id="spectrumHandle"></div> | |
| </div> | |
| </div> | |
| <!-- بخش گرید --> | |
| <div id="view-grid" class="view-section"> | |
| <div class="grid-view-container" id="gridContainer"></div> | |
| </div> | |
| <!-- بخش دستی --> | |
| <div id="view-manual" class="view-section"> | |
| <div class="manual-view-container"> | |
| <div class="manual-control-row"> | |
| <input type="number" id="input-r" class="manual-num-input" value="200" oninput="updateRGBFromInputs()"> | |
| <div class="manual-slider-group"> | |
| <div class="manual-label-text">قرمز</div> | |
| <input type="range" id="slider-r" class="rgb-slider" min="0" max="255" value="200" oninput="updateRGBFromSliders()"> | |
| </div> | |
| </div> | |
| <div class="manual-control-row"> | |
| <input type="number" id="input-g" class="manual-num-input" value="200" oninput="updateRGBFromInputs()"> | |
| <div class="manual-slider-group"> | |
| <div class="manual-label-text">سبز</div> | |
| <input type="range" id="slider-g" class="rgb-slider" min="0" max="255" value="200" oninput="updateRGBFromSliders()"> | |
| </div> | |
| </div> | |
| <div class="manual-control-row"> | |
| <input type="number" id="input-b" class="manual-num-input" value="200" oninput="updateRGBFromInputs()"> | |
| <div class="manual-slider-group"> | |
| <div class="manual-label-text">آبی</div> | |
| <input type="range" id="slider-b" class="rgb-slider" min="0" max="255" value="200" oninput="updateRGBFromSliders()"> | |
| </div> | |
| </div> | |
| <div class="hex-row"> | |
| <input type="text" id="input-hex" class="hex-input" value="C8C8C8" oninput="updateFromHexInput()"> | |
| <span class="hex-label"># Hex Color</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- اسلایدرهای سراسری --> | |
| <div class="sliders-global-wrapper"> | |
| <div class="global-slider-row" id="brightness-row"> | |
| <div class="value-pill" title="روشنایی"> | |
| <i class="fa-solid fa-sun"></i> | |
| <span><span id="disp-brightness">100</span>%</span> | |
| </div> | |
| <div class="global-slider-container"> | |
| <div class="global-label-top">روشنایی</div> | |
| <input type="range" id="brightness-slider" class="common-slider" min="0" max="100" value="100" oninput="updateBrightness()"> | |
| </div> | |
| </div> | |
| <div class="global-slider-row"> | |
| <div class="value-pill" title="شفافیت"> | |
| <i class="fa-solid fa-droplet"></i> | |
| <span><span id="disp-alpha">56</span>%</span> | |
| </div> | |
| <div class="global-slider-container" style="background: transparent; border:none; padding:0;"> | |
| <div class="global-label-top" style="right: 2px;">شفافیت</div> | |
| <div class="alpha-checkered"> | |
| <input type="range" id="alpha-slider" class="common-slider" min="0" max="100" value="56" oninput="updateAlpha()"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer Modal --> | |
| <div class="picker-footer"> | |
| <div class="large-preview" id="largeColorPreview"></div> | |
| <div class="saved-colors-container" id="savedColorsContainer"> | |
| <div class="btn-save-text" onclick="saveCurrentColor()"> | |
| <i class="fa-solid fa-save"></i> | |
| <span>ذخیره رنگ</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Modal Delete Color --> | |
| <div id="deleteModal" class="delete-overlay"> | |
| <div class="delete-box"> | |
| <div id="delColorPreview" class="del-preview"></div> | |
| <p class="del-title">آیا این رنگ حذف شود؟</p> | |
| <div class="del-actions"> | |
| <button class="del-btn del-btn-confirm" type="button" onclick="confirmDelete()">حذف</button> | |
| <button class="del-btn del-btn-cancel" type="button" onclick="closeDeleteModal()">انصراف</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- شیتهای ویرایش پایین صفحه --> | |
| <div class="bottom-sheet-overlay" id="sheetOverlay" onclick="closeAllSheets()"> | |
| <!-- ویرایش متن --> | |
| <div class="bottom-sheet" id="sheet-text" onclick="event.stopPropagation()"> | |
| <div class="sheet-handle"></div> | |
| <div class="sheet-title">ویرایش متن</div> | |
| <input type="text" id="textInput" class="sheet-input"> | |
| <div class="sheet-meta-row"> | |
| <span class="time-display-text" id="textTimeDisplay">00.00 -> 00.00</span> | |
| <button class="mini-play-btn" id="btnPreviewPlay" onclick="playPreviewWord()"><i class="fa-solid fa-play"></i></button> | |
| </div> | |
| <div class="sheet-actions"> | |
| <button class="action-btn btn-apply-sheet" onclick="saveText()">اعمال</button> | |
| <button class="action-btn btn-cancel-sheet" onclick="closeAllSheets()">لغو</button> | |
| </div> | |
| </div> | |
| <!-- ویرایش زمان (بازطراحی شده) --> | |
| <div class="bottom-sheet" id="sheet-time" onclick="event.stopPropagation()"> | |
| <div class="sheet-handle"></div> | |
| <!-- هدر: دکمه پخش و زمان --> | |
| <div class="trimmer-header"> | |
| <button id="btnTimeSheetPlay" class="trimmer-play-btn" onclick="playPreviewWord()"> | |
| <i id="btnTimeSheetPlayIcon" class="fa-solid fa-play"></i> | |
| </button> | |
| <div class="trimmer-time-display"> | |
| <span id="trimStartDisp">00:03.62</span> - <span id="trimEndDisp">00:03.88</span> | |
| </div> | |
| </div> | |
| <!-- بدنه: نوار برش و کلمات قبل/بعد --> | |
| <div class="trimmer-body"> | |
| <!-- کلمه قبل --> | |
| <div class="word-preview-side left" id="prevWordPreview">دردی</div> | |
| <!-- نوار زمانی --> | |
| <div class="trimmer-container" id="trimmerContainer"> | |
| <div class="timeline-strip" id="timelineStrip"> | |
| <!-- اینجا هندلها قرار میگیرند --> | |
| <div class="trim-handle left" id="handleLeft"> | |
| <i class="fa-solid fa-chevron-left"></i> | |
| </div> | |
| <div class="trim-track-active" id="trackActive"></div> | |
| <div class="trim-handle right" id="handleRight"> | |
| <i class="fa-solid fa-chevron-right"></i> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- کلمه بعد --> | |
| <div class="word-preview-side right" id="nextWordPreview">رفتی</div> | |
| </div> | |
| <!-- کلمه جاری (وسط) --> | |
| <div class="trimmer-current-word" id="timeSheetWord">چه</div> | |
| <!-- دکمههای اکشن --> | |
| <div class="sheet-actions"> | |
| <button class="action-btn" style="background: #7C4DFF; color: #fff; font-size: 1.1rem;" onclick="confirmTimeChanges()">اعمال</button> | |
| <button class="action-btn btn-cancel-sheet" onclick="cancelTimeChanges()" style="font-size: 1rem; background: transparent; color: #fff;">لغو</button> | |
| </div> | |
| </div> | |
| <!-- حذف --> | |
| <div class="bottom-sheet" id="sheet-delete" onclick="event.stopPropagation()"> | |
| <div class="sheet-handle"></div> | |
| <div class="delete-icon-wrap"><i class="fa-solid fa-trash-can"></i></div> | |
| <div class="delete-msg" id="deleteMsgText"></div> | |
| <div class="sheet-actions"> | |
| <button class="action-btn btn-delete-sheet" onclick="confirmDeleteWord()">بله، حذف کن</button> | |
| <button class="action-btn btn-cancel-sheet" onclick="closeAllSheets()">انصراف</button> | |
| </div> | |
| </div> | |
| <!-- تنظیمات / بازتولید --> | |
| <div class="bottom-sheet" id="sheet-regenerate" onclick="event.stopPropagation()"> | |
| <div class="sheet-handle"></div> | |
| <!-- حالت اول: دکمه انجام --> | |
| <div id="regen-step-start" style="width:100%; display:flex; flex-direction:column; gap:15px;"> | |
| <div class="sheet-title" style="font-size:1rem; font-weight:bold; color:#fff;">تنظیمات زیرنویس</div> | |
| <button class="action-btn" style="background: #333; color: white;" onclick="openSheet('wordcount')"> | |
| <i class="fa-solid fa-list-ol"></i> تعداد کلمات در هر بخش | |
| </button> | |
| <button class="action-btn" style="background: linear-gradient(135deg, #FF4081, #7C4DFF); color: white;" onclick="preConfirmRegenerate()"> | |
| <i class="fa-solid fa-wand-magic-sparkles"></i> تولید مجدد زیرنویس | |
| </button> | |
| <p style="color:#666; font-size:0.8rem; text-align:center; margin:0;"> | |
| در صورت عدم رضایت، هوش مصنوعی دوباره تلاش میکند. | |
| </p> | |
| <button class="action-btn btn-cancel-sheet" onclick="closeAllSheets()">بستن</button> | |
| </div> | |
| <!-- حالت دوم: لودینگ --> | |
| <div id="regen-step-loading" style="display:none; width:100%; flex-direction:column; align-items:center; justify-content:center; gap:20px; padding: 20px 0;"> | |
| <div class="sheet-spinner-ring"></div> | |
| <div style="text-align:center;"> | |
| <div style="color:#fff; font-weight:bold; margin-bottom:5px;">هوش مصنوعی در حال بازنویسی...</div> | |
| <div style="color:#888; font-size:0.85rem;">لطفاً صبر کنید...</div> | |
| </div> | |
| </div> | |
| <!-- حالت سوم: موفقیت --> | |
| <div id="regen-step-success" style="display:none; width:100%; flex-direction:column; align-items:center; justify-content:center; gap:15px; padding: 20px 0;"> | |
| <div class="success-checkmark-anim"> | |
| <i class="fa-solid fa-check"></i> | |
| </div> | |
| <div style="color:#00e676; font-weight:bold; font-size:1.1rem;">زیرنویس مجدد تولید شد!</div> | |
| </div> | |
| </div> | |
| <!-- انتخاب تعداد کلمات --> | |
| <div class="bottom-sheet" id="sheet-wordcount" onclick="event.stopPropagation()"> | |
| <div class="sheet-handle"></div> | |
| <div class="sheet-title">تعداد کلمات در هر بخش</div> | |
| <div class="word-count-grid"> | |
| <button class="wc-btn" onclick="resegmentByWordCount(1)">1</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(2)">2</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(3)">3</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(4)">4</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(5)">5</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(6)">6</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(7)">7</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(8)">8</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(9)">9</button> | |
| <button class="wc-btn" onclick="resegmentByWordCount(10)">10</button> | |
| </div> | |
| <button class="action-btn btn-cancel-sheet" onclick="openSheet('regenerate')">بازگشت</button> | |
| </div> | |
| </div> | |
| <!-- پیغام هوشمند هوش مصنوعی --> | |
| <div id="aiCoachMarkOverlay" class="coach-overlay" onclick="closeAITooltip()"> | |
| <div id="coachTooltip" class="coach-tooltip" onclick="event.stopPropagation()"> | |
| <div class="coach-icon"> | |
| <i class="fa-solid fa-robot"></i> | |
| </div> | |
| <div class="coach-title">هوش مصنوعی کارشو انجام داد!</div> | |
| <div class="coach-text"> | |
| متن این ویدیو توسط هوش مصنوعی تولید شده و ممکنه بعضی کلمات به خاطر لحن گفتار نیاز به اصلاح داشته باشن.<br><br> | |
| اگه اشتباه املایی دیدی، کافیه از بخش <b style="color: #00D7FF;">«متن»</b> روی کلمه مورد نظر کلیک کنی و خیلی راحت اصلاحش کنی! | |
| </div> | |
| <button class="coach-btn" onclick="closeAITooltip()">متوجه شدم</button> | |
| </div> | |
| <!-- فلش راهنما به سمت پایین --> | |
| <div id="coachArrow" class="coach-arrow"> | |
| <i class="fa-solid fa-arrow-down"></i> | |
| </div> | |
| </div> | |
| <!-- لودینگ نئونی جدید --> | |
| <div id="loader"> | |
| <div class="loader-wrapper"> | |
| <div class="modern-loader"> | |
| <div class="loader-ring"></div> | |
| <div class="loader-ring"></div> | |
| <div class="loader-ring"></div> | |
| <div class="loader-icon"> | |
| <i class="fa-solid fa-wand-magic-sparkles"></i> | |
| </div> | |
| </div> | |
| <div class="text-container"> | |
| <div class="loading-title" id="loaderTitle">در حال آماده سازی...</div> | |
| <div class="loading-sub" id="queueStatusMsg">لطفاً صبور باشید ☘️</div> | |
| <!-- نوار پیشرفت واقعی --> | |
| <div id="uploadProgressContainer" style="display: none; width: 100%; height: 8px; background: rgba(255,255,255,0.1); border-radius: 10px; margin-top: 15px; overflow: hidden; position: relative;"> | |
| <div id="uploadProgressBar" style="width: 0%; height: 100%; background: linear-gradient(90deg, #b000ff, #0077ff); transition: width 0.2s ease;"></div> | |
| <!-- افکت درخشش روی نوار --> | |
| <div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); animation: progressGlow 1.5s infinite;"></div> | |
| </div> | |
| </div> | |
| <style> | |
| @keyframes progressGlow { | |
| 0% { transform: translateX(-100%); } | |
| 100% { transform: translateX(100%); } | |
| } | |
| </style> | |
| </div> | |
| </div> | |
| <!-- صفحه نتیجه --> | |
| <div id="resultScreen"> | |
| <h3 style="color:#fff; margin-bottom: 15px;">ویدیو آماده شد!</h3> | |
| <div style="width: 90%; max-width: 400px; height: 50vh; background: #111; border-radius: 15px; overflow: hidden; margin-bottom: 25px; display: flex; align-items: center; justify-content: center; border: 1px solid #333;"> | |
| <video id="resultVideo" controls style="max-width:100%; max-height:100%; width:100%; height:100%;"></video> | |
| </div> | |
| <div style="display: flex; gap: 15px;"> | |
| <a id="downloadBtn" href="#" download class="btn-exp" style="background: #00C853; text-decoration: none; display: flex; align-items: center; gap: 8px;"><i class="fa-solid fa-download"></i> دانلود</a> | |
| <button class="btn-exp" style="background: #444;" onclick="closeResult()">بستن</button> | |
| </div> | |
| </div> | |
| <!-- اسکریپت کنترل پیغام هوش مصنوعی (اصلاح شده برای قرارگیری بالای دکمه) --> | |
| <script> | |
| function showAITooltip() { | |
| const overlay = document.getElementById('aiCoachMarkOverlay'); | |
| const targetBtn = document.getElementById('btn-text'); | |
| const tooltip = document.getElementById('coachTooltip'); | |
| const arrow = document.getElementById('coachArrow'); | |
| const controlsBar = document.querySelector('.controls-bar'); | |
| if (!targetBtn || !overlay || !tooltip || !arrow) return; | |
| // بالا آوردن z-index نوار کنترل تا دکمه متن بالای لایه مشکی قرار بگیرد | |
| if (controlsBar) controlsBar.style.zIndex = '10000'; | |
| targetBtn.classList.add('relative-z-coach'); | |
| overlay.style.display = 'block'; | |
| // محاسبه جایگاه دقیق دکمه نسبت به صفحه | |
| const rect = targetBtn.getBoundingClientRect(); | |
| // محاسبه فاصله از پایین صفحه تا بالای دکمه متن | |
| const distFromBottom = window.innerHeight - rect.top; | |
| // قرار دادن پیام بالای دکمه (روی ویدیو) | |
| tooltip.style.top = 'auto'; | |
| tooltip.style.bottom = (distFromBottom + 50) + 'px'; | |
| // قرار دادن فلش دقیقاً بالای دکمه | |
| arrow.style.top = 'auto'; | |
| arrow.style.bottom = (distFromBottom + 10) + 'px'; | |
| arrow.style.left = (rect.left + rect.width / 2) + 'px'; | |
| setTimeout(() => { overlay.classList.add('show'); }, 10); | |
| } | |
| function closeAITooltip() { | |
| const overlay = document.getElementById('aiCoachMarkOverlay'); | |
| const targetBtn = document.getElementById('btn-text'); | |
| const controlsBar = document.querySelector('.controls-bar'); | |
| if (overlay) { | |
| overlay.classList.remove('show'); | |
| setTimeout(() => { | |
| overlay.style.display = 'none'; | |
| // برگرداندن z-index به حالت اولیه پس از بسته شدن | |
| if (controlsBar) controlsBar.style.zIndex = '90'; | |
| if (targetBtn) targetBtn.classList.remove('relative-z-coach'); | |
| }, 300); | |
| } | |
| } | |
| </script> | |
| <!-- اسکریپت انیمیشن باکس --> | |
| <script> | |
| function startBoxAnim() { | |
| const container = document.getElementById('animPreviewBox'); | |
| if(!container) return; | |
| const words = container.querySelectorAll('.box-word'); | |
| let index = 0; | |
| setInterval(() => { | |
| words.forEach((w, i) => { | |
| w.className = 'box-word'; | |
| if (i < index) w.classList.add('past'); | |
| else if (i === index) w.classList.add('active'); | |
| }); | |
| index++; if (index > words.length) index = 0; | |
| }, 700); | |
| } | |
| function startAlphaAnim() { | |
| const container = document.getElementById('animPreviewAlpha'); | |
| if(!container) return; | |
| const words = container.querySelectorAll('.alpha-word'); | |
| let index = 0; | |
| setInterval(() => { | |
| words.forEach((w, i) => { | |
| w.className = 'alpha-word'; | |
| if (i < index) w.classList.add('past'); | |
| else if (i === index) w.classList.add('active'); | |
| }); | |
| index++; if (index > words.length) index = 0; | |
| }, 700); | |
| } | |
| // اجرای انیمیشن هنگام لود | |
| window.addEventListener('load', () => { | |
| startBoxAnim(); | |
| startAlphaAnim(); | |
| }); | |
| </script> | |
| <!-- بارگذاری اسکریپتها --> | |
| <script src="/static/js/globals.js"></script> | |
| <script src="/static/js/utils.js"></script> | |
| <script src="/static/js/db.js"></script> | |
| <script src="/static/js/api.js"></script> | |
| <script src="/static/js/ui.js"></script> | |
| <script src="/static/js/editor.js"></script> | |
| <script src="/static/js/main.js"></script> | |
| </body> | |
| </html> |