(function() {
"use strict";
window.onload = function(){
/*------------------------------------------------
Sticky Header
------------------------------------------------*/
const getHeaderId = document.querySelector(".navbar-area");
if (getHeaderId) {
window.addEventListener('scroll', event => {
const height = 150;
const { scrollTop } = event.target.scrollingElement;
document.querySelector('#navbar').classList.toggle('sticky', scrollTop >= height);
});
}
/*------------------------------------------------
Back to Top
------------------------------------------------*/
let progressPath = document.getElementById("progress-path");
let progressWrap = document.getElementById("progress-wrap");
let pathLength = progressPath.getTotalLength();
progressPath.style.transition = progressPath.style.webkitTransition = "none";
progressPath.style.strokeDasharray = pathLength + " " + pathLength;
progressPath.style.strokeDashoffset = pathLength;
progressPath.getBoundingClientRect();
progressPath.style.transition = progressPath.style.webkitTransition =
"stroke-dashoffset 10ms linear";
const onScollEvent = function (event) {
let scroll = window.scrollY;
let height = document.body.scrollHeight - window.innerHeight;
let progress = pathLength - (scroll * pathLength) / height;
progressPath.style.strokeDashoffset = progress;
let offset = 50;
if (window.scrollY > offset) {
progressWrap.classList.add("active-progress");
} else {
progressWrap.classList.remove("active-progress");
}
};
onScollEvent();
window.onscroll = onScollEvent;
progressWrap.onclick = function (event) {
window.scroll({ top: 0, behavior: "smooth" });
return false;
};
/*------------------------------------------------
Preloader
------------------------------------------------*/
const getPreloaderId = document.getElementById('preloader');
if (getPreloaderId) {
getPreloaderId.style.display = 'none';
}
};
/*------------------------------------------------
Hero Overlay On mouse move
------------------------------------------------*/
window.addEventListener("load", () => {
const spotlight = document.querySelector('.spotlight');
if (!spotlight) return; // ✅ stop if spotlight doesn't exist
let spotlightSize = 'transparent 20%, rgba(0, 37, 44, 0.4) 30%';
window.addEventListener('mousemove', e => updateSpotlight(e));
window.addEventListener('mousedown', e => {
spotlightSize = 'transparent 10%, rgba(0, 37, 44, 0.7) 25%';
updateSpotlight(e);
});
window.addEventListener('mouseup', e => {
spotlightSize = 'transparent 20%, rgba(0, 37, 44, 0.4) 30%';
updateSpotlight(e);
});
function updateSpotlight(e) {
spotlight.style.backgroundImage =
`radial-gradient(circle at ${e.pageX / window.innerWidth * 100}% ${e.pageY / window.innerHeight * 100}%, ${spotlightSize}`;
}
});
/*------------------------------------------------
Hero Slider One
------------------------------------------------*/
var hero_slider_one = new Swiper('.hero-slider-one', {
spaceBetween: 24,
speed: 1100,
fadeEffect: { crossFade: true },
effect: "fade",
autoplay: {
delay: 3500,
disableOnInteraction: true
},
autoHeight: true,
pagination: {
el: '.hero-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return `
/
`;
}
},
on: {
slideChange: function () {
updateFractionPadding();
},
init: function () {
updateFractionPadding();
}
}
});
var expertise_slider = new Swiper('.expertise-slider', {
autoplay: {
delay: 3500,
disableOnInteraction: true
},
spaceBetween: 24,
pagination: {
el: '.expertise-pagination',
clickable: true
},
breakpoints: {
0: {
slidesPerView: 1
},
576: {
slidesPerView: 2
},
992: {
slidesPerView: 3
},
1200: {
slidesPerView: 4
}
}
})
function updateFractionPadding() {
const currentEl = document.querySelector('.swiper-pagination-current');
const totalEl = document.querySelector('.swiper-pagination-total');
if (currentEl && totalEl) {
currentEl.textContent = currentEl.textContent.padStart(2, '0');
totalEl.textContent = totalEl.textContent.padStart(2, '0');
}
}
/*------------------------------------------------
Testimonial Slider
------------------------------------------------*/
var testimonial_slider_one = new Swiper(".testimonial-slider-one", {
spaceBetween: 24,
speed: 12000,
loop:true,
autoHeight: true,
autoplay: {
delay: 1,
disableOnInteraction: true
},
breakpoints: {
0: {
slidesPerView: 1
},
768: {
slidesPerView: 1.4
},
992: {
slidesPerView: 2.2
},
1200: {
slidesPerView: 2.8
},
1400: {
slidesPerView: 3.2
},
1600: {
slidesPerView: 3.5
},
1920: {
slidesPerView: 4
}
},
});
var sliderContainer = document.querySelector(".testimonial-slider-one");
if (sliderContainer && typeof testimonial_slider_one !== "undefined") {
sliderContainer.addEventListener('mouseenter', function () {
testimonial_slider_one.autoplay.stop();
});
sliderContainer.addEventListener('mouseleave', function () {
testimonial_slider_one.autoplay.start();
});
}
var testimonial_slider_two = new Swiper(".testimonial-slider-two", {
spaceBetween: 0,
speed: 1100,
autoHeight: true,
slidesPerView: 1,
fadeEffect: { crossFade: true },
effect: "fade",
navigation: {
nextEl: ".testimonial-next",
prevEl: ".testimonial-prev",
},
});
/*------------------------------------------------
Service Slider
------------------------------------------------*/
var service_slider_one = new Swiper(".service-slider-one", {
loop: true,
speed: 1500,
spaceBetween: 24,
navigation: {
nextEl: ".service-next",
prevEl: ".service-prev",
},
breakpoints: {
0: {
slidesPerView: 1
},
768: {
slidesPerView: 2
},
992: {
slidesPerView: 2.5
},
1200: {
slidesPerView: 3
},
1300: {
slidesPerView: 3.2
},
1400: {
slidesPerView: 3.4
},
1600: {
slidesPerView: 3.7
},
1920: {
slidesPerView: 4
}
}
});
/*------------------------------------------------
Case Study Slider
------------------------------------------------*/
var case_slider_one = new Swiper(".case-slider-one", {
loop: true,
speed: 1500,
freemode: false,
spaceBetween: 24,
simulateTouch: false,
navigation: {
nextEl: ".case-next",
prevEl: ".case-prev",
},
breakpoints: {
0: {
slidesPerView: 1
},
768: {
slidesPerView: 2
},
992: {
slidesPerView: 1.3
},
1200: {
slidesPerView: 1.4
},
1300: {
slidesPerView: 1.5
},
1400: {
slidesPerView: 1.7
},
1600: {
slidesPerView: 1.9
},
1920: {
slidesPerView: 2.15
}
}
});
/*------------------------------------------------
Blog Slider
------------------------------------------------*/
var blog_slider_one = new Swiper(".blog-slider-one", {
loop: true,
speed: 1500,
freemode: false,
spaceBetween: 24,
pagination: {
el: '.blog-pagination',
clickable: true
},
breakpoints: {
0: {
slidesPerView: 1
},
768: {
slidesPerView: 2
},
1200: {
slidesPerView: 3
}
}
});
/*------------------------------------------------
Service Js
------------------------------------------------*/
/*------------------------------------------------
Counter Js
------------------------------------------------*/
if ("IntersectionObserver" in window) {
let counterObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
let counter = entry.target;
let target = parseInt(counter.innerText);
let step = target / 200;
let current = 0;
let timer = setInterval(function () {
current += step;
counter.innerText = Math.floor(current);
if (parseInt(counter.innerText) >= target) {
clearInterval(timer);
}
}, 10);
counterObserver.unobserve(counter);
}
});
});
let counters = document.querySelectorAll(".counter");
counters.forEach(function (counter) {
counterObserver.observe(counter);
});
}
//Gsap Mousemove Animation
/*------------------------------------------------
Hero Slider One
------------------------------------------------*/
document.addEventListener("mousemove", mouseMoveFunc);
let moveonmouse = gsap.utils.toArray(".moveContent");
function mouseMoveFunc(e) {
moveonmouse.forEach((circle, index) => {
const depth = 65;
const moveX = (e.pageX - window.innerWidth / 2) / depth;
const moveY = (e.pageY - window.innerHeight / 2) / depth;
index ++
gsap.to(circle, {
x: moveX * index,
y: moveY * index,
});
});
}
gsap.registerPlugin(SplitText, ScrollTrigger);
/*------------------------------------------------
GSAP Text Animation
------------------------------------------------*/
//Text Reveal From Bottom
document.addEventListener("DOMContentLoaded", () => {
const titles = document.querySelectorAll(".reveal-text-bottom");
titles.forEach((title) => {
// Split the text into lines
const split = new SplitText(title, { type: "lines" });
const lines = split.lines;
// Clear the original content
title.innerHTML = "";
// Wrap each line into mask > line-inner (preserve inline HTML like )
lines.forEach((line) => {
const mask = document.createElement("div");
mask.className = "reveal-mask";
const inner = document.createElement("div");
inner.className = "line-inner";
inner.innerHTML = line.innerHTML; // ✅ preserve markup
mask.appendChild(inner);
title.appendChild(mask);
});
// Animate each line on scroll
gsap.from(title.querySelectorAll(".reveal-mask .line-inner"), {
y: 60,
opacity: 0,
duration: 0.9,
ease: "power3.out",
stagger: 0.05,
scrollTrigger: {
trigger: title,
start: "top 70%",
toggleActions: "play none play reverse",
},
});
});
});
//Text Reveal By Letters
let split = new SplitText(".reveal-text", { type: "chars" });
gsap.from(split.chars, {
x: 20,
opacity: 0,
duration: 0.6,
ease: "power4.out",
stagger: 0.05
});
//Text Reveal By Words
let split_two = new SplitText(".reveal-text-two", { type: "words" });
gsap.from(split_two.words, {
y: 40,
opacity: 0,
duration: 1.2,
ease: "power4.out",
stagger: 0.15
});
//Text Reveal From Right
window.addEventListener("load", function() {
gsap.registerPlugin(CustomEase);
// Wrap every letter
const textRevealElements = document.querySelectorAll(".reveal-text-right");
textRevealElements.forEach((element) => {
element.innerHTML = element.textContent.replace(
/([-A-Za-z0-9!$#%^&*@()_+|~=`{}\[\]:";'<>?,.\/]+)/g,
'$1
'
);
let words = element.querySelectorAll(".word");
words.forEach((word) => {
word.innerHTML = word.textContent.replace(
/[-A-Za-z0-9!$#%^&*@()_+|~=`{}\[\]:";'<>?,.\/]/g,
""
);
});
const letters = element.querySelectorAll(".letter");
let tl = gsap.timeline({
scrollTrigger: {
trigger: element,
toggleActions: "restart none none reset"
}
});
tl.set(element, { autoAlpha: 1 });
tl.fromTo(
letters,
0.6, {
transformOrigin: "center",
rotationY: 90,
x: 30
}, {
rotationY: 0.1,
x: 0,
stagger: 0.025,
ease: CustomEase.create("custom", "M0,0 C0.425,0.005 0,1 1,1 ")
}
);
});
});
//Title Animation With SplitText
let splitTitleLines = gsap.utils.toArray(".title-anim");
splitTitleLines.forEach(splitTextLine => {
const tl = gsap.timeline({
scrollTrigger: {
trigger: splitTextLine,
start: 'top 90%',
end: 'bottom 60%',
scrub: false,
markers: false,
toggleActions: 'play none none none'
}
});
const itemSplitted = new SplitText(splitTextLine, { type: "words, lines" });
gsap.set(splitTextLine, { perspective: 400 });
itemSplitted.split({ type: "lines" })
tl.from(itemSplitted.lines, { duration: 1, delay: 0.3, opacity: 0, rotationX: -90, force3D: true, transformOrigin: "top center -50", stagger: 0.1 });
});
/*------------------------------------------------
GSAP Image Tilt Effect
------------------------------------------------*/
document.addEventListener("DOMContentLoaded", () => {
const images = document.querySelectorAll(".tilt-img"); // Select all images
images.forEach((img) => {
img.addEventListener("mousemove", (e) => {
const { width, height, left, top } = img.getBoundingClientRect();
const x = (e.clientX - left - width / 2) / width * 2;
const y = (e.clientY - top - height / 2) / height * 2;
gsap.to(img, {
rotateY: x * 15,
rotateX: y * -15,
transformPerspective: 2000,
ease: "power2.out",
duration: 0.3,
});
});
img.addEventListener("mouseleave", () => {
gsap.to(img, {
rotateY: 0,
rotateX: 0,
duration: 0.5,
ease: "power2.out",
});
});
});
});
/*------------------------------------------------
GSAP Parallax Image With Lenis
------------------------------------------------*/
const lenis = new Lenis({
lerp: 0.09
});
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time)=>{
lenis.raf(time * 1000)
})
gsap.utils.toArray('.img-container').forEach(container => {
const img = container.querySelector('img');
const tl = gsap.timeline({
scrollTrigger: {
trigger: container,
scrub: true,
pin: false,
}
});
tl.fromTo(img, {
yPercent: -20,
ease: 'none'
}, {
yPercent: 20,
ease: 'none'
});
});
/*------------------------------------------------
GSAP Move Element On Scroll
------------------------------------------------*/
if (document.querySelector(".move-left")) {
gsap.to('.move-left', {
xPercent: 60,
ease: "none",
scrollTrigger: {
trigger: ".move-left",
start: "0% 85%",
end: "100% 10%",
scrub: true
}
});
}
if (document.querySelector(".move-left-two")) {
gsap.to('.move-left-two', {
xPercent: 15,
ease: "none",
scrollTrigger: {
trigger: ".move-left-two",
start: "0% 85%",
end: "100% 10%",
scrub: true
}
});
}
if (document.querySelector(".move-right")) {
gsap.to('.move-right', {
xPercent: -120,
ease: "none",
scrollTrigger: {
trigger: ".move-right",
start: "0% 85%",
end: "100% 10%",
scrub: true
}
});
}
var move_target = document.querySelector(".move-right-full");
if (move_target) {
const container = document.querySelector('.container-wrapper');
const containerWidth = container?.offsetWidth || 0;
const targetX = -containerWidth * 0.5;
gsap.to(move_target, {
x: targetX,
ease: "none",
scrollTrigger: {
trigger: move_target,
start: "top 85%",
end: "bottom 10%",
scrub: 1
}
});
}
if (document.querySelector(".move-top")) {
gsap.to('.move-top', {
yPercent: -40,
ease: "none",
scrollTrigger: {
trigger: ".move-top",
start: "0% 85%",
end: "100% 10%",
scrub: true
}
});
}
if (document.querySelector(".move-bottom")) {
gsap.to('.move-bottom', {
yPercent: 80,
ease: "none",
scrollTrigger: {
trigger: ".move-bottom",
start: "0% 5%",
end: "100% 0%",
scrub: true
}
});
}
if (document.querySelector(".move-bottom-two")) {
gsap.to('.move-bottom-two', {
yPercent: 20,
ease: "none",
scrollTrigger: {
trigger: ".move-bottom-two",
start: "0% 5%",
end: "100% 0%",
scrub: true
}
});
}
/*------------------------------------------------
scrollCue Slider One
------------------------------------------------*/
scrollCue.init({
threshold: 0.05,
});
})();
try {
// function to set a given theme/color-scheme
function setTheme(themeName) {
localStorage.setItem('exrox_theme', themeName);
document.documentElement.className = themeName;
}
// function to toggle between light and dark theme
function toggleTheme() {
if (localStorage.getItem('exrox_theme') === 'theme-dark') {
setTheme('theme-light');
} else {
setTheme('theme-dark');
}
}
// Immediately invoked function to set the theme on initial load
(function () {
if (localStorage.getItem('exrox_theme') === 'theme-dark') {
setTheme('theme-dark');
document.querySelector('.slider-btn').checked = false;
} else {
setTheme('theme-light');
document.querySelector('.slider-btn').checked = true;
}
})();
} catch (err) {}