Shutter Effect with jQuery

shutter effect

This functionality will come in the form of an easy to use jQuery plugin that you can easily incorporate into any website which displays a set of featured photos with a camera shutter effect.

jquery.shutter.css

<style>
#container{
width:640px;
height:400px;
margin:0 auto;
border:5px solid #fff;
overflow:hidden;
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

#container ul{
list-style:none;
padding:0;
margin:0;
}
#page{
width:650px;
height:400px;
}
#container img{
padding:0;
}
.shutterAnimationHolder .film canvas{
display: block;
margin: 0 auto;
}

.shutterAnimationHolder .film{
position:absolute;
left:50%;
top:0;
}

.shutterAnimationHolder{
position:absolute;
overflow:hidden;
top:0;
left:0;
z-index:1000;
}
</style>

jQuery

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>

<script src=".../jquery.shutter.js"></script>

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

var container = $('#container'),
li = container.find('li');

// Using the tzShutter plugin. We are giving the path
// to he shutter.png image in the plugin folder and two
// callback functions.

container.tzShutter({
imgSrc: 'assets/jquery.shutter/shutter.png',
closeCallback: function(){

// Cycling the visibility of the li items to
// create a simple slideshow.

li.filter(':visible:first').hide();

if(li.filter(':visible').length == 0){
li.show();
}

// Scheduling a shutter open in 0.1 seconds:
setTimeout(function(){container.trigger('shutterOpen')},100);
},
loadCompleteCallback:function(){
setInterval(function(){
container.trigger('shutterClose');
},4000);

container.trigger('shutterClose');
}
});

});
</script>

Generated HTML

<div id="page">

<h1>Shutter Folio Photography</h1>

<div id="container">
<ul>
<li><img src=".../img/1.jpg" width="640" height="400" /></li>
<li><img src=".../img/2.jpg" width="640" height="400" /></li>
<li><img src=".../img/3.jpg" width="640" height="400" /></li>
<li><img src=".../img/4.jpg" width="640" height="400" /></li>
</ul>
</div>

</div>

The Final Code

<head>
<style>
#container{
width:640px;
height:400px;
margin:0 auto;
border:5px solid #fff;
overflow:hidden;
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

#container ul{
list-style:none;
padding:0;
margin:0;
}
#page{
width:650px;
height:400px;
}
#container img{
padding:0;
}
.shutterAnimationHolder .film canvas{
display: block;
margin: 0 auto;
}

.shutterAnimationHolder .film{
position:absolute;
left:50%;
top:0;
}

.shutterAnimationHolder{
position:absolute;
overflow:hidden;
top:0;
left:0;
z-index:1000;
}
</style>
</head>

<body>
<div id="page">

<h1>Shutter Folio Photography</h1>

<div id="container">
<ul>
<li><img src=".../img/1.jpg" width="640" height="400" /></li>
<li><img src=".../img/2.jpg" width="640" height="400" /></li>
<li><img src=".../img/3.jpg" width="640" height="400" /></li>
<li><img src=".../img/4.jpg" width="640" height="400" /></li>
</ul>
</div>

</div>

<script type='text/javascript'>
//<![CDATA[
(function(){

// Creating a regular jQuery plugin:

$.fn.tzShutter = function(options){

// Checking for canvas support. Works in all modern browsers:
var supportsCanvas = 'getContext' in document.createElement('canvas');

// Providing default values:

options = $.extend({
openCallback:function(){},
closeCallback:function(){},
loadCompleteCallback:function(){},
hideWhenOpened:true,
imgSrc: 'http://dl.dropbox.com/u/13256471/jquery.shutter/assets/jquery.shutter/shutter.png'
},options);

var element = this;

if(!supportsCanvas){

// If there is no support for canvas, bind the
// callack functions straight away and exit:

element.bind('shutterOpen',options.openCallback)
.bind('shutterClose',options.closeCallback);

options.loadCompleteCallback();

return element;
}

window.setTimeout(function(){

var frames = {num:15, height:1000, width:1000},
slices = {num:8, width: 416, height:500, startDeg:30},
animation = {
width : element.width(),
height : element.height(),
offsetTop: (frames.height-element.height())/2
},

// This will calculate the rotate difference between the
// slices of the shutter. (2*Math.PI equals 360 degrees in radians):

rotateStep = 2*Math.PI/slices.num, 
rotateDeg = 30;

// Calculating the offset   
slices.angleStep = ((90 - slices.startDeg)/frames.num)*Math.PI/180;

// The shutter slice image:
var img = new Image();

// Defining the callback before setting the source of the image:
img.onload = function(){

window.console && console.time && console.time("Generating Frames");

// The film div holds 15 canvas elements (or frames).

var film = $('<div>',{
className: 'film',
css:{
height: frames.num*frames.height,
width: frames.width,
marginLeft: -frames.width/2, // Centering horizontally
top: -animation.offsetTop
}
});

// The animation holder hides the film with overflow:hidden,
// exposing only one frame at a time.

var animationHolder = $('<div>',{
className: 'shutterAnimationHolder',
css:{
width:animation.width,
height:animation.height
}
});

for(var z=0;z<frames.num;z++){

// Creating 15 canvas elements.

var canvas = document.createElement('canvas'),
c  = canvas.getContext("2d");

canvas.width=frames.width;
canvas.height=frames.height;

c.translate(frames.width/2,frames.height/2);

for(var i=0;i<slices.num;i++){

// For each canvas, generate the different
// states of the shutter by drawing the shutter
// slices with a different rotation difference.

// Rotating the canvas with the step, so we can
// paint the different slices of the shutter.
c.rotate(-rotateStep);

// Saving the current rotation settings, so we can easily revert
// back to them after applying an additional rotation to the slice.

c.save();

// Moving the origin point (around which we are rotating
// the canvas) to the bottom-center of the shutter slice.
c.translate(0,frames.height/2);

// This rotation determines how widely the shutter is opened.
c.rotate((frames.num-1-z)*slices.angleStep);

// An additional offset, applied to the last five frames,
// so we get a smoother animation:

var offset = 0;
if((frames.num-1-z) <5){
offset = (frames.num-1-z)*5;
}

// Drawing the shutter image
c.drawImage(img,-slices.width/2,-(frames.height/2 + offset));

// Reverting back to the saved settings above.
c.restore();
}

// Adding the canvas (or frame) to the film div.
film.append(canvas);
}

// Appending the film to the animation holder.
animationHolder.append(film);

if(options.hideWhenOpened){
animationHolder.hide();
}

element.css('position','relative').append(animationHolder);

var animating = false;

// Binding custom open and close events, which trigger
// the shutter animations.

element.bind('shutterClose',function(){

if(animating) return false;
animating = true;

var count = 0;

var close = function(){

(function animate(){
if(count>=frames.num){
animating=false;

// Calling the user provided callback.
options.closeCallback.call(element);

return false;
}

film.css('top',-frames.height*count - animation.offsetTop);
count++;
setTimeout(animate,20);
})();
}

if(options.hideWhenOpened){
animationHolder.fadeIn(60,close);
}
else close();
});

element.bind('shutterOpen',function(){

if(animating) return false;
animating = true;

var count = frames.num-1;

(function animate(){
if(count<0){

var hide = function(){
animating=false;
// Calling the user supplied callback:
options.openCallback.call(element);
};

if(options.hideWhenOpened){
animationHolder.fadeOut(60,hide);
}
else{
hide();
}

return false;
}

film.css('top',-frames.height*count - animation.offsetTop);
count--;

setTimeout(animate,20);
})();
});

// Writing the timing information if the
// firebug/web development console is opened:

window.console && console.timeEnd && console.timeEnd("Generating Frames");
options.loadCompleteCallback();
};

img.src = options.imgSrc;

},0);

return element;  
};

})(jQuery);
//]]>
</script>

</body>

With this Shutter Effect is complete!

Related Posts Plugin for WordPress, Blogger...

0 comments:

Post a Comment

Go
to
Top
© 2011 Deviation. WP Themes by Skatter Tech. Bloggerized by Bambang Wicaksono.
Mouse Movement to the Next Widget
 
BLOG MENU