JSFiddle - React, Tailwind, and code Playground
by abude
HTML
<h2 style="margin-left:15px;">Lava Lamp Style Menu using GSAP - Hover Event</h2>
<p style="margin-left:16px;">hover over a menu item to see the animated underline:</p>
<div id="box">
<ul id="menu">
<li><a href="javascript:;" class="active">menu</a></li>
<li><a href="javascript:;">long menu</a></li>
<li><a href="javascript:;">even longer menu</a></li>
<li><a href="javascript:;">short menu</a></li>
</ul>
</div>
CSS
body {
background:#FFF;
color:#555;
margin:20px 0 0 10px;
}
#box,
#box2{
position:relative;
height:40px;
margin:0 0 0 0;
}
ul{
margin:0;
padding:0;
display:block;
}
li {
float:left;
margin:0;
list-style-type:none;
padding:0;
padding:5px 20px;
}
li a {
display:block;
text-decoration:none;
font-weight:bold;
font-family:Arial;
color:#222;
}
li a.active {
color:#CC0000;
}
#menu li.slide-line,
#menu2 li.slide-line {
display: block;
padding:0;
margin:0;
background: none #CC0000;
position: absolute;
top: 0;
width: 43px;
height: 6px;
left: 20px;
top: 30px;
z-index: 0;
}
JavaScript
// adds sliding underline HTML
jQuery('#menu').append('<li class="slide-line"></li>');
// animate slide-line on click
jQuery(document).on('mouseenter', '#menu li a', function () {
var $this = jQuery(this),
// get offset of hovered this
offset = $this.offset(),
//find the offset of the wrapping div
offsetBody = jQuery('#box').offset();
// GSAP animate to clicked menu item
TweenMax.to(jQuery('#menu .slide-line'), 0.5, {
css:{
width: $this.outerWidth()+'px',
left: (offset.left-offsetBody.left)+'px'
},
overwrite:"all",
// easing for overshoot
ease:Back.easeOut
});
}).on('mouseleave', '#menu li', function () {
var $this = jQuery(this),
// get the active menu selector
$active = $this.parent().find("a.active"),
// get offset of active menu item
offset = $active.offset(),
//find the offset of the wrapping div
offsetBody = jQuery('#box').offset();
// GSAP animate to clicked menu item
TweenMax.to(jQuery('#menu .slide-line'), 0.5, {
css:{
width: $active.outerWidth()+'px',
left: (offset.left-offsetBody.left)+'px'
},
overwrite:"all",
ease:Power4.easeInOut
});
});