422 lines
11 KiB
JavaScript
422 lines
11 KiB
JavaScript
// ===============================
|
|
// ✅ Load Header & Footer
|
|
// ===============================
|
|
["header", "footer"].forEach((id) => {
|
|
const file =
|
|
id === "header" ? "components/header.html" : "components/footer.html";
|
|
fetch(file)
|
|
.then((res) => res.text())
|
|
.then((html) => {
|
|
const mount = document.getElementById(id);
|
|
if (!mount) return;
|
|
mount.innerHTML = html;
|
|
if (id === "header") {
|
|
const script = document.createElement("script");
|
|
script.src = "js/navbar.js";
|
|
script.defer = true;
|
|
document.body.appendChild(script);
|
|
}
|
|
});
|
|
});
|
|
|
|
// ===============================
|
|
// ✅ Routes for SPA Navigation
|
|
// ===============================
|
|
const routes = {
|
|
"#/": "pages/home.html",
|
|
"#/our-fund": "pages/our-fund.html",
|
|
"#/our-team": "pages/our-team.html",
|
|
"#/about": "pages/about.html",
|
|
"#/contact": "pages/contact.html",
|
|
"#/blog": "pages/blog.html",
|
|
};
|
|
|
|
// ===============================
|
|
// ✅ Timeline Data
|
|
// ===============================
|
|
const timelineData = {
|
|
1983: {
|
|
icon: "../assests/images/1983-Icon.svg",
|
|
heading: "The beginning",
|
|
sub1: "Set up by Mr. Asit Koticha and Mr. Sameer Koticha,",
|
|
sub2: "ASK Group offers research-based Investment advisory",
|
|
sub3: "",
|
|
},
|
|
1991: {
|
|
icon: "../assests/images/1991-Icon.svg",
|
|
heading: "ASK Raymond James",
|
|
sub1: "ASK Group and Raymond James",
|
|
sub2: "Financial enter into a Partnership",
|
|
sub3: "",
|
|
},
|
|
2007: {
|
|
icon: "../assests/images/2007-Icon.svg",
|
|
heading: "Launch of ASK Wealth Advisors",
|
|
sub1: "Raymond James Financial partnership exits.",
|
|
sub2: "",
|
|
sub3: "",
|
|
},
|
|
2008: {
|
|
icon: "../assests/images/2008-Icon.svg",
|
|
heading: "Launch of ASK multi-family office",
|
|
sub1: "",
|
|
sub2: "",
|
|
sub3: "",
|
|
},
|
|
2013: {
|
|
icon: "../assests/images/2013-Icon.svg",
|
|
heading: "License from SEBI",
|
|
sub1: "ASK Wealth Advisors receives an",
|
|
sub2: "Investment Advisor License from SEBI.",
|
|
sub3: "",
|
|
},
|
|
2015: {
|
|
icon: "../assests/images/2015-Icon.svg",
|
|
heading: "ASK Wealth Advisors adjudged",
|
|
sub1: ` "the best Independent Wealth Advisor, 2015" `,
|
|
sub2: "by Wealth Briefing, Asia.",
|
|
sub3: "",
|
|
},
|
|
2016: {
|
|
icon: "../assests/images/2016-Icon.svg",
|
|
mobileIcon: "../assests/images/2016-Mobile-Icon.svg",
|
|
heading: "",
|
|
sub1: "Advert International acquires minority ",
|
|
sub2: "stake in ASK Group.",
|
|
sub3: "",
|
|
},
|
|
2017: {
|
|
icon: "../assests/images/2015-Icon.svg",
|
|
heading: "ASK Wealth Advisors adjudged",
|
|
sub1: `"One to Watch - Wealth Manager - India Domestic" - Distinction, 2017"`,
|
|
sub2: "by Asian Private Banker.",
|
|
sub3: "",
|
|
},
|
|
2018: {
|
|
icon: "../assests/images/2015-Icon.svg",
|
|
heading:
|
|
"ASK launches its first offshore fund - ASK Global Strategies Fund",
|
|
sub1: "TWICE IN A ROW:",
|
|
sub2: " ASK Wealth advisors adjudged",
|
|
sub3: `"Best Performing Financial Advisor"-Wealth 2016-17 by UTI MF & CNBC TV18.`,
|
|
},
|
|
2019: {
|
|
icon: "../assests/images/1983-Icon.svg",
|
|
heading: "Hall of Fame",
|
|
sub1: `ASK Wealth Advisors inducted into the "Hall of Fame"`,
|
|
sub2: "at the Financial Advisor Awards for the Years ",
|
|
sub3: "2018-19 and 2019-20 by UTI MF & CNBC TV18.",
|
|
},
|
|
2020: {
|
|
icon: "../assests/images/2015-Icon.svg",
|
|
heading: "Outstanding Private Bank",
|
|
sub1: "Outstanding Private Bank for UNHW clients ",
|
|
sub2: "at the Private Banker International Global",
|
|
sub3: "Wealth Summit & Awards 2020, Singapore.",
|
|
},
|
|
2022: {
|
|
icon: "../assests/images/2022-Icon.svg",
|
|
heading: "Blackstone Acquisition",
|
|
sub1: "Blackstone acquires majority stake in ",
|
|
sub2: "ASK Group, Advert International exits.",
|
|
sub3: "",
|
|
},
|
|
};
|
|
|
|
// ===============================
|
|
// ✅ Initialize Timeline & Swiper
|
|
// ===============================
|
|
function initTimelineSwiper() {
|
|
const swiperWrapper = document.querySelector(".swiper-wrapper");
|
|
const timelineItems = document.querySelectorAll(".timeline-item");
|
|
if (!swiperWrapper || !timelineItems.length) return;
|
|
|
|
// ✅ Check if screen width is 768px or below
|
|
const isMobile = window.matchMedia("(max-width: 768px)").matches;
|
|
|
|
swiperWrapper.innerHTML = "";
|
|
Object.keys(timelineData).forEach((year) => {
|
|
const content = timelineData[year];
|
|
const slide = document.createElement("div");
|
|
slide.classList.add("swiper-slide");
|
|
|
|
// ✅ Use mobile icon if on mobile, else desktop
|
|
const iconToUse = isMobile && content.mobileIcon ? content.mobileIcon : content.icon;
|
|
|
|
const headingColor = ["2015", "2017", "2018"].includes(year)
|
|
? "#ffffff"
|
|
: "#b18c4a";
|
|
const sub1Color = ["2015", "2017", "2018"].includes(year)
|
|
? "#b18c4a"
|
|
: "#ffffff";
|
|
const customTopPad = ["2018"].includes(year) ? "1rem" : "";
|
|
|
|
slide.innerHTML = `
|
|
${iconToUse ? `<img src="${iconToUse}" alt="icon" />` : ""}
|
|
<h2>${year}</h2>
|
|
${
|
|
content.heading
|
|
? `<p class="heading" style="color:${headingColor};">${content.heading}</p>`
|
|
: ""
|
|
}
|
|
<div class="sub-heading-container">
|
|
${
|
|
content.sub1
|
|
? `<p style="color:${sub1Color}; padding-top:${customTopPad}">${content.sub1}</p>`
|
|
: ""
|
|
}
|
|
${content.sub2 ? `<p>${content.sub2}</p>` : ""}
|
|
${content.sub3 ? `<p>${content.sub3}</p>` : ""}
|
|
</div>
|
|
`;
|
|
|
|
swiperWrapper.appendChild(slide);
|
|
});
|
|
|
|
// Line fill logic
|
|
const lineFill = document.querySelector(".line-fill");
|
|
const totalKites = timelineItems.length;
|
|
|
|
function updateTimeline(index) {
|
|
timelineItems.forEach((item, i) => {
|
|
item.classList.toggle("active", i === index);
|
|
});
|
|
const timelineWidth =
|
|
document.querySelector(".timeline")?.offsetWidth - 20;
|
|
const newWidth = (timelineWidth / (totalKites - 1)) * index;
|
|
if (lineFill) lineFill.style.width = newWidth + "px";
|
|
}
|
|
|
|
// Initialize Swiper
|
|
const swiper = new Swiper(".mySwiper", {
|
|
spaceBetween: 20,
|
|
centeredSlides: true,
|
|
effect: "fade",
|
|
autoplay: {
|
|
delay: 3000,
|
|
disableOnInteraction: false,
|
|
},
|
|
navigation: {
|
|
nextEl: ".swiper-button-next",
|
|
prevEl: ".swiper-button-prev",
|
|
},
|
|
});
|
|
|
|
swiper.on("slideChange", () => {
|
|
updateTimeline(swiper.realIndex);
|
|
});
|
|
|
|
updateTimeline(0);
|
|
}
|
|
|
|
// ===============================
|
|
// ✅ Generic Swiper Init (Other Pages)
|
|
// ===============================
|
|
function initSwiper() {
|
|
if (document.querySelector(".mySwiper2")) {
|
|
new Swiper(".mySwiper2", {
|
|
slidesPerView: 1.2,
|
|
spaceBetween: 20,
|
|
loop: true,
|
|
autoplay: {
|
|
delay: 2500,
|
|
disableOnInteraction: false,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
// ===============================
|
|
// ✅ Team Drawer
|
|
// ===============================
|
|
window.openDrawer = function (name, role, img, desc) {
|
|
document.getElementById("drawerName").textContent = name;
|
|
document.getElementById("drawerRole").textContent = role;
|
|
document.getElementById("drawerImg").src = img;
|
|
document.getElementById("drawerDesc").innerHTML = desc;
|
|
|
|
const drawer = bootstrap.Offcanvas.getOrCreateInstance(
|
|
document.getElementById("teamDrawer")
|
|
);
|
|
drawer.show();
|
|
};
|
|
|
|
|
|
|
|
|
|
let cards = [];
|
|
let currentIndex = 0;
|
|
let animating = false;
|
|
let isInsideSection = false;
|
|
|
|
function initGsapStackScroll() {
|
|
const section = document.querySelector(".cards-wrapper");
|
|
if (!section) return;
|
|
|
|
cards = Array.from(section.querySelectorAll('.card-scroll'));
|
|
if (!cards.length) return;
|
|
|
|
// Hide all cards initially, show the first one
|
|
gsap.set(cards, { opacity: 0, y: "100%", zIndex: 0 });
|
|
gsap.set(cards[0], { opacity: 1, y: "0px", zIndex: 4 });
|
|
currentIndex = 0;
|
|
|
|
section.addEventListener('mouseenter', () => (isInsideSection = true));
|
|
section.addEventListener('mouseleave', () => (isInsideSection = false));
|
|
|
|
window.removeEventListener("wheel", window._gsapStackHandler);
|
|
window._gsapStackHandler = function (e) {
|
|
if (!isInsideSection) return;
|
|
e.preventDefault();
|
|
if (animating) return;
|
|
|
|
if (e.deltaY > 0) {
|
|
showNextGsapCard();
|
|
} else {
|
|
showPrevGsapCard();
|
|
}
|
|
};
|
|
|
|
window.addEventListener('wheel', window._gsapStackHandler, { passive: false });
|
|
}
|
|
|
|
function showNextGsapCard() {
|
|
if (currentIndex >= cards.length - 1) return;
|
|
animating = true;
|
|
|
|
const current = cards[currentIndex];
|
|
const next = cards[currentIndex + 1];
|
|
|
|
// Animate current card (move it to previous stack position)
|
|
gsap.to(current, {
|
|
y: "40px",
|
|
scale: 0.95,
|
|
opacity: 1,
|
|
duration: 0.8,
|
|
ease: "power2.inOut",
|
|
onComplete: () => current.classList.add("previous")
|
|
});
|
|
|
|
// Animate next card (slide in from below and become active)
|
|
gsap.set(next, { zIndex: 5 }); // Active card gets highest z-index
|
|
gsap.fromTo(
|
|
next,
|
|
{ y: "100%", opacity: 0, scale: 1 },
|
|
{
|
|
y: "60px", // Active card position
|
|
opacity: 1,
|
|
scale: 1,
|
|
duration: 0.8,
|
|
ease: "power2.inOut",
|
|
onComplete: () => {
|
|
adjustPreviousCards();
|
|
animating = false;
|
|
},
|
|
}
|
|
);
|
|
|
|
currentIndex++;
|
|
}
|
|
|
|
function showPrevGsapCard() {
|
|
if (currentIndex <= 0) return;
|
|
animating = true;
|
|
|
|
const current = cards[currentIndex];
|
|
const prev = cards[currentIndex - 1];
|
|
|
|
// Hide current card (slide it down)
|
|
gsap.to(current, {
|
|
y: "100%",
|
|
opacity: 0,
|
|
duration: 0.8,
|
|
ease: "power2.inOut",
|
|
onComplete: () => current.classList.remove("previous")
|
|
});
|
|
|
|
// Bring back previous card as active
|
|
gsap.set(prev, { zIndex: 5 }); // Active card gets highest z-index
|
|
gsap.to(prev, {
|
|
y: "60px", // Active card position
|
|
opacity: 1,
|
|
scale: 1,
|
|
duration: 0.8,
|
|
ease: "power2.inOut",
|
|
onComplete: () => {
|
|
adjustPreviousCards();
|
|
animating = false;
|
|
},
|
|
});
|
|
|
|
currentIndex--;
|
|
}
|
|
|
|
// 🪄 Adjust visible cards (up to 4-layer stack including active card)
|
|
function adjustPreviousCards() {
|
|
// Reset all cards to default state
|
|
gsap.set(cards, { opacity: 0, y: "100%", zIndex: 0 });
|
|
|
|
// Always show the current active card
|
|
if (cards[currentIndex]) {
|
|
gsap.set(cards[currentIndex], {
|
|
y: "60px",
|
|
scale: 1,
|
|
opacity: 1,
|
|
zIndex: 5
|
|
});
|
|
}
|
|
|
|
// Show up to 3 previous cards in the stack
|
|
for (let i = 1; i <= 3; i++) {
|
|
const prevIndex = currentIndex - i;
|
|
if (prevIndex >= 0) {
|
|
const yOffset = 60 - (i * 30); // 60px, 40px, 20px, 0px
|
|
const scale = 1 - (i * 0.05); // 1, 0.95, 0.9, 0.85
|
|
const zIndex = 5 - i; // 5, 4, 3, 2
|
|
|
|
gsap.set(cards[prevIndex], {
|
|
y: `${yOffset}px`,
|
|
scale: scale,
|
|
opacity: 1,
|
|
zIndex: zIndex
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", initGsapStackScroll);
|
|
|
|
|
|
|
|
|
|
|
|
// ===============================
|
|
// ✅ Load Page Content Dynamically
|
|
// ===============================
|
|
function loadPage() {
|
|
const hash = location.hash || "#/";
|
|
const page = routes[hash] || routes["#/"];
|
|
|
|
fetch(page)
|
|
.then((res) => res.text())
|
|
.then((html) => {
|
|
document.getElementById("page-content").innerHTML = html;
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
|
|
// Init all components after content load
|
|
initSwiper();
|
|
initTimelineSwiper();
|
|
initGsapStackScroll();
|
|
})
|
|
.catch(() => {
|
|
document.getElementById("page-content").innerHTML =
|
|
"<h2>Page not found</h2>";
|
|
});
|
|
}
|
|
|
|
// ===============================
|
|
// ✅ Router Event Listener
|
|
// ===============================
|
|
window.addEventListener("hashchange", loadPage);
|
|
loadPage(); // Default load
|