Hover Background Flip

Hover
GSAP
FLIP
JS
CMS
Last Updated: Nov 11, 2025
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/Flip.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
	gsap.registerPlugin(Flip);
	document.querySelectorAll(".hover-2_list").forEach(function (component) {
		if (component.hasAttribute("data-hover-2")) return;
		component.setAttribute("data-hover-2", "");

		const items = component.querySelectorAll(".hover-2_item");
		component.querySelectorAll(".hover-2_background").forEach((el, i) => i && el.remove());
		const background = component.querySelector(".hover-2_background");
		const fill = component.querySelector(".hover-2_fill");
		let hoverBetween = false;

		const tl = gsap.timeline({ paused: true, onReverseComplete: () => hoverBetween = false });
		tl.fromTo(fill, { scale: 0.8, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.2 });

		function flipInto(item) {
			const state = Flip.getState(background);
			item.querySelector(".hover-2_visual")?.prepend(background);
			if (hoverBetween) Flip.from(state, { duration: 0.3, ease: "power1.inOut" });
		}
		items.forEach(function (item) {
			item.addEventListener("mouseenter", function () {
				flipInto(item);
				hoverBetween = true;
			});
		});
		component.addEventListener("mouseenter", () => tl.play());
		component.addEventListener("mouseleave", () => tl.reverse());
	});
});
</script>