You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.1 KiB
172 lines
5.1 KiB
import "./common.js";
|
|
import "./earth.js";
|
|
//#region js/about.js
|
|
function counterUpInit() {
|
|
if (!window.counterUp) return;
|
|
const counterUp = window.counterUp.default;
|
|
const callback = (entries) => {
|
|
entries.forEach((entry) => {
|
|
const el = entry.target;
|
|
if (entry.isIntersecting && !el.classList.contains("is-visible")) {
|
|
counterUp(el, {
|
|
duration: 1e3,
|
|
delay: 16
|
|
});
|
|
el.classList.add("is-visible");
|
|
}
|
|
});
|
|
};
|
|
const IO = new IntersectionObserver(callback, { threshold: .5 });
|
|
document.querySelectorAll(".counter").forEach((el) => {
|
|
IO.observe(el);
|
|
});
|
|
}
|
|
function setActiveNav() {
|
|
const pageNav = document.querySelector("[data-nav]")?.getAttribute("data-nav");
|
|
if (!pageNav) return;
|
|
document.querySelectorAll(".site-header__nav a").forEach((link) => {
|
|
const active = link.textContent.trim().startsWith(pageNav);
|
|
link.classList.toggle("is-active", active);
|
|
});
|
|
}
|
|
function initHistorySwiper() {
|
|
const root = document.querySelector(".ab-history");
|
|
const el = root?.querySelector(".ab-history__swiper");
|
|
if (!root || !el || !window.Swiper) return;
|
|
function updateFarClass(swiper) {
|
|
const active = swiper.activeIndex;
|
|
swiper.slides.forEach((slide, i) => {
|
|
slide.classList.toggle("is-far", i > active + 2);
|
|
});
|
|
}
|
|
updateFarClass(new window.Swiper(el, {
|
|
slidesPerView: "auto",
|
|
spaceBetween: 100,
|
|
navigation: {
|
|
prevEl: root.querySelector(".ab-history__head .s-arrows__prev"),
|
|
nextEl: root.querySelector(".ab-history__head .s-arrows__next")
|
|
},
|
|
breakpoints: {
|
|
0: {
|
|
spaceBetween: 32,
|
|
navigation: {
|
|
prevEl: root.querySelector(".ab-history__arrows-mobile .s-arrows__prev"),
|
|
nextEl: root.querySelector(".ab-history__arrows-mobile .s-arrows__next")
|
|
}
|
|
},
|
|
993: { spaceBetween: 100 }
|
|
},
|
|
on: { slideChange: updateFarClass }
|
|
}));
|
|
}
|
|
function initHonorsToggle() {
|
|
const list = document.querySelector(".ab-honors__list");
|
|
const btn = document.querySelector(".ab-honors__more");
|
|
if (!list || !btn) return;
|
|
const items = list.querySelectorAll(".ab-honors__item");
|
|
if (items.length <= 5) {
|
|
btn.style.display = "none";
|
|
return;
|
|
}
|
|
btn.addEventListener("click", () => {
|
|
const expanded = list.classList.toggle("is-expanded");
|
|
btn.classList.toggle("is-expanded", expanded);
|
|
btn.querySelector("span").textContent = expanded ? t("about.collapse") : t("about.expand_more");
|
|
if (expanded) list.setAttribute("data-lenis-prevent", "");
|
|
else list.removeAttribute("data-lenis-prevent");
|
|
});
|
|
}
|
|
function initMembersCarousel() {
|
|
const root = document.querySelector(".ab-members");
|
|
const SwiperCtor = window.Swiper;
|
|
if (!root || !SwiperCtor) return;
|
|
const el = root.querySelector(".ab-members__panels-swiper");
|
|
const buttons = [...root.querySelectorAll(".ab-members__logo")];
|
|
if (!el || !buttons.length) return;
|
|
|
|
const mobileMq = window.matchMedia("(max-width: 576px)");
|
|
const getGroupSize = () => mobileMq.matches ? 2 : 5;
|
|
const total = buttons.length;
|
|
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
const initial = Math.max(0, buttons.findIndex((btn) => btn.classList.contains("is-active")));
|
|
|
|
const swiper = new SwiperCtor(el, {
|
|
initialSlide: initial,
|
|
loop: false,
|
|
grabCursor: true,
|
|
speed: 600,
|
|
autoplay: false
|
|
});
|
|
|
|
const syncNav = (index) => {
|
|
const GROUP = getGroupSize();
|
|
const groupStart = Math.floor(index / GROUP) * GROUP;
|
|
buttons.forEach((btn, i) => {
|
|
const inGroup = total <= GROUP || (i >= groupStart && i < groupStart + GROUP);
|
|
btn.hidden = !inGroup;
|
|
const on = i === index;
|
|
btn.classList.toggle("is-active", on);
|
|
btn.setAttribute("aria-selected", on ? "true" : "false");
|
|
});
|
|
};
|
|
|
|
const goTo = (index) => {
|
|
const next = Math.max(0, Math.min(index, total - 1));
|
|
swiper.slideTo(next);
|
|
syncNav(next);
|
|
};
|
|
|
|
/** 组内下一项;组末跳到下一组第一个;全部结束后回到 0 */
|
|
const nextInSequence = () => {
|
|
const GROUP = getGroupSize();
|
|
const i = swiper.activeIndex;
|
|
const groupStart = Math.floor(i / GROUP) * GROUP;
|
|
const groupEnd = Math.min(groupStart + GROUP - 1, total - 1);
|
|
if (i < groupEnd) goTo(i + 1);
|
|
else if (groupEnd + 1 < total) goTo(groupEnd + 1);
|
|
else goTo(0);
|
|
};
|
|
|
|
let timer = null;
|
|
const stopAutoplay = () => {
|
|
if (timer) {
|
|
clearInterval(timer);
|
|
timer = null;
|
|
}
|
|
};
|
|
const startAutoplay = () => {
|
|
stopAutoplay();
|
|
if (reduceMotion || total <= 1) return;
|
|
timer = setInterval(nextInSequence, 3e3);
|
|
};
|
|
|
|
buttons.forEach((btn, i) => {
|
|
btn.addEventListener("click", () => {
|
|
goTo(i);
|
|
startAutoplay();
|
|
});
|
|
});
|
|
swiper.on("slideChange", () => syncNav(swiper.activeIndex));
|
|
|
|
const onGroupBreakpoint = () => {
|
|
syncNav(swiper.activeIndex);
|
|
startAutoplay();
|
|
};
|
|
if (mobileMq.addEventListener) mobileMq.addEventListener("change", onGroupBreakpoint);
|
|
else mobileMq.addListener(onGroupBreakpoint);
|
|
|
|
const card = root.querySelector(".ab-members__card");
|
|
card?.addEventListener("mouseenter", stopAutoplay);
|
|
card?.addEventListener("mouseleave", startAutoplay);
|
|
|
|
syncNav(swiper.activeIndex);
|
|
startAutoplay();
|
|
}
|
|
$(function() {
|
|
setActiveNav();
|
|
initHistorySwiper();
|
|
counterUpInit();
|
|
initHonorsToggle();
|
|
initMembersCarousel();
|
|
});
|
|
//#endregion
|