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();