// Initial Call document.addEventListener('DOMContentLoaded', function() { // 文章图片灯箱 if (window.ViewImage) { ViewImage.init('.post-content img:not(.amigo-music-card__cover):not(.amigo-voice-avatar):not(.amigo-livephoto-img)'); } // 灯箱增强:滚动关闭 + fade scale 退回动画 (function() { var clickedImg = null; document.addEventListener('click', function(e) { var img = e.target.closest('.post-content img:not(.amigo-music-card__cover):not(.amigo-voice-avatar):not(.amigo-livephoto-img)'); if (img) clickedImg = img; }, true); function closeLightbox() { var lb = document.querySelector('.view-image'); if (!lb) return; // 用 UIkit 内置动画关闭 if (window.UIkit && UIkit.animate) { UIkit.animate(lb, 'uk-animation-fade uk-animation-fast'); setTimeout(function() { lb.remove(); }, 300); } else { lb.classList.add('view-image__out'); setTimeout(function() { lb.remove(); }, 290); } } // 拦截关闭按钮 document.addEventListener('click', function(e) { var lb = e.target.closest('.view-image'); if (!lb) return; var isClose = e.target.closest('.view-image-close') || e.target.closest('.view-image-close__full'); if (!isClose) return; e.stopPropagation(); e.preventDefault(); closeLightbox(); }, true); // 滚动关闭 var lastScrollY = window.scrollY; window.addEventListener('scroll', function() { var lb = document.querySelector('.view-image'); if (!lb) { lastScrollY = window.scrollY; return; } if (Math.abs(window.scrollY - lastScrollY) > 15) { lastScrollY = window.scrollY; closeLightbox(); } }, { passive: true }); })(); // 文章图片懒加载 (优先初始化,防止其他模块调用时出错) if (typeof lazyLoadInit === 'function') { lazyLoadInit({ offsetBottom: 50, offsetTopm: 50, showTime: 1100, queueInterval: 100 }); } else { console.warn('lazyLoadInit is not defined'); } // 初始化各个模块 if (window.initLoader) window.initLoader(); if (window.initFloatingTools) window.initFloatingTools(); if (window.initSearch) window.initSearch(); if (window.initArtalk) window.initArtalk(); // New Utils Init if (window.initThemeToggle) window.initThemeToggle(); if (window.initCodeFold) window.initCodeFold(); if (window.initCodeCopy) window.initCodeCopy(); if (window.initParagraphComments) window.initParagraphComments(); if (window.initInfiniteScroll && window.enableInfiniteScroll) window.initInfiniteScroll(); // Initialize Typewriter Effect for Mobile Header initTypewriter(); // Image frame scroll reveal initImageFrameReveal(); }); /** * Typewriter Effect for Mobile Header Bio */ function initTypewriter() { // Only run on mobile or if the element is visible const bioElement = document.querySelector('.header-bio'); if (!bioElement) return; // Check if we are on mobile (matching CSS media query) const isMobile = window.matchMedia('(max-width: 768px)').matches; if (!isMobile) return; const originalText = bioElement.innerText.trim(); if (!originalText) return; // Clear text initially bioElement.innerText = ''; bioElement.classList.add('typing'); let i = 0; const speed = 100; // Typing speed in ms function typeWriter() { if (i < originalText.length) { bioElement.innerText += originalText.charAt(i); i++; setTimeout(typeWriter, speed); } else { // Typing finished, remove cursor after a delay? // bioElement.classList.remove('typing'); // Keep blinking cursor for effect } } // Start typing with a small delay setTimeout(typeWriter, 500); } /** * Scroll-triggered reveal for sen-image-frame */ var senFrameObserver = null; function initImageFrameReveal() { var frames = document.querySelectorAll('.sen-image-frame'); if (!frames.length) return; if (!window.IntersectionObserver) { frames.forEach(function(frame) { frame.classList.add('is-visible'); }); return; } frames.forEach(function(frame) { frame.classList.add('reveal-pending'); }); if (senFrameObserver) { senFrameObserver.disconnect(); } senFrameObserver = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { entry.target.classList.add('is-visible'); senFrameObserver.unobserve(entry.target); } }); }, { rootMargin: "0px 0px 50px 0px", threshold: 0.08 }); frames.forEach(function(frame) { senFrameObserver.observe(frame); }); } window.initImageFrameReveal = initImageFrameReveal;