Sync Animations Between Components

After the nav was set up, it looked like a sore thumb on the homepage. Reason being, the homepage has that slick animation in which the entire page is dark until the animation plays through. At the end, it fades in white. With the white nav sitting on top of the dark page, the contrast is jarring. What do do?

Coordinating across components

The answer seemed simple enough: animate it to match the home page; dark to light. This started by looking at the <LogoSplash> component. It was really nicely encapsulated and the thought of putting a bunch of code in there for a completely different component made me sad. I needed some way to coordinate the beginning and end of the <LogoSplash> animations from outside the component.

Custom Events to the rescue

Setting up a custom event that dispatches at the start and end of the animation give me the hooks I need to coordinate the navigation component’s animations.

const timelineEvent = (detail:String) => {
  document.dispatchEvent(new CustomEvent('logoSplash', { detail }));
};
...
// Animation start
timelineEvent('begin');
// Animation end
timelineEvent('end');

Then the navigation component listens for the logoSplash event and adds class names that will handle the animation in CSS:

document.addEventListener('logoSplash', ((e:CustomEvent) => {
  const elNav = document.querySelector('#nav-site');
  if (!elNav) return;

  if (e.detail === 'begin') elNav.classList.add('splash-dark');
  if (e.detail === 'end') {
    elNav.classList.remove('splash-dark');
    elNav.classList.add('splash-light');
  }
}) as EventListener);
#nav-site.splash-dark {
  background-color: var(--theme-gray-dark);
  transition: linear 0s;
}
#nav-site.splash-light {
  background-color: var(--theme-base);
  transition: linear 500ms;
}