Welcome to Day 1 of Daily Code!

Fun with jQuery mouse events

We will keep is simple today with a random project on jQuery mouse events.

This is actually an Easter Egg that I had in place on my company website for a bit, until another developer saw the code and didn’t think it was funny.

First off, lets look at some markup:

<img src="images/dragon.gif" id="dragon" draggable="false"/> <img src="images/fire.gif" class="fire" style="display:none"/>

The draggable <img/> element needs an id so we can select it. The draggable=”false” parameter is used to disable the standard browser functionality of dragging images.

The fire <img/> element is really only there so we can preload the gif. Set to display: none so we cant see it initially.

Next, we make it look good:

#dragon { position:absolute; z-index:9999 } .fire { position:absolute; z-index:9990 }

Both #dragon and .fire need position: absolute; in order to be placed in the correct spot on the DOM.

#dragon needs a higher z-index than .fire for correct layering.

I tend to use z-index: 9999; to make sure it is the top most element.

Now, for all the magic to happen:

var gl, w = $(window), fireShooter, mouseStillDown = false; w.mousemove(function(e){ gl = e; $('#dragon').css({ 'top': gl.clientY - 90 + w.scrollTop(), 'left': gl.clientX - 50 }); }); function fireShooterFun(){ if( !mouseStillDown ) { return; } if(mouseStillDown) { var ele = $('<img/>', { src: "images/fire.gif", class: "fire" }); $('body').append(ele); ele.css({ 'top': gl.clientY - 40 + w.scrollTop(), 'left': gl.clientX - 40 }).animate({ 'top': "-=20px" }, 700); setTimeout(function(){ ele.fadeOut('slow',function(){ $(this).remove(); }); },700); } } $('#dragon, img, body').mousedown(function(e){ mouseStillDown = true; fireShooter = setInterval( function(){fireShooterFun()}, 10); }).mouseup(function(e){ mouseStillDown = false; });

First, we need to set some global variables.



gl is for global event tracking.



w is the window element.



fireShooter is our interval variable for repeative firing.



mouseStillDown is boolean (true/false) to know if we should still be firing.

Next, we define a function for our mouse movement on the window element (w).



gl = e; updates the global event variable.



#dragon‘s CSS positioning is updated with the global client x & y offsets. ‘top’ : gl.clientY – 90 + w.scrollTop() sets the top value of #dragon to the y position of the mouse minus 90px (due to where the dragon’s head is in the gif) then we add the window scroll top offset so we can scroll the page without the dragon moving. ‘left’ : gl.clientX – 50 sets the left value of #dragon to the x position of the mouse minus 50px (due to where the dragon’s head is in the gif).

Then, we define the function to make the magic happen.



if( !mouseStillDown ) { return; } checks to see if the mouse is not being pressed. return stops the function execution.

If the mouse is still being pressed, define the image element being added (ele).



Define the image source and class with src: “images/fire.gif”, class: “fire”.



Append the new image element to the body with $(‘body’).append(ele);



The image needs to know where to be placed, apply css in the same manner we did with #dragon. However, mind the offsets based on image size.



Each appended image gets animated with animate({‘top’: “-=20px”}, 700); which moves the fire image up 20 pixels over 700 ms.

The fire needs to go away at a certain point, so we use setTimeout to slowly fadeOut the image then .remove() it.

Finally, we need to bind the mouse events appropriately.



Binding to #dragon, img, body makes sure that we fire out function regardless of what is clicked. mousedown sets mouseStillDown to true and using setInterval to call fireShooterFun every 10 ms. mouseup sets mouseStillDown to false and stops firing function.