Francesca
Francesca

Reputation: 28188

Bordered box effect on hover

I have an aesthetic piece of functionality I am trying to create.

The "look" is a box, which has lots of moving about borders when the box is hovered over. This is the design graphic:

http://i.imgur.com/pF779SC.png

The solution I have is that .on('mousemove') a new div with a border is created. The new div, .created-x, has a top and left position randomly positions between -10 and 10. The box fades in and after 500 milliseconds it is faded out and subsequently destroyed.

It's OK/getting there.

Here is a JSFiddle: https://jsfiddle.net/adgndLqe/13/

But I am having the following issues:

1. When the cursor is static over the box, mousemove doesn't trigger. I need it to keep triggering whenever the cursor is over the box, regardless of movement.

I'm triggering the effects as such:

$(".box .inner").on("mousemove", function () {

How can I make this trigger whenever the hover is over the div?

2. Too many boxes

Because it generates on every mousemove, it created a bordered box for every pixel moved. Obviously it's overkill. In the graphic above you can see there are only about 6 boxes maximum. Mine is a lot heavier.

How can I reduce the number of boxes created so it does not trigger on every pixel moved but say, every 3 or 5 pixels moved to reduce the number of boxes?

Upvotes: 1

Views: 104

Answers (4)

falsarella
falsarella

Reputation: 12447

My solution ended up being very similar to tonoslfx's / ioum's. But I tried to make less changes and more explanations.

The problem was that the effect should be executed independently of mousemove, while hovering a box. So, instead of placing the effect code on mousemove, I've placed it on a setInterval inside the mouseenter. Make sure that the code inside the setInterval can't directly access the mouseenter's this due to scope change, so an auxiliar variable is needed to work (thanks to closure).

Additionally, when the user leaves the box, the effect should be stopped. So, on mouseleave, we should clearInterval. But, sometimes, the events don't occur properly: it may happen to have two mouseenter in a box without a mouseleave, leading to an infinite running effect. To resolve that, we should also clearInterval before we call the next setInterval, so we guarantee that the old one won't run for ever.

Finally, to have specify how many borders the effect has, you could have a configured value - let's say, 6 - stored on a variable - let's call it maxBorderCount. Then, you can work with the interval set on setInterval. If you create a border on every 100 milliseconds, and fade them down after 500 milliseconds, you'll have a maximum of 5 solid borders being shown. In other words, if you create a border on every 100 milliseconds, and fade them down after 100 * maxBorderCount, you'll have a maximum of maxBorderCount solid borders bein shown.

Please, see the working fiddle:

$(document).ready(function () {
    var counter = 0;
    var maxBorderCount = 6;
    var borderInterval = undefined;
    $(".box .inner").on("mouseenter", function () {
        clearInterval(borderInterval);
        var superThis = this;
        borderInterval = setInterval(function() {
            // Generate top and left position;
            var randomTop = Math.floor(Math.random() * 21) - 10;
            randomTop = randomTop + 'px';

            var randomLeft = Math.floor(Math.random() * 21) - 10;
            randomLeft = randomLeft + 'px';

            // Create unique id
            counter++;
            var current = "created-" + counter;

            // Create the div (max of ten)
            $(superThis).append("<div id='" + current + "' style='display:none;border:1px solid #fff;width:100%;min-height:170px;position:absolute;top:" + randomTop + ";left:" + randomLeft + ";'></div>");
            $('#' + current).fadeIn('fast');

            // Destroy the div after a set time
            setTimeout(function () {
                // destroy
                $('#' + current).fadeOut('fast');
                $('#' + current).remove();
            }, 100 * maxBorderCount);
        }, 100);
    }).on("mouseleave", function() {
        clearInterval(borderInterval);
    });
});

Upvotes: 2

tonoslfx
tonoslfx

Reputation: 3442

$(function () {
    var counter = 0;
    var myinterval = 0;
    var current;

    function _boxes($this) {

        var randomTop = Math.floor(Math.random() * 21) - 10;
        randomTop = randomTop + 'px';

        var randomLeft = Math.floor(Math.random() * 21) - 10;
        randomLeft = randomLeft + 'px';

        // Create unique id
        counter++;
        var current = "created-" + counter;

        // Create the div (max of ten)
        $this.append("<div id='" + current + "' style='display:none;border:1px solid #fff;width:100%;min-height:170px;position:absolute;top:" + randomTop + ";left:" + randomLeft + ";'></div>");
        $('#' + current).fadeIn('fast');

        // Destroy the div after a set time
        setTimeout(function () {
            // destroy
            $('#' + current).fadeOut('fast');
            $('#' + current).remove();

        }, 500);

    }

    $(".box .inner").on("mouseenter", function () {

        var $this = $(this);

        clearInterval(myinterval);

        myinterval = setInterval(function () {
            _boxes($this)
        }, 100);

    }).on('mouseleave', function () {
        clearInterval(myinterval);
    });

});

Upvotes: 2

ioums
ioums

Reputation: 1395

I would change your approach to use mouseenter and mouseleave. Then, while the cursor is over a box set an interval that adds borders. Clear the interval when the cursor leaves. This takes care of both creating the border even without cursor movement, and, depending on how you set the interval for border creation, controls how many border boxes are shown.

Example

Upvotes: 2

Ali Alwash
Ali Alwash

Reputation: 533

You have to use mouseenter. Check this example: https://api.jquery.com/mouseenter/

Upvotes: -1

Related Questions