Animate Curtains Opening with jQuery


Animate Curtains Opening with jQuery

Step 1 – What You’ll Need

This tutorial would not be anything special without the graphics, so let’s make sure you’ve got those under control. I’ve included the ones used in demo as part of the attached files, now would be a good time to download them if you intend to use them.

Secondly, in addition to the standard jQuery file, we are also using the easing plugin. We have worked with this plugin in previous tutorials but in this case we will use it to provide a bounce effect when the rope is pulled.

IE6 Disclaimer – A few of the project images use the PNG format in order to have cleaner transparency. To keep things short, I will not be demonstrating the workaround for transparency errors in IE6. If this affects you, I recommend reading this article for a solution.

Step 2 – Setting Up the HTML

<head>
 <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"></script>
 <script src="jquery.easing.1.3.js" type="text/javascript"></script>
</head>
<body>
 <div class="leftcurtain"><img src="images/frontcurtain.jpg"/></div>
 <div class="rightcurtain"><img src="images/frontcurtain.jpg"/></div>
 <img class="logo" src="images/buildinter.png"/>
 <a class="rope" href="#"><img src="images/rope.png"/></a>
</body>

Step 3 – Add the CSS

*{
 margin:0;
 padding:0;
 }
 body {
 text-align: center;
 background: #4f3722 url('images/darkcurtain.jpg') repeat-x;
 }
 img{
 border: none;
 }
 .leftcurtain{
 width: 50%;
 height: 495px;
 top: 0px;
 left: 0px;
 position: absolute;
 z-index: 2;
 }
 .rightcurtain{
 width: 51%;
 height: 495px;
 right: 0px;
 top: 0px;
 position: absolute;
 z-index: 3;
 }
 .rightcurtain img, .leftcurtain img{
 width: 100%;
 height: 100%;
 }
 .logo{
 margin: 0px auto;
 margin-top: 150px;
 }
 .rope{
 position: absolute;
 top: -40px;
 left: 70%;
 z-index: 4;
 }

Let’s pause for a minute and catch up with what we’ve just done.

We made two div classes for the two curtains (.leftcurtain and .rightcurtain) which are locked to their designated sides. This was done in the CSS by using the top,left, and position attributes.

You’ll notice that we specified the width for each curtain, 50% and 51%. The varying widths is to compensate for some choppy edges when the curtains are closed that could cause the elements underneath to peak through. To combat this we made the right curtain slightly overlap the left one, by using the z-indexes. These z-index values also ensure that the curtains stay on top of everything that is supposed to be behind the curtains.

The actual curtain images are set to be 100% width/height of the curtain divs so that when the these divs shrink in width the images become bunched up, just as they would in real life.

The .logo contains what I wish to hide behind the curtain, you can replace it with whatever you wish.

Finally the .rope simply places the rope graphic on top of everything else and hides part of the image off screen so we can accomplish the “pulling the rope” effect later.

Step 4 – Open the Curtains with jQuery

<script type="text/javascript">
 $(document).ready(function() {

 $curtainopen = false;

 $(".rope").click(function(){

 $(this).blur();

 if ($curtainopen == false){ 

 $(this).stop().animate({top: '0px' }, {queue:false, duration:350, easing:'easeOutBounce'});
 $(".leftcurtain").stop().animate({width:'60px'}, 2000 );
 $(".rightcurtain").stop().animate({width:'60px'},2000 );
 $curtainopen = true;

 }else{

 $(this).stop().animate({top: '-40px' }, {queue:false, duration:350, easing:'easeOutBounce'});
 $(".leftcurtain").stop().animate({width:'50%'}, 2000 );
 $(".rightcurtain").stop().animate({width:'51%'}, 2000 );
 $curtainopen = false;

 }

 return false;

 });

 });
 </script>

When the document is all ready to roll, we establish that the curtains are closed, by setting $curtainopen = false. We use the value of this variable to determine whether to run the animations for opening or closing the curtains via an ‘if’ statement.

The other event that we have mapped out is when .rope is clicked, which causes the above mentioned conditional statement to run. Additionally we blur() the links and return false; to make sure the link does not direct the user elsewhere. For those curious, we have written an article about blurring links, so get versed in it.

If the curtain is currently closed, the .rope is pulled down, repositioned to top:0px from top:-40px, with a bounce effect brought about by the easing plugin we grabbed before. While this magic is happening each curtain is simultaneously adjusted to a width of 60px, which creates the opening effect. You can set the amount of time they take to open by changing the duration, which is currently set to 2000 (or 2 seconds).

Now that the curtains are open, when the rope is pulled again, the conditional statement will run the closing animation which sets everything back to default values.

Step 5 – Cue Excitement, You’re Done

You’ve now got yourself a functioning stage, hopefully you can find something showstopping to put on it. I opted to make the stage stretch the entire screen but you can certainly adjust the width by placing it in a specified width container. This is where the artistic license kicks in. This might also benefit from a preloader to prevent the user from seeing what’s behind the curtain during longer loads.

As always, your comments, thoughts, dreams, and aspirations are appreciated in the comments below.

  • Stumble It!
  • Bookmark It!
  • Tweet it!

About Sam Dunn

Sam is a designer and co-founder of One Mighty Roar from Massachusetts, USA. He takes particular interest in all things aesthetically pleasing. He can be found online at Vivalasam and Twitter.

 

Discussion

  1. Brian Muse

    July 8th, 2009 at 5:56 PM

    Pretty neat. You have two step 3s though!

  2. Sam Dunn

    July 8th, 2009 at 6:01 PM

    @Brian Muse
    So I did…thank you for your superior counting skills

  3. 2tone

    July 8th, 2009 at 6:11 PM

    I really like your tutorials, specially jquery´s, please don´t stop sharing!;)
    .-= 2tone´s last blog ..swedish-organic-water =-.

  4. Nicholas Z. Cardot

    July 8th, 2009 at 8:32 PM

    Wow! That looks really cool. I don’t need a curtain for any of my current projects but it looks great.
    .-= Nicholas Z. Cardot´s last blog ..Only 2 Days Remaining: Subscribe Now & Win =-.

  5. Chob

    July 9th, 2009 at 6:13 AM

    Thanks for this great tutorial. I tried the live demo and if you just pull with the mouse, nothing happens. You need to click and not just pull. Did I miss something ?
    .-= Chob´s last blog ..Mon entreprise dialogue avec les blogueurs « influents» … partie 2 =-.

  6. Jørgen

    July 9th, 2009 at 8:16 AM

    Great effect :)
    .-= Jørgen´s last blog ..30 Best Photoshop Tutorials of June 2009 =-.

  7. Mac Agenda

    July 9th, 2009 at 8:57 AM

    Very nice! Especially the easing in and easing out. Nice images, love this!

  8. Ezrad Lionel

    July 9th, 2009 at 10:11 AM

    I hope you don’t mind if I port this to VVED? It runs kinda slow even in Chrome or that might be the easing plugin? Great Job.

  9. Sam Dunn

    July 9th, 2009 at 11:06 AM

    @Chob
    I suppose I could have labeled the rope a little bit more clearly, it’s a click activated event only, although it could be modified to respond to a pull as well.

    @Ezrad Lionel
    What exactly appears to be running slow? I have checked it out in all browsers and the only thing I’ve seen is minor image distortions in the curtains mid-resize in Firefox. I would be curious to see your VVED port/if it runs any smoother.

  10. Travis

    July 9th, 2009 at 11:42 AM

    FYI, the demo doesn’t work in FF 3.5

  11. Sam Dunn

    July 9th, 2009 at 12:11 PM

    @Travis
    I don’t entirely know how to field this one, because I’m running Firefox 3.5 and it works splendidly.

  12. e11world

    July 9th, 2009 at 1:03 PM

    This is pretty sweet! I love jQuery. Thank you for this neat effect!

  13. Will Anderson

    July 9th, 2009 at 2:27 PM

    @Travis
    I’m also running Firefox 3.5 and it seems to work fine. Even though the rope says “Pull Me” you just want to click on it, other wise it won’t work. Also make sure JavaScript is enabled :)
    .-= Will Anderson´s last blog ..JSON and ASP.NET =-.

  14. Sam Dunn

    July 9th, 2009 at 2:44 PM

    @Will Anderson & Travis
    To avoid further confusion I have changed the text on the rope in the demo, thanks for voicing the concern.

  15. Janko

    July 9th, 2009 at 4:42 PM

    Fantastic idea and awesome demo. Really refreshing tutorial.
    .-= Janko´s last blog .."Web Form Validation" article on Smashing Magazine =-.

  16. Nikola

    July 9th, 2009 at 5:29 PM

    this is amazing! BRAVO!
    .-= Nikola´s last blog ..Summer Sun =-.

  17. Adam

    July 10th, 2009 at 3:45 AM

    Very cool effect !

  18. xavier

    July 10th, 2009 at 6:21 AM

    Amazing!!!! Thanks for share it!!

  19. James

    July 12th, 2009 at 4:30 AM

    Nice effect.

    Couple of notes about your JS:

    You should always use var to declare variables; otherwise you’re just creating globals. Why are you prefixing “$curtainopen” with a dollar symbol? – this is not a convention; unless, perhaps, you thought you were writing PHP…

    Also “if(something == false)” is an almost meaningless expression. It’s essentially the same as “if(something)”.
    .-= James´s last blog ..Special scroll events for jQuery =-.

  20. Sam Dunn

    July 12th, 2009 at 3:33 PM

    @James
    Thank you, my background began in PHP so that shows up sometimes in my jQuery. Your method would work too.

  21. Diego

    July 15th, 2009 at 3:22 PM

    Wow, really awesome..
    Maybe I can use it on a project soon.. :D

    Thanks!

  22. Paul

    July 15th, 2009 at 6:12 PM

    Clever! Perfect example of how jQuery can make what was once a very complicated JavaScript animation and turn it into an easy task.
    .-= Paul´s last blog ..Using Form Labels as Input Values with jQuery and CSS =-.

  23. mcd

    July 17th, 2009 at 5:02 PM

    I love this! It works fine in the latest versions of Firefox, Opera, Chrome, and IE. Great work!

  24. Ezrad Lionel

    July 18th, 2009 at 3:56 PM

    I was referring to the easing on the animation. At the start and/or(dependent on browser) the end of the animation it sort of stutters.(I restarted my pc to confirm this) I see you’re using jquery easing which uses linear equations. Mine (no plug) uses bezier curves which are integrated into the core. The linear equation should always be smoother as the bezier curves are dependent on an additional precision value. I was actually planning on extending my rendering engine to incorporate these kind of user defined linear equations. I think that the stutter/lag is because Jquery uses brute force techniques. i.e. If you call “animation” 10 times and it will try to execute them all at the same time, which is why i think it’s happening when you’re animating two large objects a the same time. Mine (again no plug) runs on a system clock that coordinates animation dependent on the current load on the cpu and a predefined system FPS. You might have noticed, the first demo I tried to port might have been smoother than the Jquery implementation.. (well except for loading the large *** .js dev file ^_^) As I might have said, I’m basically building a game engine that i use on my sites. A falsh killer if you will. HTML 5 will be a big help. I’ve been kinda busy (surprisingly) lately but once I port it I’ll send it to you via email or something.

  25. Web Design Mumbai

    July 20th, 2009 at 11:34 AM

    this is very very impressive.

  26. FAQPAL

    July 20th, 2009 at 9:26 PM

    Excellent effect, well done and thanks for sharing. I posted it to FAQPAL.
    .-= FAQPAL´s last blog ..16 Good Questions to Ask before hiring PSD to HTML provider | Everything about XHTML & CSS =-.

  27. Michael Updegraff

    July 24th, 2009 at 1:28 PM

    Has an issue with FireFox 3.0.12, curtain will not open

  28. Davide

    July 29th, 2009 at 5:46 AM

    awesome!
    .-= Davide´s last blog ..jQuery: il metodo .bind() =-.

  29. Weboldalkészítés - Pécs

    July 31st, 2009 at 6:49 AM

    Wow, really awesome.. Excellent effect! Thanks!

  30. Gabriel

    August 4th, 2009 at 2:36 AM

    Really awesome. I love it !!!
    A question… I try to put a Youtube video in img class=”logo”, replacing .png, but it see over the curtains…
    Is there a way to “fix” this ??
    Thanks,
    G.
    .-= Gabriel´s last blog ..Heroes Volumen 5, Redemption, video adelanto =-.

  31. PhpMyCoder

    August 7th, 2009 at 12:43 AM

    The problem for Firefox users is most likely with NoScript. It seems that NoScript is blocking Build Internet from getting the JQuery JavaScript file from Google code (The error refers to a problem with the file name not matching). Here is the complete error from the Error Console:

    [NoScript] Blocking cross site Javascript served from http://jqueryjs.googlecode.com/files/jquery-1.3.2.js with wrong type info attachment; filename=”jquery-1.3.2.js” and included by http://buildinternet.com/live/curtains/#

    For some reason Allowing buildinternet.com in NoScript isn’t working, nor is Allowing Scripts globally. This goes so show how picky NoScript is about file names, but I guess all for the better. My guess would be simply disabling from the Addons window NoScript or going into settings and allowing scripts to be included from other domains will fix this. I, though, am going to avoid all that hassle and view it in Chrome. That should work! (Or James could host the JQuery script on BuildInternet and the problem should vanish)

  32. Piyush Agarwal

    August 7th, 2009 at 2:15 AM

    amazingly cooolll…..
    This is something that will bring that WOW effect to a project I am working on….
    Thanks a lot!
    .-= Piyush Agarwal´s last blog ..Kolkata Bloggers Meet 2009 – WebReps.in =-.

  33. saro

    August 28th, 2009 at 8:04 AM

    I would like to have it onload function.

    as i am newbie..can you please explain it.

    Thanks

  34. fahma

    October 5th, 2009 at 7:02 AM

    cool man…thanx

  35. Jimmy

    October 6th, 2009 at 11:39 AM

    very cool !
    but by setting “$curtainopen = true;” the site doesn’t start with an open curtain. is there a trick?

  36. Sam Dunn

    October 6th, 2009 at 12:09 PM

    @Jimmy
    $curtainopen is just a way to check if the curtain is already open, if you want it to start open you have to change the CSS the elements begin with.

  37. rona

    October 23rd, 2009 at 4:54 PM

    Hi Sam firstly tnx for the this great sharing , i have some problems ,it does not work on ie 8 ? when i open script with ie8 it ask me to show plugin but in firefox in works directly ? what is your advice and if i wanna use script for the all page what should i do to get good quality in curtain image? .. tnxx

  38. rizza

    November 6th, 2009 at 12:27 PM

    WOW, this is what I’m looking for, I have a project and I think it would be nice to have animate curtain.
    Thank for sharing Sam

  39. tuna

    November 10th, 2009 at 4:28 PM

    I really like it, good tutorial..
    .-= tuna´s last blog ..Photoshop’ta Hoş Bir Girdap Yapımı =-.

  40. jo

    December 9th, 2009 at 4:06 PM

    thanks for this tut, i read the other explainations on other pages ages ago, and yours is one of the best… :)

  41. remco van rooyen

    January 14th, 2010 at 5:24 AM

    its very nice.. but please turn off the outline. by a.class{outline:none;} then… its perfect :D

  42. seo

    February 2nd, 2010 at 4:11 AM

    perfect bro :)

  43. Ange

    February 6th, 2010 at 6:28 AM

    Hi Sam

    These curtains are great, I am however having a small issue, I am trying to put a video behind the curtain as opposed to the image idea. The video is there and working BUT when I go to shut the curtains the video sits on top of the curtain instead of under it. Do you know what I need to do to fix this?

  44. Foekie

    February 22nd, 2010 at 12:06 PM

    It has some rendering problems. It lags in google chrome and in internet explorer it is clear that the image is constantly renderen untill it arrives at the specified point (e.g. 30px).

    I will try to get a work around for this.

    To ange:
    Youtube video’s are always on top of everything. (it’s an object) There is a work around for this called iframe shim, but this is a very bad work around.

Join the Conversation!

Remember: Life's not all doom and gloom, so please keep it constructive. If we've made an error or missed something big, please let us know! Learning is revisions, after all.

CommentLuv is Enabled

 

Sponsors

Advertise on Build Internet!