JSFiddle - React, Tailwind, and code Playground
by BurpmanJunior
HTML
<div class="directional-hover">
<div></div>
<img src="http://lorempixel.com/500/300/city/" />
</div>
SCSS
.directional-hover{
display: inline-block;
position: relative;
overflow: hidden;
font-size: 0;
& > div{
content: '';
display: block;
position: absolute;
background-color: #6c308e;
z-index: 2;
top: -100%;
right: 0;
bottom: 100%;
left: 0;
}
// IN
&.dh-in-top > div{
top: -100%;
right: 0;
bottom: 100%;
left: 0;
}
&.dh-in-right > div{
top: 0;
right: -100%;
bottom: 0;
left: 100%;
}
&.dh-in-bottom > div{
top: 100%;
right: 0;
bottom: -100%;
left: 0;
}
&.dh-in-left > div{
top: 0;
right: 100%;
bottom: 0;
left: -100%;
}
// OVER
&.dh-over > div{
transition: top 500ms, right 500ms, bottom 500ms, left 500ms;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
// OUT
&.dh-out-top > div{
transition: top 500ms, right 500ms, bottom 500ms, left 500ms;
top: -100%;
right: 0;
bottom: 100%;
left: 0;
}
&.dh-out-right > div{
transition: top 500ms, right 500ms, bottom 500ms, left 500ms;
top: 0;
right: -100%;
bottom: 0;
left: 100%;
}
&.dh-out-bottom > div{
transition: top 500ms, right 500ms, bottom 500ms, left 500ms;
top: 100%;
right: 0;
bottom: -100%;
left: 0;
}
&.dh-out-left > div{
transition: top 500ms, right 500ms, bottom 500ms, left 500ms;
top: 0;
right: 100%;
bottom: 0;
left: -100%;
}
}
JavaScript
/**
* DIRECTIONAL HOVER
*/
var dh = {
init: function () {
$('.directional-hover').each(function () {
$(this).mouseenter(function (e) {
dh.inEval($(this), e);
});
$(this).mouseleave(function (e) {
dh.outEval($(this), e);
});
});
},
inEval: function (elem, e) {
var o = dh.nearestOffset(e);
console.log(o);
elem[0].className = elem[0].className.replace(/\s?dh\-out\-\S*/g, '');
setTimeout(function () {
elem.addClass('dh-in-' + o)
setTimeout(function () {
elem.addClass('dh-over');
}, 10);
}, 10);
},
outEval: function (elem, e) {
var o = dh.nearestOffset(e);
console.log(o);
elem[0].className = elem[0].className.replace(/\s?dh\-in\-\S*/g, '');
elem.addClass('dh-out-' + o).removeClass('dh-over');
},
nearestOffset: function (e) {
var d = {
top: e.offsetY,
right: e.currentTarget.clientWidth - e.offsetX,
bottom: e.currentTarget.clientHeight - e.offsetY,
left: e.offsetX
};
console.log(d);
if (d.top < d.left && d.top < d.right && d.top < d.bottom) {
return 'top';
}
if (d.bottom < d.left && d.bottom < d.right && d.bottom < d.top) {
return 'bottom';
}
if (d.left < d.top && d.left < d.right && d.left < d.bottom) {
return 'left';
}
if (d.right < d.left && d.right < d.bottom && d.right < d.top) {
return 'right';
}
}
}
dh.init();