Pixelated Page Transition

Page Transition
GSAP
JS
Last Updated: Jan 6, 2026
  • To avoid flicker, the transition should be one of the first elements on the page.
<style>
html:not(.transition-2-first-visit).w-mod-js .transition-2_component {
	display: flex;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
if (!sessionStorage.getItem("transition-2-first-visit")) {
	sessionStorage.setItem("transition-2-first-visit", "viewed");
	document.documentElement.classList.add("transition-2-first-visit");
}
document.addEventListener("DOMContentLoaded", () => {
	document.querySelectorAll(".transition-2_component").forEach((component) => {
		if (component.hasAttribute("data-transition-2")) return;
		component.setAttribute("data-transition-2", "");

		document.addEventListener("click", (e) => {
			const link = e.target.closest("a");
			if (!link) return;
			const currentUrl = link.href;
			if (link.hostname !== window.location.host || currentUrl.includes("#") || link.target === "_blank") return;
			e.preventDefault();
			gsap.context(() => {
				let tl = gsap.timeline({ onComplete: () => window.location.href = currentUrl });
				tl.set(component, { display: "flex" });
				tl.fromTo(".transition-2_box", { opacity: 0 }, { opacity: 1, duration: 0.01, ease: "power1.out", stagger: { amount: 0.5, from: "random" } });
			}, component);
		});
		window.onpageshow = e => e.persisted && window.location.reload();

		if (document.documentElement.classList.contains("transition-2-first-visit")) return;
		gsap.context(() => {
			let tl = gsap.timeline();
			tl.set(component, { display: "flex" });
			tl.to(".transition-2_box", { opacity: 0, delay: 0.4, duration: 0.01, ease: "power1.out", stagger: { amount: 0.5, from: "random" } });
			tl.set(component, {display: "none"});
		}, component);

	});
});
</script>