update
This commit is contained in:
78
src/effects/homeEffect.ts
Normal file
78
src/effects/homeEffect.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
|
||||
function showTypingEffect(typingNode: HTMLElement): void {
|
||||
if (!typingNode) return;
|
||||
|
||||
const text = typingNode.innerText;
|
||||
typingNode.innerText = "";
|
||||
let i = 0;
|
||||
|
||||
const typing = setInterval(() => {
|
||||
if (i < text.length) {
|
||||
typingNode.innerText += text.charAt(i);
|
||||
i++;
|
||||
} else {
|
||||
clearInterval(typing);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function startCarousel(containerSelector: string, loop: boolean, startDelay: number): () => void {
|
||||
const containers: NodeListOf<HTMLElement> = document.querySelectorAll(`${containerSelector} .item-big`);
|
||||
const DELAY: number = 120; // Thời gian delay giữa các item trong container
|
||||
const INTERVAL: number = startDelay; // Thời gian trì hoãn trước khi bắt đầu carousel
|
||||
|
||||
// Cập nhật trạng thái item (active, previous)
|
||||
const updateItemState = (items: NodeListOf<HTMLElement>, activeIndex: number): number => {
|
||||
const nextIndex: number = (activeIndex + 1) % items.length;
|
||||
resetItemsState(items); // Xóa các trạng thái 'active' và 'previous'
|
||||
markItemState(items, activeIndex, nextIndex); // Đánh dấu item hiện tại và item tiếp theo
|
||||
return nextIndex;
|
||||
};
|
||||
|
||||
// Hàm reset các trạng thái 'active' và 'previous' của các items
|
||||
const resetItemsState = (items: NodeListOf<HTMLElement>): void => {
|
||||
items.forEach((item: HTMLElement) => {
|
||||
item.classList.remove('active', 'previous');
|
||||
});
|
||||
};
|
||||
|
||||
// Hàm đánh dấu item hiện tại và item tiếp theo
|
||||
const markItemState = (items: NodeListOf<HTMLElement>, activeIndex: number, nextIndex: number): void => {
|
||||
items[activeIndex].classList.add('previous');
|
||||
items[nextIndex].classList.add('active');
|
||||
};
|
||||
|
||||
// Hàm xử lý vòng lặp carousel cho mỗi container
|
||||
const processContainer = (container: HTMLElement, index: number): void => {
|
||||
const items: NodeListOf<HTMLElement> = container.querySelectorAll('.item');
|
||||
let activeIndex: number = Array.from(items).findIndex((item: HTMLElement) => item.classList.contains('active')) || 0;
|
||||
|
||||
setTimeout(() => {
|
||||
activeIndex = updateItemState(items, activeIndex);
|
||||
// Nếu không muốn loop và đã đến item cuối, dừng vòng lặp
|
||||
if (!loop && activeIndex === items.length - 1) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}, index * DELAY); // Delay riêng cho mỗi container
|
||||
};
|
||||
|
||||
// Hàm xử lý tất cả các container
|
||||
const processContainers = (): void => {
|
||||
containers.forEach((container: HTMLElement, index: number) => {
|
||||
processContainer(container, index);
|
||||
});
|
||||
};
|
||||
|
||||
// Chạy vòng lặp carousel theo khoảng thời gian INTERVAL
|
||||
const intervalId: NodeJS.Timeout = setInterval(processContainers, INTERVAL);
|
||||
|
||||
// Trả về hàm dừng vòng lặp khi cần
|
||||
return () => clearInterval(intervalId);
|
||||
}
|
||||
|
||||
export const homePageEffect = {
|
||||
showTypingEffect,
|
||||
startCarousel
|
||||
};
|
||||
Reference in New Issue
Block a user