Making a Photoshoot Effect With jQuery & CSS

12 February 2010 Friday

This application was viewed 1591 times




Making a Photoshoot Effect With jQuery & CSS

Often, in your design or development tasks, you are presented with challenges that require a different approach than just plunging head over heels in coding. Research and experiments are a vital part of this process.

This is why this week’s tutorial is structured in a slightly different manner than usual. First we are presented with the main problems faced and their solutions, and after this we get round to building upon it.

We are creating a photo shoot effect with our just-released PhotoShoot jQuery plug-in. With it you can convert a regular div on the page into a photo shooting stage simulating a camera-like feel. Using this plug-in, we give visitors the ability to take shots of the background image.

Before starting with the tutorial, I would suggest you download the zip archive from the buttons above.

Problem 1 – Blurring the image

JavaScript does not support blurring an image directly. For example, there is no such thing as document.getElemetById(‘image’).style.blur=2, no matter how useful it would’ve been.

The technique I’ve used and incorporated into the plug-in is actually quite simple – it just stacks up a bunch of divs, each holding the image as a background and whose opacity is lowered, one on top of the other. Those divs’ positions are off by a few pixels at random, so you end up with a blurred effect.

There is however a newer alternative to this technique, which I hope to implement in a future version of the plugin. It is achieved via the canvas HTML5 element, which allows low-level modifications of an image inside of the canvas. Unfortunately, canvas is not yet supported by a large portion of the currently used browsers, so a combination of the techniques would have to be used.

Problem 2 – Hiding the cursor

CSS does not provide a way for hiding the cursor from view. E.g. you cannot specify a CSS rule like cursor : none. There is a neat workaround though. CSS gives you the ability to specify a custom cursor in a .cur file with the css:url() rule. These files support transparency, so you just need to make a completely transparent cursor and assign it to the area in which you wish the cursor to be hidden.

Unfortunately Google Chrome has issues with completely blank cursors, so a special version has to be tailored which contains one white pixel (still better than nothing).

Another trouble maker is Opera, which does not support custom cursors altogether. There are no workarounds. It is not that much of a big deal though, everything else runs fine in Opera.

Problem 3 – No support for masks

A solution to this problem is to use the background property of the viewfinder div to display the original image. By specifying a negative top and left margin and updating it on every mouse move, we can give users  the impression that the viewfinder clears up the blurring of the scenery below.

Masking is the process in which only a part of an image or shape is shown, with the rest clipped away. In the case of this tutorial, a mask would’ve given us the ability to have a regular version of the image above the blurred one, and mask it, so that only the part that intersects with the viewfinder is shown and thus giving us the impression that it un-blurs the image below.

The solutions to these problems are implemented in the plug-in for us, which lifts a lot of the development burden and we can start building upon it.

Step 1 – XHTML

As most of the work is handled by the PhotoShoot jQuery plug-in, our work is reduced to only provide a div that is going to be transformed into a photo shooting stage (we still have to pass a configuration object holding the image we want displayed, along with a few other options though).

demo.html

 
1.<div id="main">
2.  
3.<!-- The plugin automatically inserts the needed markup here -->
4.  
5.</div>

You can have this div anywhere on your page. You’ll need to specify a fixed width and height in the stylesheet in order for this to work properly. After the page loads and the plug-in is initialized, additional code is inserted into this div.

demo.html

 
01.<div id="main">
02.  
03.<div class="blur" style="......"></div>
04.<div class="blur" style="......"></div>
05.<!--  8 more blur divs -->
06.  
07.<div class="overlay" style="opacity: 0.2;"></div>
08.  
09.<div style="......" class="viewFinder">
10.<img src="photoShoot/viewfinder.png" width="300" height="200">
11.</div>
12.  
13.<!-- Additional html for the shots is inserted here. Not part of the plug-in.  -->
14.  
15.</div>

A whole lot has changed here. As mentioned earlier, the blur effect is achieved by stacking transparent divs on top of each other – the blur divs. After this is the overlay div, which darkens the layers below it, according to the opacity option passed to the plug-in.

Finally we have the viewfinder, which follows the mouse movements on the area and has the non-blurred version of the image as its background.

To ensure maximum flexibility, the plug-in provides a way to execute a user-defined function when a click occurs. This is exactly what we use to simulate a camera flash and to insert a new shot in the album div, which is not part of the plug-in.

Step 2 – CSS

The plug-in comes with its own stylesheet (photoShoot/jquery.photoShoot-1.0.css in the demo files) which defines the look of the photo shoot components, so we are only left with styling the rest of the page.

styles.css

 
01.#main{
02.    /* This div is converted to a photoShoot stage by the Photo Shoot plug-in */
03.    margin:0 auto;
04.    width:960px;
05.    height:600px;
06.}
07.  
08..shot{
09.    /* These contain a scaled down version of the background image: */
10.  
11.    border:3px solid #FCFCFC;
12.    float:right;
13.    position:relative;
14.    margin-left:10px;
15.    overflow:hidden;
16.  
17.    /* Adding a CSS3 shadow below the shots: */
18.  
19.    -moz-box-shadow:0 0 2px black;
20.    -webkit-box-shadow:0 0 2px black;
21.    box-shadow:0 0 2px black;
22.}
23.  
24..shot img{
25.    display:block;
26.}
27.  
28..album{
29.    /* This div holds the shots */
30.    bottom:50px;
31.    height:110px;
32.    overflow:hidden;
33.    position:absolute;
34.    right:20px;
35.    width:490px;
36.}
37.  
38..album .slide{
39.    /* The slide div is contained in album  */
40.    width:700px;
41.    height:110px;
42.    position:relative;
43.    left:-210px;
44.}

Each shot is dynamically inserted by our own custom shoot function when a click event occurs (as you will see in the next step of the tutorial). The shots are basically a scaled down version of the background image (this means that the image is downloaded once and used multiple times), which are offset to the top and bottom, according to the position of the viewfinder in the moment the event occurred.

The album and slide divs are added by our own jQuery script (not by the plug-in). The principle here is that the slide div is larger than its parent, the album div, and the shot is slid to the left when inserted, but more on that in a moment.

Step 3 – jQuery

The photoShoot plug-in itself will not be discussed here as you can read more about it on its official page. We do need, however, some additional jQuery code which:

  • Inserts the .album to the #main div;
  • Chooses a random flickr image from an array to be fed to the plug-in;
  • Creates the options object;
  • Defines a custom shot function which is called on mouse click by the plug-in;
  • Calls the plug-in with the .photoshoot() method.

script.js

 
01.$(document).ready(function(){
02.  
03.    // This code is executed after the DOM has been completely loaded
04.  
05.    // Assigning the jQuery object to a variable for speed:
06.    var main = $(´#main´);
07.  
08.    // Setting the width of the photoshoot area to
09.    // 1024 px or the width of the document - whichever is smallest:
10.  
11.    main.width(Math.min(1024,$(document).width()));
12.  
13.    // Creating an array with four possible backgrounds and their sizes:
14.    var pics = new Array(
15.                { url:´http://farm4.static.flickr.com/3595/3405361333_77f2a5e731_b.jpg´, size:{x:1024,y:677}},
16.                { url:´http://farm4.static.flickr.com/3028/2753126743_4249a4e948_b.jpg´, size:{x:1024,y:768}},
17.                { url:´http://farm4.static.flickr.com/3641/3595250019_5a1237899a_b.jpg´, size:{x:1024,y:768}},
18.                { url:´http://farm3.static.flickr.com/2592/4018062274_1f7f23597d_o.jpg´, size:{x:1158,y:756}}
19.    );
20.  
21.    // Choosing a random picture to be passed to the PhotoShoot jQuery plug-in:
22.    var bg = pics[parseInt(Math.random()*4)];
23.  
24.    // Creating an options object (try tweeking the variables):
25.    var opts = {
26.        image       :   bg.url,
27.        onClick     :   shoot,
28.        opacity     :   0.8,
29.        blurLevel   :   4
30.    }
31.  
32.    // Calling the photoShoot plug-in and converting the #main div to a photo shoot stage:
33.    main.photoShoot(opts);
34.  
35.    // Adding the album holder to the stage:
36.    $(´<div class="album">´).html(´<div class="slide" />´).appendTo(main);
37.  
38.    // Our own shoot function (it is passed as onClick to the options array above):
39.    function shoot(position){
40.        // This function is called by the plug-in when the button is pressed
41.  
42.        // Setting the overlay´s div to white will create the illusion of a camera flash:
43.        main.find(´.overlay´).css(´background-color´,´white´);
44.  
45.        // The flash will last for 100 milliseconds (a tenth of the second):
46.        setTimeout(function(){main.find(´.overlay´).css(´background-color´,´´)},100);
47.  
48.        // Creating a new shot image:
49.        var newShot = $(´<div class="shot">´).width(150).height(100);
50.        newShot.append( $(´<img src="´+bg.url+´" width="´+(bg.size.x/2)+´" height="´+(bg.size.y/2)+´" />´).css(´margin´,-position.top*0.5+´px 0 0 -´+position.left*0.5+´px´) );
51.  
52.        // Removing the fourth shot (the count starts from 0):
53.        $(´.shot´).eq(3).remove();
54.  
55.        // Adding the newly created shot to the album div, but moved 160px to the right.
56.        // We start an animation to slide it in view:
57.  
58.        newShot.css(´margin-right´,-160).prependTo(´.album .slide´).animate({marginRight:0},´slow´);
59.    }
60.});

Each time you click the area, a new shot is added to the slide div with a negative margin to the right. After this an animation starts, which slides it in view and pushes the other shots to the left, hiding the leftmost one.

It is important to remove the shots that are not visible with the remove() method. This way we prevent cluttering of the DOM with unneeded elements.

Tags: jquery, effects, css,


Making a Photoshoot Effect With jQuery & CSSBookmark and Share

Comments

You write your thoughts

Please login to post comments here from the right corner.

your add
icon free icon icon set vector icon free catalog catalog template jquery news ticker widget tools tutorial php slider video youtube effects menu thumbnail forms facebook zoom image combo multiselect modal polaroid gallery expand code feedback contact navigation slider tagcloud Skateboard psd templates files badges subscribe panel login temlate file free office holland free template tabs prototype css scriptaculous opacity moo autocomplete wordpress themes design theme button images photoshop fonts font nav pdf logo style high javascript pretty photo jqery lightbox Themes Blog popular blog desing joomla xhtml brushes hair footer admin mootols slide show blackbox new download class first plugin upload browse Page effect modalbox web application urlitooltips sliding boxes captions flatchat chat ajax messaging browser hoverlightbox CSS Dev General Javascript PHP SQL search avatar vector Drupal Joomla Oscommerce javaScript phototype manager ajaxplorer flash xml rotator bookmarking pageflip slideshow poll text component script mediaplayer imagegallery pictograms car poster player mp3 radio onlineradio navigations drop-down collection brush tree textures paper pop-up bumpbox web2.0 iphone film frame twitter page fan mail delete dynamic calender form handbook city social paint timeline clock connect bar sharing accordion quotes ticker photo-effects background 3D media player graphic rss leaf green glossy bubble icon comic clean cool web 2.0 png actionscript ietter rotating Menu animated textured site masking pasword app layer sponge bob popup bubble tooltips horizontal prototip tooltip pack charachters comics blog action icon.psd flavour navi tango gradients istanbul mixed css3 sleek animations program html5 website Layer styles ultimate candy Media icons dropdown snow icon innerfade hover sub tag