From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
Today we will create a neat effect with some images using jQuery. The main idea is to have an image area with several images that slide out when we hover over them, revealing other images. The sliding effect will be random, i.e. the images will slide to the top or bottom, left or right, fading out or not. When we click on any area, all areas will slide their images out.
The idea is based on the beautiful Flash based animation on the Yumaki website.
So, let’s start.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The Markup
For the HTML structure we will create a div element with the class and id “hs_container”. Inside we will place the different image areas with all possible images. The first image will have the class “hs_visible” which will make it being displayed on the top of all other images:
<div id="hs_container" class="hs_container"> <div class="hs_area hs_area1"> <img class="hs_visible" src="images/area1/1.jpg" alt=""/> <img src="images/area1/2.jpg" alt=""/> <img src="images/area1/3.jpg" alt=""/> </div> <div class="hs_area hs_area2"> <img class="hs_visible" src="images/area2/1.jpg" alt=""/> <img src="images/area2/2.jpg" alt=""/> <img src="images/area2/3.jpg" alt=""/> </div> <div class="hs_area hs_area3"> <img class="hs_visible" src="images/area3/1.jpg" alt=""/> <img src="images/area3/2.jpg" alt=""/> <img src="images/area3/3.jpg" alt=""/> </div> <div class="hs_area hs_area4"> <img sclass="hs_visible" src="images/area4/1.jpg" alt=""/> <img src="images/area4/2.jpg" alt=""/> <img src="images/area4/3.jpg" alt=""/> </div> <div class="hs_area hs_area5"> <img class="hs_visible" src="images/area5/1.jpg" alt=""/> <img src="images/area5/2.jpg" alt=""/> <img src="images/area5/3.jpg" alt=""/> </div> </div>
Let’s take a look at the style.
The CSS
In our stylesheet, we will define all the areas and their dimensions. Since we will make them absolute, we will also define the positions for each area. Let’s start by defining the main container:
.hs_container{ position:relative; width:902px; height:471px; overflow:hidden; clear:both; border:2px solid #fff; cursor:pointer; -moz-box-shadow:1px 1px 3px #222; -webkit-box-shadow:1px 1px 3px #222; box-shadow:1px 1px 3px #222; }
It’s important that we define the overflow as hidden, since we don’t want the sliding images to be shown when they are out of this container.
Each area will also have its overflow hidden and be of position absolute:
.hs_container .hs_area{ position:absolute; overflow:hidden; }
We position the images inside of the area and make them invisible:
.hs_area img{ position:absolute; top:0px; left:0px; display:none; }
The first image will be visible, so we give it the following class:
.hs_area img.hs_visible{ display:block; z-index:9999; }
And now, we will define the borders and positions of each area:
.hs_area1{ border-right:2px solid #fff; } .hs_area4, .hs_area5{ border-top:2px solid #fff; } .hs_area4{ border-right:2px solid #fff; } .hs_area3{ border-top:2px solid #fff; } .hs_area1{ width:449px; height:334px; top:0px; left:0px; } .hs_area2{ width:451px; height:165px; top:0px; left:451px; } .hs_area3{ width:451px; height:167px; top:165px; left:451px; } .hs_area4{ width:192px; height:135px; top:334px; left:0px; } .hs_area5{ width:708px; height:135px; top:334px; left:194px; }
And that’s all the style! Let’s take a look at the JavaScript.
The JavaScript
For the effects, we will be giving the option to use some easing, so don’t forget to include the jQuery Easing Plugin if you make use of that option.
So, let’s first define some variables:
//custom animations to use //in the transitions var animations = ['right','left','top','bottom','rightFade','leftFade','topFade','bottomFade']; var total_anim = animations.length; //just change this one to one of your choice var easeType = 'swing'; //the speed of each transition var animSpeed = 450; //caching var $hs_container = $('#hs_container'); var $hs_areas = $hs_container.find('.hs_area');
When we move the mouse over one of the areas we will animate the current image with an animation from our array, so that the next image gets visible. We will use a flag “over” to know if we can animate a certain area since we don’t want two animations to happen at the same time in one area.
We will have a case for each animation and we will define how the animation will behave.
//first preload all images $hs_images = $hs_container.find('img'); var total_images = $hs_images.length; var cnt = 0; $hs_images.each(function(){ var $this = $(this); $('').load(function(){ ++cnt; if(cnt == total_images){ $hs_areas.each(function(){ var $area = $(this); //when the mouse enters the area we animate the current //image (random animation from array animations), //so that the next one gets visible. //"over" is a flag indicating if we can animate //an area or not (we don't want 2 animations //at the same time for each area) $area.data('over',true).bind('mouseenter',function(){ if($area.data('over')){ $area.data('over',false); //how many images in this area? var total = $area.children().length; //visible image var $current = $area.find('img:visible'); //index of visible image var idx_current = $current.index(); //the next image that's going to be displayed. //either the next one, or the first one if the current is the last var $next = (idx_current == total-1) ? $area.children(':first') : $current.next(); //show next one (not yet visible) $next.show(); //get a random animation var anim = animations[Math.floor(Math.random()*total_anim)]; switch(anim){ //current slides out from the right case 'right': $current.animate({ 'left':$current.width()+'px' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'left' : '0px' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the left case 'left': $current.animate({ 'left':-$current.width()+'px' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'left' : '0px' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the top case 'top': $current.animate({ 'top':-$current.height()+'px' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'top' : '0px' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the bottom case 'bottom': $current.animate({ 'top':$current.height()+'px' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'top' : '0px' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the right and fades out case 'rightFade': $current.animate({ 'left':$current.width()+'px', 'opacity':'0' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'left' : '0px', 'opacity' : '1' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the left and fades out case 'leftFade': $current.animate({ 'left':-$current.width()+'px','opacity':'0' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'left' : '0px', 'opacity' : '1' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the top and fades out case 'topFade': $current.animate({ 'top':-$current.height()+'px', 'opacity':'0' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'top' : '0px', 'opacity' : '1' }); $next.css('z-index','9999'); $area.data('over',true); }); break; //current slides out from the bottom and fades out case 'bottomFade': $current.animate({ 'top':$current.height()+'px', 'opacity':'0' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'top' : '0px', 'opacity' : '1' }); $next.css('z-index','9999'); $area.data('over',true); }); break; default: $current.animate({ 'left':-$current.width()+'px' }, animSpeed, easeType, function(){ $current.hide().css({ 'z-index' : '1', 'left' : '0px' }); $next.css('z-index','9999'); $area.data('over',true); }); break; } } }); }); //when clicking the hs_container all areas get slided //(just for fun...you would probably want to enter the site //or something similar) $hs_container.bind('click',function(){ $hs_areas.trigger('mouseenter'); }); } }).attr('src',$this.attr('src')); });
And that’s it! We hope you enjoyed the tutorial and find it useful!
The Nobel Prize in jQuery goes to you! 🙂
Awesome effect!
Great effects! I like the concept!
Wow!
as usual, always out of cool of creations…
course with the photo model’s unsightly Hohoho ….;)
Hi Mary Lou,
this time .. it’s really .. (missing words)
Thanks for your creativity and code
Awesome work!
It is possible to make the images to change automatically?
OMG this is so incredibly awesome!
Great concept but is not usable.
Wow, great!
I think it would be more usable if the images could change automatically. Is there a way to get it?
Wow
is the best
thanks
How do you do it.
Nice!
It’s amazing
usable or not depends yours! Btw, how could I implement a click to go to a link in one or all areas? any hints will be appreciated.
to open a new window by clicking anywhere on the container, replace line 194:
$hs_areas.trigger(‘mouseenter’);
with
open(“targeturl”);
where targeturl is the url for the page you want opened
Line 18 in the markup should be
instead of
This is sick! .. I think I might try this one out in a Magento site.
Awesome script !
Thanks for sharing it !
Please, can you tell me how doing to get all images with an opacity and when the mouse is over it’s “normal” ?
Do you see what i mean ?
Thanks.
This is a really awesome effect. Thanks for making the tutorial and plugin!
I am changing the plugin a small amount o fit in the space I want it in but it seems that the area4 space is not working at all. I have tried to troubleshoot it but have been unable to make it work.
URL: http://joshualee.cordslatton.com
then click on the photos link in the top navigation.
DrCord, you have a typo in the img tag: sclass=”hs_visible” should be class=”hs_visible”
🙂 Hope it helps,
ML
@Mary Lou – Thanks! You rock!
Excellent demo. Will implement this in my new project related to jewelry
Hey..i’m trying to implement it into Joomla here
URL: http://demo.joomlamini.com/3rded/
Thx Mary & Stubbybus
Thank you! This will be great for some of my upcoming projects.
I do have one question if instead of clicking on it making all of the images slide would it be possible to make it so that each set of images are a different link that opens in the same window?
Really cool stuff. I have implemented few stuffs given in previous posts long time before. Eagerly waiting for an opportunity to implement this script in my future work.
i have taken this script i am going to implement on my site
As I can do to make the links open in the same page?
example code
i need help ! thanks
demo: http://www.portalfoxmix.net
great script, but if i put a link on the img i cannot see any img;
great tutorial!
how can i change the images automatically? a instruction would be really great!
That is a great tutorial.
Juste one question, what is the Cantarelle.font.js file?
Will that font work on any computer?
Thanx.
That’s the Cufon font and you can read more about Cufon here: https://github.com/sorccu/cufon/wiki/About
Hope it helps,
ML
Thank you very much Mary Lou!
That concept is not that easy, but I will work on it.
Best from Patrick.
Awesome, as always. But the nagging question that I share with others–can some sort of autoplay be triggered?
very cool effect,I am going to use this effect on my website?thanks so much
????
Pretty cool. But the I also miss the auto mode.
Beautiful work! Great thanks!!!
But please help! How to make that when you click on the upper right group of images – one page of the site will open? And when you click on the bottom left would open another page? So if we have 5 groups of pictures – user will can open 5 different pages.
@Kenjar, I’m with you, I’ve been trying to work this out for hours. Replacing -$hs_areas.trigger(‘mouseenter’);
with
open(“targeturl”);
Might work on the entire image, but how does one do it for individual Area’s?
Overall, this is awesome!
I have a solution.
We need nothing to override. Only to put two blo?ks of code:
First after the line with code
var $hs_areas = $hs_container.find(‘.hs_area’);
We put:
var $hs_areas_1 = $hs_container.find(‘.hs_area1’);
var $hs_areas_2 = $hs_container.find(‘.hs_area2’);
var $hs_areas_3 = $hs_container.find(‘.hs_area3’);
var $hs_areas_4 = $hs_container.find(‘.hs_area4’);
var $hs_areas_5 = $hs_container.find(‘.hs_area5’);
And the second after
$hs_container.bind(‘click’,function(){
$hs_areas.trigger(‘mouseenter’);
});
We put:
$hs_areas_1.bind(‘click’,function(){
open(“targeturl_1”);
});
$hs_areas_2.bind(‘click’,function(){
open(“targeturl_2”);
});
$hs_areas_3.bind(‘click’,function(){
open(“targeturl_3”);
});
$hs_areas_4.bind(‘click’,function(){
open(“targeturl_4”);
});
$hs_areas_5.bind(‘click’,function(){
open(“targeturl_5”);
});
I think it looks awful. And I hope somebody can write beautifully. But it works 🙂
Many thanks to MARY LOU! Beautiful and a very clean & nice JavaScript code! 🙂
SNR ROY – In my previous example – we do not replace anything, only add.
Thanks for your script.. you are doing great service.
very cool.
you’re great.
Is auto mode, ready?
Thank you for sharing.
Does your plugin run with jquery-mobile ?
If I use your framework directly, the result is fine with iphone.
If I use your framework, not directly, but embeded with jquery-mobile, the result is not as expected [images does not fit screen !]
(div data-role=”page” data-theme=”d” id=”” div data-role=”content” div id=”hs_container” class=”hs_container”)
Please have a look at http://fiddle.jshell.net/aEkTX/4/show/
We may resized the screen.
Suggestion: max-width, width=100% ?
Any suggestion ?
Great work !
Can you help on how to start this automatically and make it repeat with a given interval?
This is great but unfortunately won’t work in IE9 🙁
Any suggestion?!
Anyone have idea to put this artwork in blogspot !?Give me tutorial please.
beautyful work !
How to get this effect at random in a cycle without hovering when document is ready
I wanna the same from Marcel, a auto animation, please help us
Is there a wordpress plugin for this effect yet?
This is brilliant! Wondering if it’s possible to have the individual images click out to urls?… I tried adding a basic anchor to each image but it broke the transition. Any help/insight would be greatly appreciated!