Can anyone tell me how to create "wiggle" effect?

I have seen some sites that have a call to action with some sort of image, like an arrow,etc., and after your on the page for a few seconds it will wiggle or point in the direction they want you to look in. I thought it could be done with CSS3, but it doesn’t seem to have that timing feature and isn’t widely supported. Is there a Jquery plugin for something like this?

Due to the wide possibilities with such techniques, can you link us to a couple of examples of what you mean?

Unfortunately I didn’t bookmark them and I can’t remember. I found this yesterday which is close, but you have to hover to make the element move. I was hoping to do it where like 15-20 seconds after page loads it would activate on its own and continue every few seconds. http://droot.github.com/wiggle/#

This is the CSS that the page uses to perform the wiggle. I’ve just changed the :hover pseudo-selector to a .hover one instead, so that we can use scripting to add and remove that hover class to the button.


@-webkit-keyframes wiggle {
    0% {-webkit-transform:rotate(2deg);}
    50% {-webkit-transform:rotate(-2deg);}
    100% {-webkit-transform:rotate(2deg);}
}

@-moz-keyframes wiggle {
    0% {-moz-transform:rotate(2deg);}
    50% {-moz-transform:rotate(-2deg);}
    100% {-moz-transform:rotate(2deg);}
}

@keyframes wiggle {
    0% {transform:rotate(2deg);}
    50% {transform:rotate(-2deg);}
    100% {transform:rotate(2deg);}
}

.alert.hover .btn-danger {
    -webkit-animation: wiggle 0.2s;
    -moz-animation: wiggle 0.2s;
}
​

To add and remove the class name, we can use a scripting library if you already have one, or we can use these functions to manage the task for us.


function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\\\s|^)' + cls + '(\\\\s|$)'));
}

function addClass(ele, cls) {
    if (!hasClass(ele, cls)) {
        ele.className += ' ' + cls;
    }
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\\\s|^)' + cls + '(\\\\s|$)'),
            newClass = ele.className.replace(reg, ' ');
        ele.className = newClass.replace(/^\\s+|\\s+$/g, '');
    }
}

All that’s needed now is to add the hover class, and to then remove that class name after the CSS animation has finished performing its wiggle.
So we create a triggerHover function, which whenever it’s run will add the hover class name, and then shortly afterwards remove it.


function createTriggerHover(el, duration) {
    return function () {
        addClass(el, 'hover');
        window.setInterval(function () {
            removeClass(el, 'hover');
        }, duration);
    };
}
var alert = document.querySelector('.alert'),
    triggerHover = createTriggerHover(alert, 1000);

window.setInterval(triggerHover, 3000);

I’ve made the delay between each wiggle for 3 seconds, so that you can see its effect without having to wait as long between each one.

You can see it in action at http://jsfiddle.net/pmw57/XVEsf/2/

Off Topic:

That’s amazing, paul. Although, for me in Chrome, it wiggles once and then only blinks every three seconds from that point on. Just following along here with interest. :slight_smile:

Wow, thank you for the detailed explanation! I definitely understand the theory of how you accomplished it, but some of the js code is a bit over my head still. It definitely does exactly what I wanted. But, I noticed that the one time I loaded the page, it moved twice, I loaded the page again and it went 4 times, another 3 times. Is that because of the jsfiddle platform? Or is there a way to set number of times the script should be executed?

*Forgot to mention I was viewing in firefox:)

The script triggers on a cycle that loops forever, repeating every 3 seconds.

You may want to talk to someone in the CSS forum about issues relating to the CSS effect.

An animated gif would always work but the JS solution is pretty trivial. Just substitute your own image:

<!DOCTYPE HTML>
<html>
<head>
<title>Poxy Element Vibrator</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type='text/css'>
body{background-color:#00f}
#g_arrow{ position:fixed; bottom:20px;right:20px; margin:0 10px 0 10px }
</style>
</head>
<body>
<img src='greenrightarrow.gif' d='g_arrow' >

<script type='text/javascript'>

function cycleMargin( imgId, defMargin, offsetMargin )
{
  var elem = document.getElementById( imgId ),
      displaced = false;
  
  function nudge()
  {
    elem.style.margin = ( displaced ^= true ) ? defMargin : offsetMargin; 
    
    setTimeout( nudge, displaced ? 100 + Math.random() * 500 : 50 );
  }
  
  nudge();
}

cycleMargin( 'g_arrow', '0 10px 0 0', '0 0 0 10px' );

</script>
</body>
</html>

I came across an example finally! http://css3ps.com/ They achieved it with just css3, though its more a shake effect than wiggle. Any decent browser would support it I guess.

I like Ali’s mention of the animated gif. Some browsers offer the option to turn those off, but people who want no animation on gifs should be able to. It’s small, simple, runs whether the browser is old or new, whether JS is available or not. Especially if you are not changing the frequency of the wiggle (I would indeed use JS if that needs to change as the user does stuff).

If you want an example of insane wiggle, http://www.staggeringbeauty.com/ will be sure to give you epilepsy or a war flashback if you are currently sane and healthy.