File: h:/root/home/kytoffice-001/www/expresstinou/wp-content/themes/home_1772500334/js/card-animations.js
// 文章卡片淡入動畫控制器
class CardAnimationController {
constructor() {
this.cards = [];
this.observer = null;
this.init();
}
init() {
// 等待DOM加載完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.setup());
} else {
this.setup();
}
}
setup() {
// 查找所有文章卡片
this.cards = document.querySelectorAll('.post-card');
if (this.cards.length === 0) return;
// 初始化Intersection Observer
this.setupIntersectionObserver();
// 重置所有卡片狀態
this.resetCards();
// 開始觀察
this.observeCards();
}
setupIntersectionObserver() {
const options = {
root: null,
rootMargin: '50px', // 提前50px觸發動畫
threshold: 0.1 // 當10%可見時觸發
};
this.observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.animateCard(entry.target);
this.observer.unobserve(entry.target); // 動畫後停止觀察
}
});
}, options);
}
resetCards() {
this.cards.forEach((card, index) => {
// 移除CSS動畫,由JS控制
card.style.animation = 'none';
card.classList.add('card-hidden');
// 為每張卡片設置唯一的延遲時間
card.dataset.animationDelay = (index % 3) * 0.1; // 每行3張卡片
});
}
observeCards() {
this.cards.forEach(card => {
this.observer.observe(card);
});
}
animateCard(card) {
const delay = parseFloat(card.dataset.animationDelay) || 0;
setTimeout(() => {
card.classList.remove('card-hidden');
card.classList.add('card-visible');
}, delay * 1000);
}
// 手動觸發所有卡片動畫(用於測試或特殊情況)
animateAllCards() {
this.cards.forEach((card, index) => {
setTimeout(() => {
card.classList.remove('card-hidden');
card.classList.add('card-visible');
}, index * 100);
});
}
}
// 頁面加載後自動初始化
const cardAnimationController = new CardAnimationController();
// 導出到全局作用域供其他腳本使用
window.cardAnimationController = cardAnimationController;