Zirnavis90 / static /js /main.js
Opera10's picture
Update static/js/main.js
227fc20 verified
Raw
History Blame Contribute Delete
5.37 kB
// راه‌اندازی اولیه و هندلرهای رویداد اصلی
window.onload = function() {
startAnim('#animPreviewStatic');
initDB().then(() => {
loadHome();
});
syncModeButtons();
const timeline = document.getElementById('timelineScroll');
timeline.addEventListener('touchstart', () => { v.pause(); togglePlayIcon(false); }, {passive: true});
timeline.addEventListener('mousedown', () => { v.pause(); togglePlayIcon(false); });
// هماهنگ‌سازی حرکت انیمیشن ویژوالایزرها با وضعیت پخش و توقف ویدیو
v.addEventListener('play', () => {
const vBars = tEl.querySelectorAll('.v-bar');
vBars.forEach(b => b.style.animationPlayState = 'running');
});
v.addEventListener('pause', () => {
const vBars = tEl.querySelectorAll('.v-bar');
vBars.forEach(b => b.style.animationPlayState = 'paused');
});
};
window.onresize = fit;
// --- موتور زمان‌سنج هوشمند (High-Precision Sync) جایگزین v.ontimeupdate ---
function runFastSync() {
// فقط وقتی ویدیو در حال پخش است یا دستی جابجا می‌شود اجرا شود
if (!v.paused || manualOverride) {
const cur = v.currentTime;
const timeDisplay = document.getElementById('globalTimeDisplay');
if (timeDisplay) {
timeDisplay.innerText = `${formatTimeSimple(cur)} / ${formatTimeSimple(v.duration || 0)}`;
}
if (!v.paused) manualOverride = false;
let foundWord = false;
// اضافه کردن 0.1 ثانیه تلورانس برای دیده شدن کلمات آخر جمله
for (let s = 0; s < state.segs.length; s++) {
const seg = state.segs[s];
if (cur >= seg.start && cur < (seg.end + 0.1)) {
if (seg.words) {
for (let w = 0; w < seg.words.length; w++) {
const word = seg.words[w];
// بررسی فعال بودن کلمه با دقت بالا و تلورانس شروع و پایان
if (cur >= (word.start - 0.02) && cur < (word.end + 0.05)) {
const uid = `${s}-${w}`;
if (activeWordId !== uid) {
activeWordId = uid;
document.querySelectorAll('.word-chip').forEach(c => c.classList.remove('active'));
const el = document.getElementById(`w-${uid}`);
if(el) {
el.classList.add('active');
if(!manualOverride) el.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}
updateSplitButton();
}
foundWord = true;
break;
}
}
}
}
if (foundWord) break;
}
if (!foundWord && !manualOverride) {
document.querySelectorAll('.word-chip').forEach(c => c.classList.remove('active'));
activeWordId = null;
const toolbar = document.getElementById('toolbar');
if (toolbar) toolbar.classList.remove('show');
}
updateOverlayContent(cur);
}
// تکرار مداوم برای دقت ۶۰ فریم در ثانیه
requestAnimationFrame(runFastSync);
}
// شروع به کار موتور همزمان با لود شدن صفحه
requestAnimationFrame(runFastSync);
// --- سیستم لمسی ---
tEl.addEventListener('touchstart', (e) => {
if(e.touches.length === 1) {
// Drag
touchMode = 'drag';
initialY = e.touches[0].clientY;
initialX = e.touches[0].clientX;
initialBottom = state.st.y;
initialXState = state.st.x || 0;
} else if (e.touches.length === 2) {
// Pinch (Zoom)
touchMode = 'pinch';
initialDist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
initialFontSize = state.st.fz;
}
}, {passive: false});
tEl.addEventListener('touchmove', (e) => {
if (!touchMode) return;
e.preventDefault();
if (touchMode === 'drag' && e.touches.length === 1) {
let diffY = (initialY - e.touches[0].clientY) * 1.8;
let newBottom = initialBottom + diffY;
state.st.y = Math.round(newBottom);
let diffX = (e.touches[0].clientX - initialX) * 1.5;
let newX = initialXState + diffX;
state.st.x = Math.round(newX);
syncUIWithState();
upd();
} else if (touchMode === 'pinch' && e.touches.length === 2) {
let dist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
let newSize = initialFontSize * (dist / initialDist);
state.st.fz = Math.round(Math.max(10, Math.min(150, newSize)));
syncUIWithState();
upd();
}
}, {passive: false});
tEl.addEventListener('touchend', () => {
touchMode = null;
saveProjectToDB();
});