(function() {
document.documentElement.classList.add('menu-loading');
const criticalStyle = document.createElement('style');
criticalStyle.textContent = `
html.menu-loading .bf-expandable-menu {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
max-height: 0 !important;
overflow: hidden !important;
transition: none !important;
pointer-events: none !important;
}
`;
document.head.appendChild(criticalStyle);
})();
document.addEventListener('DOMContentLoaded', function() {
const style = document.createElement('style');
style.textContent = `
html.menu-loading * .bf-expandable-menu {
transition: none !important;
}
.bf-expandable-menu {
opacity: 0;
max-height: 0;
margin-bottom: 0;
overflow: hidden;
pointer-events: none;
transform-origin: top center;
transform: translateY(-20px);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, opacity, max-height;
visibility: hidden;
}
.bf-expandable-menu.active {
opacity: 1;
max-height: 520px;
margin-bottom: 16px;
pointer-events: auto;
transform: translateY(0);
visibility: visible;
}
.bf-expandable-menu > * {
opacity: 0;
transform: translateY(-10px);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, opacity;
}
.bf-expandable-menu.active > * {
opacity: 1;
transform: translateY(0);
}
[data-menu-trigger].active-trigger {
background-color: rgba(169, 169, 169, 0.2);
border-radius: 6px;
padding: 6px 12px;
transition: all 0.2s ease;
position: relative;
}
[data-menu-trigger].active-trigger:hover {
background-color: rgba(169, 169, 169, 0.25);
}
.bf-expandable-menu.instant-close,
.bf-expandable-menu.instant-close > * {
transition: none !important;
}
.bf-expandable-menu.no-animation,
.bf-expandable-menu.no-animation > * {
transition: none !important;
}
.bf-blur-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.4));
backdrop-filter: blur(8px);
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 999;
}
.bf-blur-overlay.active {
opacity: 1;
visibility: visible;
}
.Blur {
position: relative;
z-index: 1000;
}
`;
document.head.appendChild(style);
const overlay = document.createElement('div');
overlay.className = 'bf-blur-overlay';
document.body.appendChild(overlay);
const menuTriggers = document.querySelectorAll('[data-menu-trigger]');
const menus = document.querySelectorAll('.bf-expandable-menu');
menus.forEach(menu => {
menu.style.opacity = '0';
menu.style.visibility = 'hidden';
menu.style.maxHeight = '0';
menu.style.overflow = 'hidden';
menu.style.pointerEvents = 'none';
});
function updateTriggerState(targetId, isActive) {
menuTriggers.forEach(trigger => {
const triggerId = trigger.getAttribute('data-menu-trigger');
if (triggerId === targetId) {
isActive
? trigger.classList.add('active-trigger')
: trigger.classList.remove('active-trigger');
}
});
}
function handleMenuTransition(menu, isClosing, instantClose = false) {
return new Promise((resolve) => {
const menuId = menu.id;
if (instantClose) {
menu.classList.add('instant-close');
menu.classList.remove('active');
menu.style.visibility = 'hidden';
overlay.classList.remove('active');
updateTriggerState(menuId, false);
setTimeout(() => {
menu.classList.remove('instant-close');
resolve();
}, 50);
return;
}
if (isClosing) {
menu.classList.remove('active');
overlay.classList.remove('active');
updateTriggerState(menuId, false);
setTimeout(() => {
menu.style.visibility = 'hidden';
resolve();
}, 400);
} else {
menu.style.visibility = 'visible';
requestAnimationFrame(() => {
menu.classList.add('active');
overlay.classList.add('active');
updateTriggerState(menuId, true);
setTimeout(resolve, 50);
});
}
});
}
async function closeAllMenus(exceptMenuId = null) {
const closingPromises = Array.from(menus).map(menu => {
if (menu.id !== exceptMenuId && menu.classList.contains('active')) {
return handleMenuTransition(menu, true, !!exceptMenuId);
}
return Promise.resolve();
});
await Promise.all(closingPromises);
}
menuTriggers.forEach(trigger => {
trigger.addEventListener('click', async function(e) {
e.preventDefault();
e.stopPropagation();
const targetId = this.getAttribute('data-menu-trigger');
const targetMenu = document.getElementById(targetId);
if (!targetMenu) return;
if (targetMenu.classList.contains('active')) {
await handleMenuTransition(targetMenu, true);
return;
}
await closeAllMenus(targetId);
await handleMenuTransition(targetMenu, false);
});
});
document.addEventListener('click', function(e) {
const isClickInsideMenu = Array.from(menus).some(menu => menu.contains(e.target));
const isClickOnTrigger = Array.from(menuTriggers).some(trigger => trigger.contains(e.target));
if (!isClickInsideMenu && !isClickOnTrigger) {
closeAllMenus();
}
});
window.addEventListener('load', function() {
setTimeout(() => {
document.documentElement.classList.remove('menu-loading');
setTimeout(() => {
menus.forEach(menu => {
menu.removeAttribute('style');
});
}, 100);
}, 50);
});
});
v2.0
Instant motion
Bring to life one of the most acclaimed effects by web designers for your clients' projects. Ray Cast will leave no one indifferent.
Crafting exceptional web experiences with cutting-edge design and development. Elevate your digital presence with our expert team.
BF-Ray
Required
Add this attribute only to sections to activate the Ray Cast effect.
bf-instantmotion001
CSS classes
Required
Add this class to your section to make the content of your section (div and containers) visible.
BF-Ray="preset-name"
red
blue
green
orange
yellow
silver
purple
pink
Choose how you'd like to connect with our support team
Get help from our team of experts
Response within 24 hours