Canal Street Market

A visual clone of the Canal Street Market site which demonstrates intriguing animations and abnormal layout designs.

Device mockup of Canal Street Market

This is primarily a front-end focused application in which I attempt to recreate the Canal Street Market site with its interesting animations.

Planning and Implementation

The main challenge with cloning the Canal Street Market site was the transition animations. The load-in animations were simple as all we had to do was put a delay on the tabs to stagger animations.

Implementing the transition animations required the creation of a global context which keeps track of the current tab, URL route, whether a navigation animation was in progress, and provides a custom function, nextRoute() to handle page navigation in order for the animations to occur correctly. A portion of what the context does can be seen below:

const nextRoute = (routeIdx: number) => {
if (!canSwitch) return;

setCurrRoute(`/${SiteTabs[routeIdx].route}`);
setInProgress(true);

clearTimeout(timerRef.current); // Debounce timer
timerRef.current = setTimeout(() => {
navigate(SiteTabs[routeIdx].route);
// Make sure we're at the top of the page when we switch pages
window.scrollTo(0, 0);
setCurrTabIdx(routeIdx);
document.body.style.backgroundColor = SiteTabs[routeIdx].color;
}, 500);
};

useEffect(() => {
setCanSwitch(false);
const timeout = setTimeout(() => {
setInProgress(false);
setCanSwitch(true);
}, 250);

return () => {
clearTimeout(timeout);
};
}, [location]);

What the nextRoute() function does is set a timeout for 500ms to allow for the fade-out animation to occur, with checks to see if the animation gets interrupted. After 500ms, the actual navigation will occur with React Router's useNavigate(). When we use useNavigate() to transition between pages, we can use the useLocation() hook to lock the nextRoute() function to allow for the load-in animation to finish (which takes roughly 250ms).